I'm writing a win32 application in Visual C++ 6.0 which repartitions
a drive by writing a new MBR onto the first sector (intended for
small compact flash cards). The basic approach, which is working
quite well, is to open "\\\\.\\PhysicalDrive1" (or whatever number
the drive happens to be), lock it for exclusive access using
DeviceIoControl with FSCTL_LOCK_VOLUME, and the write a new
partition table onto it. As per Microsoft's docs, I unlock it
when I'm done, and then dismount it with FSCTL_DISMOUNT_VOLUME.
This last step is where the problems, and this question come in.
The purpose of FSCTL_DISMOUNT_VOLUME is to make the filesystem
code in windows "forget" about the drive... and then next time
someone tries to access it, the filesystem will detect the new
partitioning (and since I just wrote zeros over the filesystem,
windows will prompt the user to format the drive... which is nice
since I actually wrote two partitions, a little one with FAT12
type and a big one where I'm storing my own special data using
a type that windows doesn't recognize).
The problem is that calling DeviceIoControl with FSCTL_DISMOUNT_VOLUME
on the handle for \\.\PhysicalDrive1 does not cause the filesystem
layer inside windows XP to "forget" about the logical volumes
(from the previous partitions) that are already mounted. This of
course leads to a complete mess in the case where I replaced one large
FAT16 partition with a tiny FAT12 and my own non-standard partition...
as the filesystem drive will happily keep accessing and writing data
into the space originally partitioned for that large FAT16 volume.
If I pull the removable compact flash card immediately after my program
writes the new partition table, and then re-insert it, Windows does
indeed do what I want. The next attempt to access the card is aware
of the smaller unformatted FAT12 space.
But I don't want to require the user to pull and re-insert the card.
I need you, dear answerer, to advise me on how I can get Windows XP
(and 2000, NT4... but of course not 98/ME/95) to dismount all the
logical drives associated with the physical drive I'm repartitioning.
Perhaps just some way to get a list of them, so I can open them,
lock them, and then dismount 'em all. Perhaps there's a diffent way
that I'm not envisioning??
Well, that's the question... it seems like all I need is a way to
find the list of all logical drives associated with the existing
partitions (if FSCTL_DISMOUNT_VOLUME actually works when used on
a logical drive... it sure doesn't do anything when used on a
physical drive!) |