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