How do you get the physical disk number of a removable device from the drive letter in Windows 7?

I am trying to find the number of the physical disk (for example, I need N in \\.\PhysicalDriveN to open the block device for reading) from the drive letter of the CDROM disk in Windows 7. This page indicates that IOCTL_STORAGE_GET_DEVICE_NUMBER should work, but it returns 0 for the disk number for C: and D: (where D: is a removable drive), so it’s not. IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS is also suggested, but with an error ERROR_INVALID_FUNCTION on D :.

I can't help but feel that somewhere I missed a key concept.

Here is 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 conclusion, when I run it, is either as an 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 
+4
source share
2 answers

"\\.\PhysicalDriveN" only works for (what works) hard drives, not removable drives. If something acts like a removable disk (or floppy disk, CD-ROM, etc.), "\\.\X:" opens the raw disk (other drives do not support partitions, so the difference between "\\.\X:" and "\\.\PhysicalDiskN" does not exist for them). Usually you want to use GetDriveType to find out which drive you have, and only if it says that DRIVE_FIXED you are trying to find the drive number and use "\\.\PhysicalDriveN" .

+5
source

This is C # .Net code, but this is what I wrote for the job:

 using System.Management; //Add in a reference to this as well in the project settings public static string GetPhysicalDevicePath(char DriveLetter) { ManagementClass devs = new ManagementClass( @"Win32_Diskdrive"); { ManagementObjectCollection moc = devs.GetInstances(); foreach(ManagementObject mo in moc) { foreach (ManagementObject b in mo.GetRelated("Win32_DiskPartition")) { foreach (ManagementBaseObject c in b.GetRelated("Win32_LogicalDisk")) { string DevName = string.Format("{0}", c["Name"]); if (DevName[0] == DriveLetter) return string.Format("{0}", mo["DeviceId"]); } } } } return ""; } 
+2
source

Source: https://habr.com/ru/post/1346068/


All Articles