我正在尝试将USB密钥直通功能添加到与远程桌面功能类似的软件中。我有以下代码:
public void Open(string path)
{
System.OperatingSystem ver = System.Environment.OSVersion;
uint mode;
uint attr;
uint share;
int junk = 0;
bool success;
string partitionFileName = @"\\.\" + path;
uint drvtype;
// Only determine drvtype if not already defined
// Default drytype is DRIVE_UNKNOWN
if (drvtype == Kernel32.DriveType.Unknown)
{
drvtype = Kernel32.GetDriveType(path); //0=unknown, 1 = no root drive, 2= removable, 3=fixed, 4=remote, 5=cdrom, 6=ramdisk
}
// Set the access modes depending on what we are opening
if (drvtype == Kernel32.DriveType.CDROM)
{
// Depending on the OS version, the flags for opening the cdrom for ioctls are different
if (ver.Version.Major == 4) //4 == Windows NT
{
mode = Kernel32.GENERIC_READ;
share = Kernel32.FILE_SHARE_READ;
attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
}
else
{
mode = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
share = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE;
attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
}
}
else
{
mode = Kernel32.GENERIC_READ | Kernel32.GENERIC_WRITE;
share = Kernel32.FILE_SHARE_READ | Kernel32.FILE_SHARE_WRITE; // exclusive access to device
attr = Kernel32.FILE_ATTRIBUTE_NORMAL;
}
// Try to open the partition as read/write
hFile = Kernel32.CreateFile(partitionFileName,
mode,
share,
IntPtr.Zero,
Kernel32.OPEN_EXISTING,
attr,
IntPtr.Zero);
// Lock the volume
Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlLockVolume, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);
// Dismount from the host OS to get around Vista's security
Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlDismountVolume, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);
// Allow extended access to get at boot sectors
Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.FsctlAllowExtendedDasdIo, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);
// If it's a USB disk, see if it is write-protected
if (drvtype == Kernel32.DriveType.Removable)
{
// If it is write-protected, tell the user
success = Kernel32.DeviceIoControl(hFile, Kernel32.EIOControlCode.DiskIsWritable, IntPtr.Zero, 0, IntPtr.Zero, 0, ref junk, IntPtr.Zero);
if (success)
{
bWriteProtect = false;
}
else
{
if (Kernel32.GetLastError() == 19) //ERROR_WRITE_PROTECT
{
bWriteProtect = true;
showStatus("Unable to open as read/write. File opened as read-only.");
}
else
{
bWriteProtect = false;
}
}
}
}
然后我用ReadFile()读取磁盘。它适用于FAT格式的USB密钥,我可以读/写甚至从它启动。但是,出于某种原因,它不适用于NTFS格式的密钥。调用ReadFile()会抛出错误21,ERROR_NOT_READY,其中一些挖掘发现是因为已卸载卷。我无法保持卷安装,因为我正在访问(并可能写入)驱动器上的引导扇区,据我所知,Vista / 7将不允许您在没有首先卸载驱动器的情况下执行此操作。
我是否应该为NTFS做一些其他的DeviceIoControl调用?