1

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);
David Brown
  • 35,411
  • 11
  • 83
  • 132

1 Answers1

0

This doesn't really answer your question, but it might actually be better to create the VHD directly first, then mount it. VHD is a drop-dead simple format, you could probably write a program to directly create a VHD with an already pre-written bootloader (i.e. just using CreateFile/WriteFile), then mount it and create a filesystem.

Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • Thanks for the suggestion. If DiskPart is the problem, then I'll do that. But for now, I'm trying to keep things as simple as possible. Letting DiskPart take care of the VHD stuff lets me focus on other things. – David Brown Jul 24 '11 at 03:52