I'm working on a program that installs FreeDOS onto a Virtual Hard Disk. It generates and executes a DiskPart script to create the VHD, partition it, format it, then assign it a drive letter.
This works fine. My installer copies everything to the VHD, but now I need to write a boot sector, which requires direct access to the volume. Before starting this process, I try to lock the volume with FSCTL_LOCK_VOLUME.
The problem is: DeviceIoControl
returns ERROR_ACCESS_DENIED
, which (according to MSDN) means there are files open on the volume. But my installer closes every file once it's done copying it, so I'm not sure what else could be causing this. Does it have something to do with how DiskPart has mounted the VHD?
Sample DiskPart Script
create vdisk file=E:\Dev\freedos.vhd maximum=128 type=fixed
select vdisk file=E:\Dev\freedos.vhd
attach vdisk
create partition primary
select partition 1
format quick fs=FAT
assign letter=A
Note: The file path, disk size, file system, and drive letter values change depending on options supplied to the program.
C Code
HANDLE volume;
char volName[MAX_PATH];
DWORD bytesReturned;
if (!GetVolumeNameForVolumeMountPoint(config.volRoot, volName, sizeof(volName)))
ThrowError(1, "Failed to get volume name (error %d)!", GetLastError());
/*
* CreateFile will fail if the volume name has a trailing backslash
*/
PathRemoveBackslash(volName);
volume = CreateFile(volName, (GENERIC_READ | GENERIC_WRITE),
(FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (volume == INVALID_HANDLE_VALUE)
ThrowError(1, "Failed to open installation volume (error %d)!", GetLastError());
if (!DeviceIoControl(volume, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &bytesReturned, NULL))
ThrowError(1, "Failed to lock installation volume (error %d)!", GetLastError());
CloseHandle(volume);