Подскажите как можно средствами win32 получить сектор описания HDD там серийный номер, параметры и т. д. можно канеш напрямую ч-з драйвер кинуть команду идентификации, но хотелось бы чтонибудь по красивее.. типа IOCTL_DISK_GET_DRIVEINFO что вобщем почитать по теме низкоуровневой работы с винтом в win32?..
Есть 2 основных способа. 1. Обращение к устройству \\.\PhysicalDrive0 (0,1,2 и т.д.) и посылка ему команды SMART_GET_VERSION. В ответном буфере будет инфа и диске (серийный номер, модель, версия прошивки и т.д.). Требует прав администратора. 2. Через SCSI miniport. Обращение к устройству \\.\SCSI0 (0,1,2 и т.д.) посылка IOCTL_SCSI_MINIPORT. В запросе команда IOCTL_SCSI_MINIPORT_IDENTIFY. Не требует прав админа. Вот статья Криса Касперски, с хорошим описанием низкоуровневой работы с хардом. http://slil.ru/26296103 Исходник на Це с реализацией. http://slil.ru/26296104 В нем следует учитывать что SCSI0 и SCSI1 не обязательно IdePort0 и IdePort1. Если надо, могу скинуть реализацию на Делфи. ПС. Можно еще через WMI, можно напрямую посылать запросы девайсу WMIDataDevice, я тут даже тему создавал, но так никто ниче и не ответил...
То что нужно, спасибо за помощь.. Хм... а если из драйвера рулить хардом ч-з I/O порты, проблемы с мультитаскингом могут возникнуть или система смотрит на флаг занятости харда?.. имхо как то не красиво работают смарт команды с винтом тем более что через них только 0ECh работает из всех АТА команд ...
А чтобы не парится с PhysicalDrive0/SCSI0 можно написать так \\.\C:. Я те даже сорсы дам Код (Text): void trim(std::string& str) { std::string::size_type pos = str.find_last_not_of(' '); if(pos != std::string::npos) { str.erase(pos + 1); pos = str.find_first_not_of(' '); if(pos != std::string::npos) str.erase(0, pos); } else str.erase(str.begin(), str.end()); } std::string GetSystemDriveString() { char driveLetter[3]; if(GetEnvironmentVariable("SystemDrive", driveLetter, 3) == 0) { throw EnvironmentException(); }; return driveLetter; } std::string FormatDriveStringToIoCtlDriveString(const std::string &driveLetter) { std::string tempString("\\\\.\\"); tempString += driveLetter; return tempString; } HANDLE OpenIOCtlDrive(const std::string &ioCtlDriveLetter) { return CreateFile(ioCtlDriveLetter.c_str(), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,OPEN_EXISTING, 0, NULL); } std::string GetDriveSerialNumber(HANDLE driveHandle) { const int IDENTIFY_BUFFER_SIZE = 512; BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; memset (IdOutCmd, 0, sizeof(IdOutCmd)); GETVERSIONOUTPARAMS versionParams; SENDCMDINPARAMS scip; USHORT *pIdSector; DWORD cbBytesReturned; if(!DeviceIoControl(driveHandle, DFP_GET_VERSION, NULL, 0, &versionParams, sizeof(versionParams), &cbBytesReturned, 0)) { throw IOCtlException(); } memset(&scip, 0, sizeof(scip)); scip.irDriveRegs.bCommandReg = (versionParams.bIDEDeviceMap >> 0 & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY; if(!DeviceIoControl(driveHandle, DFP_RECEIVE_DRIVE_DATA, (LPVOID)&scip, sizeof( SENDCMDINPARAMS ) - 1, (LPVOID)IdOutCmd, sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1, &cbBytesReturned, 0)) { throw IOCtlException(); } pIdSector = (USHORT *) ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer; std::string serialNumber; for(int i = 10; i < 20; ++i) { serialNumber += static_cast<char>(pIdSector[i] / 256); serialNumber += static_cast<char>(pIdSector[i] % 256); } trim(serialNumber); return serialNumber; } std::string GetSystemDriveSerialNumber() { std::string tempString = GetSystemDriveString(); tempString = FormatDriveStringToIoCtlDriveString(tempString); HANDLE tempHandle = OpenIOCtlDrive(tempString); if(tempHandle == INVALID_HANDLE_VALUE) { throw IOCtlException(); } return GetDriveSerialNumber(tempHandle); }