Background
NanaBox first attempted VSMB support in ab355ec (Add EnableHostDriverStore option for GPU-PV settings), which added a VirtualSmb share to expose the host's DriverStore to the guest. Shortly after, 3d0d857 removed it:
Remove Virtual SMB mode for EnableHostDriverStore option because there is no proper way to initialize Virtual SMB shares without Windows Container.
The core issue: a full Windows guest (unlike a container UVM) has no guest agent to initialize the SMB-over-VMBus redirector.
We've now solved this and every downstream problem. This issue documents the full technical journey and proposes integrating VSMB as a first-class NanaBox feature.
Solution summary
Guest-side VSMB initialization — Reverse-engineered from hcsshim's gcs-sidecar/vsmb.go: two FSCTLs (FSCTL_LMR_START_INSTANCE + FSCTL_LMR_BIND_TO_TRANSPORT) on the LanmanRedirector create a \Device\vmsmb instance and bind it to the VMBus transport. A keepalive handle must be held to prevent mrxsmb.sys BSOD.
Mounting via mklink — mklink /d C:\Shared "\\?\GLOBALROOT\Device\vmsmb\VSMB-{guid}\ShareName" makes shares accessible at local paths. Persists across reboots; resolves automatically once VSMB is initialized.
HostDriverStore + GPU-PV — GPU-PV drivers load at kernel boot, before VSMB is available. Solved by syncing HostDriverStore from VSMB to local disk post-boot, then restarting GPU-PV devices on change to reload drivers.
UAC elevation fix — mklink symlinks resolve to \Device\vmsmb\..., which has no volume mapping. consent.exe calls GetFinalPathNameByHandle(VOLUME_NAME_DOS) → ERROR_INVALID_FUNCTION → "Incorrect function" dialog. Reverse-engineering Windows Sandbox revealed it uses Bind Filter (BfSetupFilter with flag 0x20) instead of symlinks, making VSMB files appear as local volume paths. Verified working for UAC elevation.
Performance
Compared to Plan9Shares (the current file sharing mechanism): ~900 MB/s (VSMB) vs ~100 MB/s (Plan9), with excellent small-file performance as well.
Guest-side init service
Runs four stages at boot:
- VSMB transport init —
FSCTL_LMR_START_INSTANCE + FSCTL_LMR_BIND_TO_TRANSPORT (hardcoded VMBus constants, no config needed)
- Bind Filter mount — read mount config from a VSMB share (now accessible after stage 1), call
BfSetupFilter per share to create local mount points
- HostDriverStore sync + GPU-PV restart — sync driver files to local disk via mounted share, restart GPU-PV devices on change
- Keepalive — hold a VSMB share handle open to prevent VMBus channel teardown
Roadmap
| Post |
Topic |
| 2 |
Guest-side VSMB initialization and mklink mounting |
| 3 |
HostDriverStore synchronization and GPU-PV integration |
| 4 |
UAC limitation, Sandbox reverse-engineering, and Bind Filter solution |
| 5 |
Proposed feature design for NanaBox |
Background
NanaBox first attempted VSMB support in
ab355ec(Add EnableHostDriverStore option for GPU-PV settings), which added aVirtualSmbshare to expose the host's DriverStore to the guest. Shortly after,3d0d857removed it:The core issue: a full Windows guest (unlike a container UVM) has no guest agent to initialize the SMB-over-VMBus redirector.
We've now solved this and every downstream problem. This issue documents the full technical journey and proposes integrating VSMB as a first-class NanaBox feature.
Solution summary
Guest-side VSMB initialization — Reverse-engineered from hcsshim's gcs-sidecar/vsmb.go: two FSCTLs (
FSCTL_LMR_START_INSTANCE+FSCTL_LMR_BIND_TO_TRANSPORT) on the LanmanRedirector create a\Device\vmsmbinstance and bind it to the VMBus transport. A keepalive handle must be held to prevent mrxsmb.sys BSOD.Mounting via mklink —
mklink /d C:\Shared "\\?\GLOBALROOT\Device\vmsmb\VSMB-{guid}\ShareName"makes shares accessible at local paths. Persists across reboots; resolves automatically once VSMB is initialized.HostDriverStore + GPU-PV — GPU-PV drivers load at kernel boot, before VSMB is available. Solved by syncing HostDriverStore from VSMB to local disk post-boot, then restarting GPU-PV devices on change to reload drivers.
UAC elevation fix — mklink symlinks resolve to
\Device\vmsmb\..., which has no volume mapping.consent.execallsGetFinalPathNameByHandle(VOLUME_NAME_DOS)→ERROR_INVALID_FUNCTION→ "Incorrect function" dialog. Reverse-engineering Windows Sandbox revealed it uses Bind Filter (BfSetupFilterwith flag0x20) instead of symlinks, making VSMB files appear as local volume paths. Verified working for UAC elevation.Performance
Compared to Plan9Shares (the current file sharing mechanism): ~900 MB/s (VSMB) vs ~100 MB/s (Plan9), with excellent small-file performance as well.
Guest-side init service
Runs four stages at boot:
FSCTL_LMR_START_INSTANCE+FSCTL_LMR_BIND_TO_TRANSPORT(hardcoded VMBus constants, no config needed)BfSetupFilterper share to create local mount pointsRoadmap