Здравствуйте, Lipatov, Вы писали:
L>Здравствуйте, Dexter, Вы писали:
D>>А надо и под NT и под 9х... L>Задачу решается по разному для NT и Win9x.
L>Сначала получаем список всех логических дисков, определяем их тип и сохраняем полученную информацию
L>res = GetLogicalDrives(); L>if(!res) return 0;
L>int i = 0; L>sprintf(drv,"a:\\"); L>for (i=1;i<32;i++) L>{ L> int j=0; L> int pw = 1; L> for (;j<(i-1);j++) pw = pw*2;
L> if((res & pw) != 0) L> { L> char dl; L> dl = 'A' + i — 1; L> drv[0] = dl; L> DWORD dt = GetDriveType(drv); L> list[counter].DriveLetter = dl; L> list[counter].sign = 0; L> if(dt == DRIVE_FIXED) L> { L> nHDD++; L> strcpy(list[*counter].type, "HDD"); L> char name[] = "\\\\.\\A:"; L> name[4] = list[counter].DriveLetter; L> HANDLE hDisk = CreateFile(name, GENERIC_READ|GENERIC_WRITE, L> FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); L> DWORD junk;
L> BYTE LayoutInfo[0xFFFF]; L> // Для WinNT получаем информацию о расположении лог. дисков на утройстве hDisk. L> // То что hDisk — лог. диск не имеет значения, функция выполнится для физ. диска, L> // на котором находится hDisk. Если у нас Win9x, то DeviceIoControl вернет FALSE L> if(!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0, L> LayoutInfo, 0xFFFF, &junk, NULL)) L> { L> CloseHandle(hDisk); L> continue; L> }
L> // Сохраняем сигнатуру физического диска для данного лог. диска L> list[*counter].sign = ((DRIVE_LAYOUT_INFORMATION*)LayoutInfo)->Signature; L> CloseHandle(hDisk); L> }
L> counter++; L> } L>}
L>Для NT: L>Далее вызываем QueryDosDevice: QueryDosDevice("PhysicalDriveN", Buff, 1024) для каждого диска. Если она вернула TRUE, то диск имеется L>и можно получить его сигнатуру, описанным выше способом:
L>HANDLE hDevice = CreateFile(DriveName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); L>if(hDevice == INVALID_HANDLE_VALUE) continue;
L>DWORD junk;
L> if(DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, L> 0, LayoutInfo, 0xFFFF, &junk, NULL)) L>{ L> // Получаем сигнатуру и сравниваем с уже полученными L>}
L>Для Win9x:
L>#define VWIN32_DIOC_DOS_IOCTL 1
L>HANDLE hVxD = CreateFile("\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);
L>if(hVxD == INVALID_HANDLE_VALUE) return -2;
L>DRIVE_MAP_INFO map; L>DIOC_REGISTERS reg; L>DWORD junk;
L>// для всех fixed дисков L>for(j = 0; j < counter; j++) L>{ L> if(strcmp(list[j].type, "HDD")) continue; L> SetLastError(0);
L> reg.reg_EAX = 0x440D; // IOCTL for block devices L> reg.reg_EBX = list[j].DriveLetter + 1 — 'A';// zero-based drive identifier L> reg.reg_ECX = 0x86F; // Get Media ID command L> reg.reg_EDX = (DWORD) ↦ // receives media identifier information L> reg.reg_Flags = 0x0001; // assume error (carry flag is set)
L> map.dmiAllocationLength = sizeof(map);
L> if(!DeviceIoControl(hVxD, VWIN32_DIOC_DOS_IOCTL, L> ®, sizeof(reg), L> ®, sizeof(reg), L> &junk, NULL)) continue;
L> // Получаем номер физичексого диска (от нуля) L> int PhDiskNo = 0x80 — map.dmiInt13Unit; L>}
L>CloseHandle(hVxD);
L>Вот и все.
Подход неправильный, поскольку если на диске нет томов(разделов) с буквами, то по твоей логике этого диска не увидишь.
Под NT очень просто:
CreateFileW( L"\\PHYSICALDRIVE%d", ... ),
где вместо %d надо подставлять 0,1,2,...
Если получил handle, то можешь затем вызвать DeviceIoControl( IOCTL_DISK_GET_DRIVE_GEOMETRY, .... )