Получение информации о HDD

Тема в разделе "WASM.WIN32", создана пользователем Exp10der, 2 ноя 2008.

  1. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    Подскажите как можно средствами win32 получить сектор описания HDD там серийный номер, параметры и т. д. можно канеш напрямую ч-з драйвер кинуть команду идентификации, но хотелось бы чтонибудь по красивее.. типа IOCTL_DISK_GET_DRIVEINFO :) что вобщем почитать по теме низкоуровневой работы с винтом в win32?..
     
  2. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    Есть 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, я тут даже тему создавал, но так никто ниче и не ответил...
     
  3. Exp10der

    Exp10der Мастер дзена

    Публикаций:
    0
    Регистрация:
    27 авг 2007
    Сообщения:
    337
    Адрес:
    Красноярск
    То что нужно, спасибо за помощь..

    Хм... а если из драйвера рулить хардом ч-з I/O порты, проблемы с мультитаскингом могут возникнуть или система смотрит на флаг занятости харда?.. имхо как то не красиво работают смарт команды с винтом тем более что через них только 0ECh работает из всех АТА команд :dntknw: ...
     
  4. Av0id

    Av0id New Member

    Публикаций:
    0
    Регистрация:
    21 окт 2004
    Сообщения:
    87
    исходник перевыложите plz
     
  5. K10

    K10 New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2008
    Сообщения:
    1.590
    http://slil.ru/26415841
     
  6. facelift

    facelift New Member

    Публикаций:
    0
    Регистрация:
    18 ноя 2008
    Сообщения:
    25
    А чтобы не парится с PhysicalDrive0/SCSI0 можно написать так \\.\C:.

    Я те даже сорсы дам
    Код (Text):
    1. void trim(std::string& str)
    2. {
    3.     std::string::size_type pos = str.find_last_not_of(' ');
    4.     if(pos != std::string::npos) {
    5.         str.erase(pos + 1);
    6.         pos = str.find_first_not_of(' ');
    7.         if(pos != std::string::npos) str.erase(0, pos);
    8.     }
    9.     else str.erase(str.begin(), str.end());
    10. }
    11.  
    12. std::string GetSystemDriveString()
    13. {
    14.     char driveLetter[3];
    15.     if(GetEnvironmentVariable("SystemDrive", driveLetter, 3) == 0)
    16.     {
    17.         throw EnvironmentException();
    18.     };
    19.     return driveLetter;
    20. }
    21.  
    22. std::string FormatDriveStringToIoCtlDriveString(const std::string &driveLetter)
    23. {
    24.     std::string tempString("\\\\.\\");
    25.     tempString += driveLetter;
    26.     return tempString;
    27. }
    28.  
    29. HANDLE OpenIOCtlDrive(const std::string &ioCtlDriveLetter)
    30. {
    31.     return CreateFile(ioCtlDriveLetter.c_str(),
    32.                       GENERIC_READ | GENERIC_WRITE,
    33.                       FILE_SHARE_READ | FILE_SHARE_WRITE,
    34.                       NULL,OPEN_EXISTING, 0, NULL);
    35. }
    36.  
    37. std::string GetDriveSerialNumber(HANDLE driveHandle)
    38. {
    39.     const int IDENTIFY_BUFFER_SIZE = 512;
    40.  
    41.     BYTE IdOutCmd [sizeof (SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1];
    42.     memset (IdOutCmd, 0, sizeof(IdOutCmd));
    43.  
    44.     GETVERSIONOUTPARAMS versionParams;
    45.     SENDCMDINPARAMS scip;    
    46.     USHORT *pIdSector;
    47.  
    48.     DWORD cbBytesReturned;
    49.  
    50.     if(!DeviceIoControl(driveHandle,
    51.                         DFP_GET_VERSION,
    52.                         NULL,
    53.                         0,
    54.                         &versionParams,
    55.                         sizeof(versionParams),
    56.                         &cbBytesReturned, 0))
    57.     {
    58.         throw IOCtlException();
    59.     }
    60.     memset(&scip, 0, sizeof(scip));
    61.  
    62.     scip.irDriveRegs.bCommandReg = (versionParams.bIDEDeviceMap >> 0 & 0x10) ? IDE_ATAPI_IDENTIFY : IDE_ATA_IDENTIFY;
    63.  
    64.     if(!DeviceIoControl(driveHandle, DFP_RECEIVE_DRIVE_DATA,
    65.                         (LPVOID)&scip,
    66.                         sizeof( SENDCMDINPARAMS ) - 1,
    67.                         (LPVOID)IdOutCmd,
    68.                         sizeof( SENDCMDOUTPARAMS ) + IDENTIFY_BUFFER_SIZE - 1,
    69.                         &cbBytesReturned, 0))
    70.     {
    71.         throw IOCtlException();
    72.     }
    73.  
    74.     pIdSector = (USHORT *)
    75.         ((PSENDCMDOUTPARAMS) IdOutCmd) -> bBuffer;
    76.  
    77.     std::string serialNumber;
    78.     for(int i = 10; i < 20; ++i)
    79.     {
    80.         serialNumber += static_cast<char>(pIdSector[i] / 256);
    81.         serialNumber += static_cast<char>(pIdSector[i] % 256);
    82.     }
    83.  
    84.     trim(serialNumber);
    85.     return serialNumber;
    86. }
    87.  
    88. std::string GetSystemDriveSerialNumber()
    89. {
    90.     std::string tempString = GetSystemDriveString();
    91.     tempString = FormatDriveStringToIoCtlDriveString(tempString);
    92.  
    93.     HANDLE tempHandle = OpenIOCtlDrive(tempString);
    94.     if(tempHandle == INVALID_HANDLE_VALUE)
    95.     {
    96.         throw IOCtlException();
    97.     }
    98.     return GetDriveSerialNumber(tempHandle);
    99. }