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;
}