question

HUANGda avatar image
0 Votes"
HUANGda asked HUANGda answered

How to list all physical drives and find there drive letter?

What I am doing is, to help users (me) to find the raw data sdcard (its physical drive no). and to warn them (me) not to WRITE any thing on that drive letter.

for finding part, I have done this:

for (1 to 10) {
CreateFile(""\.\PhysicalDriveX", ...
if invalid handle, break.
}

I could get all physical drives.


But for warning part, how can I get there drive letter?
I found a sample code like this:

GetLogicalDriveStrings()
for (those drive strings) {
handle = CreateFile(drive string, ...
DeviceIoControl(handle , IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, ...
}

But for C drive, I got a "3 = ERROR_PATH_NOT_FOUND",
for D~G drive, sdcard read without card, I got "21 = ERROR_NOT_READY",
for H drive, sdcard read with a raw data card, I got "1005 = ERROR_UNRECOGNIZED_VOLUME"

Please help.
(Using pure C with win32 api)

windows-app-sdk
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Castorix31 avatar image
1 Vote"
Castorix31 answered Castorix31 edited

I have this old code in my archives which seems to work (as Admin) :

 WCHAR sBuf[1000];
 WCHAR sBuffer1[255], sBuffer2[50];
 DWORD nSize, nCpt;
 nSize = GetLogicalDriveStrings(1000, sBuf);
 nCpt = 0;
 while (nCpt < nSize)
 {
     wsprintf(sBuffer1, L"\\\\.\\%s", &sBuf[nCpt]);
     sBuffer1[6] = 0;
     // strcpy(sBuffer1, &num[6]);
     HANDLE  hVol = NULL;
     hVol = CreateFile(sBuffer1,
         GENERIC_READ,
         FILE_SHARE_READ | FILE_SHARE_WRITE,
         NULL,
         OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL,
         NULL);
     int                         maxDisks;
     BOOL                        b;
     DWORD                       cbBytes;
     PVOLUME_DISK_EXTENTS        PVolDiskExtent;
     PVolDiskExtent = (PVOLUME_DISK_EXTENTS)LocalAlloc(LMEM_FIXED, sizeof(VOLUME_DISK_EXTENTS));
     STORAGE_DEVICE_NUMBER sdn;
     DWORD dwBytesReturned = 0;
     b = DeviceIoControl(hVol, IOCTL_STORAGE_GET_DEVICE_NUMBER, NULL, 0, &sdn, sizeof(sdn), &dwBytesReturned, NULL);
     int nType = sdn.DeviceType;
     b = DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, PVolDiskExtent, sizeof(VOLUME_DISK_EXTENTS), &cbBytes, NULL);
     int nDiskNumber = 0;
     if (!b)
     {
         int n = GetLastError();
         if (n == ERROR_MORE_DATA)
         {
             maxDisks = PVolDiskExtent->NumberOfDiskExtents;
             LocalFree(PVolDiskExtent);
             PVolDiskExtent = (PVOLUME_DISK_EXTENTS)LocalAlloc(LMEM_FIXED, sizeof(VOLUME_DISK_EXTENTS) + (sizeof(DISK_EXTENT) * maxDisks));
             b = DeviceIoControl(hVol, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, PVolDiskExtent, sizeof(VOLUME_DISK_EXTENTS) + (sizeof(DISK_EXTENT) * maxDisks),
                 &cbBytes,
                 NULL);
             nDiskNumber = PVolDiskExtent->Extents[0].DiskNumber;
         }
         else
             nDiskNumber = -1;
     }
     else
     {
         nDiskNumber = PVolDiskExtent->Extents[0].DiskNumber;                           
     }
     WCHAR wsText[255] = L"";
     wsprintf(wsText, L"Disk : %s - Disk Number : %d - Type : %d\n", &sBuf[nCpt], nDiskNumber, nType);
     OutputDebugString(wsText);
     CloseHandle(hVol);
     nCpt += lstrlen(&sBuf[nCpt]) + 1;
 }
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

XiaopoYang-MSFT avatar image
0 Votes"
XiaopoYang-MSFT answered XiaopoYang-MSFT commented

Have you seen the Assign Drive Letter Sample? And according to IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, DeviceIoControl receives a handle to device.

· 1
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

HUANGda avatar image
0 Votes"
HUANGda answered

WRONG: CreateFile(L"C:\\", ...

RIGHT: CreateFile(L"\\\.\\C:", ...

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.