Re[3]: Сколько HDD в системе?
От: Lipatov  
Дата: 09.12.03 05:31
Оценка:
Здравствуйте, Dexter, Вы писали:

D>А надо и под NT и под 9х...

Задачу решается по разному для NT и Win9x.

Сначала получаем список всех логических дисков, определяем их тип и сохраняем полученную информацию

res = GetLogicalDrives();
if(!res) return 0;

int i = 0;
sprintf(drv,"a:\\");
for (i=1;i<32;i++)
{
int j=0;
int pw = 1;
for (;j<(i-1);j++) pw = pw*2;

if((res & pw) != 0)
{
char dl;
dl = 'A' + i — 1;
drv[0] = dl;
DWORD dt = GetDriveType(drv);
list[counter].DriveLetter = dl;
list[counter].sign = 0;
if(dt == DRIVE_FIXED)
{
nHDD++;
strcpy(list[*counter].type, "HDD");
char name[] = "\\\\.\\A:";
name[4] = list[counter].DriveLetter;
HANDLE hDisk = CreateFile(name, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
DWORD junk;

BYTE LayoutInfo[0xFFFF];
// Для WinNT получаем информацию о расположении лог. дисков на утройстве hDisk.
// То что hDisk — лог. диск не имеет значения, функция выполнится для физ. диска,
// на котором находится hDisk. Если у нас Win9x, то DeviceIoControl вернет FALSE
if(!DeviceIoControl(hDisk, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL, 0,
LayoutInfo, 0xFFFF, &junk, NULL))
{
CloseHandle(hDisk);
continue;
}

// Сохраняем сигнатуру физического диска для данного лог. диска
list[*counter].sign = ((DRIVE_LAYOUT_INFORMATION*)LayoutInfo)->Signature;
CloseHandle(hDisk);
}

counter++;
}
}

Для NT:
Далее вызываем QueryDosDevice: QueryDosDevice("PhysicalDriveN", Buff, 1024) для каждого диска. Если она вернула TRUE, то диск имеется
и можно получить его сигнатуру, описанным выше способом:

HANDLE hDevice = CreateFile(DriveName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(hDevice == INVALID_HANDLE_VALUE) continue;

DWORD junk;

if(DeviceIoControl(hDevice, IOCTL_DISK_GET_DRIVE_LAYOUT, NULL,
0, LayoutInfo, 0xFFFF, &junk, NULL))
{
// Получаем сигнатуру и сравниваем с уже полученными
}

Для Win9x:

#define VWIN32_DIOC_DOS_IOCTL 1

HANDLE hVxD = CreateFile("\\\\.\\vwin32", 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL);

if(hVxD == INVALID_HANDLE_VALUE) return -2;

DRIVE_MAP_INFO map;
DIOC_REGISTERS reg;
DWORD junk;

// для всех fixed дисков
for(j = 0; j < counter; j++)
{
if(strcmp(list[j].type, "HDD")) continue;
SetLastError(0);

reg.reg_EAX = 0x440D; // IOCTL for block devices
reg.reg_EBX = list[j].DriveLetter + 1 — 'A';// zero-based drive identifier
reg.reg_ECX = 0x86F; // Get Media ID command
reg.reg_EDX = (DWORD) &map; // receives media identifier information
reg.reg_Flags = 0x0001; // assume error (carry flag is set)

map.dmiAllocationLength = sizeof(map);

if(!DeviceIoControl(hVxD, VWIN32_DIOC_DOS_IOCTL,
&reg, sizeof(reg),
&reg, sizeof(reg),
&junk, NULL)) continue;

// Получаем номер физичексого диска (от нуля)
int PhDiskNo = 0x80 — map.dmiInt13Unit;
}

CloseHandle(hVxD);

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