Re[4]: Сколько HDD в системе?
От: Аноним  
Дата: 09.12.03 12:22
Оценка:
Здравствуйте, 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) &map; // 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> &reg, sizeof(reg),
L> &reg, 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, .... )

Под 9x чуть сложнее, но долго писать.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.