如何从 Windows 7 中的驱动器号获取可移动设备的物理驱动器号?
我正在尝试从驱动器查找物理驱动器编号(例如,我需要 \\.\PhysicalDriveN
中的 N
来打开块设备进行读取) Windows 7 上 CDROM 驱动器的盘符。此页 表示 IOCTL_STORAGE_GET_DEVICE_NUMBER 应该可以工作,但它为 C: 和 D: 的驱动器号返回 0(其中 D: 是可移动驱动器),因此这是不正确的。还建议使用 IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,但在 D: 上会失败并出现 ERROR_INVALID_FUNCTION。
我不禁觉得我在某个地方错过了一个关键的概念。
这是我的代码:
#include "stdafx.h"
#include "Windows.h"
void printLastError(){
DWORD lastError;
DWORD bytesReturned;
WCHAR outbuf[2048];
lastError = GetLastError();
bytesReturned = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL, lastError, LANG_USER_DEFAULT, outbuf, 2048, NULL);
if (bytesReturned > 0){
wprintf(outbuf);
} else {
printf("Error %d while formatting error %d\n", GetLastError(), lastError);
}
}
void readDeviceNumberByExtents(HANDLE hFile){
BOOL ioctlSuccess;
DWORD bytesReturned;
VOLUME_DISK_EXTENTS vde;
ioctlSuccess = DeviceIoControl(hFile,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL);
if (ioctlSuccess != 0){
printf("%d\n", vde.Extents->DiskNumber );
} else {
printLastError();
}
}
void readDeviceNumberByStorage(HANDLE hFile){
BOOL ioctlSuccess;
DWORD bytesReturned;
STORAGE_DEVICE_NUMBER sdn;
ioctlSuccess = DeviceIoControl(hFile,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL, 0, &sdn, sizeof(sdn), &bytesReturned, NULL);
if (ioctlSuccess != 0){
printf("%d\n", sdn.DeviceNumber );
} else {
printLastError();
}
}
void runTest(WCHAR* driveName){
HANDLE driveHandle;
DWORD diskNumber;
driveHandle = CreateFile(driveName,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (driveHandle != INVALID_HANDLE_VALUE){
wprintf(L"Opened %s\n", driveName);
printf("Device number by extents: ");
readDeviceNumberByExtents(driveHandle);
printf("Device number by storage: ");
readDeviceNumberByStorage(driveHandle);
CloseHandle(driveHandle);
} else {
printf("Failure!\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
runTest(L"\\\\.\\C:");
printf("\n");
runTest(L"\\\\.\\D:");
getc(stdin);
return 0;
}
...以及我以管理员身份或非管理员身份运行它时的输出:
Opened \\.\C:
Device number by extents: 0
Device number by storage: 0
Opened \\.\D:
Device number by extents: Incorrect function.
Device number by storage: 0
I'm trying to look up the physical drive number (as in, I need the N
in \\.\PhysicalDriveN
to open the block device for reading) from the drive letter of a CDROM drive on Windows 7. This page indicates that IOCTL_STORAGE_GET_DEVICE_NUMBER should work, but it returns 0 for the drive number for both C: and D: (where D: is the removable drive), so that can't be right. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS is also suggested, but that fails with an ERROR_INVALID_FUNCTION on D:.
I can't help but feel that I've missed a crucial concept somewhere.
Here's my code:
#include "stdafx.h"
#include "Windows.h"
void printLastError(){
DWORD lastError;
DWORD bytesReturned;
WCHAR outbuf[2048];
lastError = GetLastError();
bytesReturned = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
NULL, lastError, LANG_USER_DEFAULT, outbuf, 2048, NULL);
if (bytesReturned > 0){
wprintf(outbuf);
} else {
printf("Error %d while formatting error %d\n", GetLastError(), lastError);
}
}
void readDeviceNumberByExtents(HANDLE hFile){
BOOL ioctlSuccess;
DWORD bytesReturned;
VOLUME_DISK_EXTENTS vde;
ioctlSuccess = DeviceIoControl(hFile,
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS,
NULL, 0, &vde, sizeof(vde), &bytesReturned, NULL);
if (ioctlSuccess != 0){
printf("%d\n", vde.Extents->DiskNumber );
} else {
printLastError();
}
}
void readDeviceNumberByStorage(HANDLE hFile){
BOOL ioctlSuccess;
DWORD bytesReturned;
STORAGE_DEVICE_NUMBER sdn;
ioctlSuccess = DeviceIoControl(hFile,
IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL, 0, &sdn, sizeof(sdn), &bytesReturned, NULL);
if (ioctlSuccess != 0){
printf("%d\n", sdn.DeviceNumber );
} else {
printLastError();
}
}
void runTest(WCHAR* driveName){
HANDLE driveHandle;
DWORD diskNumber;
driveHandle = CreateFile(driveName,
0,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (driveHandle != INVALID_HANDLE_VALUE){
wprintf(L"Opened %s\n", driveName);
printf("Device number by extents: ");
readDeviceNumberByExtents(driveHandle);
printf("Device number by storage: ");
readDeviceNumberByStorage(driveHandle);
CloseHandle(driveHandle);
} else {
printf("Failure!\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
runTest(L"\\\\.\\C:");
printf("\n");
runTest(L"\\\\.\\D:");
getc(stdin);
return 0;
}
...and the output when I run it, either as Administrator or not:
Opened \\.\C:
Device number by extents: 0
Device number by storage: 0
Opened \\.\D:
Device number by extents: Incorrect function.
Device number by storage: 0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
“\\.\PhysicalDriveN”
仅适用于(类似的东西)硬盘驱动器,不适用于可移动磁盘。如果某个东西的作用类似于可移动磁盘(或软盘、CD-ROM 等),"\\.\X:"
打开原始驱动器(其他驱动器不支持分区,因此区分"\\.\x:"
和"\\.\PhysicalDiskN"
之间不存在)。您通常希望使用GetDriveType
来确定您拥有哪种类型的磁盘,只有当显示它是DRIVE_FIXED
时,您才会尝试查找驱动器编号并使用“\\.\PhysicalDriveN”
与它。The
"\\.\PhysicalDriveN"
only works for (things that act like) hard drives, not removable disks. If something acts like a removable disk (or floppy, CD-ROM, etc.),"\\.\X:"
opens the raw drive (other drives don't support partitions, so the distinction between"\\.\x:"
and"\\.\PhysicalDiskN"
doesn't exist for them). You normally want to useGetDriveType
to figure out what kind of disk you have, and only if that says it's aDRIVE_FIXED
do you attempt to find the drive number and use"\\.\PhysicalDriveN"
with it.这是 C#.Net 代码,但这是我为完成这项工作而编写的代码:
It's C#.Net code, but this is what i've written to do the job: