DeviceIOControl MEDIA_SERIAL_NUMBER_DATA [Delphi]

Тема в разделе "WASM.WIN32", создана пользователем transserg, 26 мар 2009.

  1. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    привет всем!
    тут возникла такая проблема, немогу разобраться почему DeviceIOcontrol не "подключается" к флешке поэтому структира пустая и немогу получить серийный! серийный номер у флешки есть! так как пробовал через WMI VID PID и серийный получаю, но хочу реализовать безе WMI, вот процедура
    Код (Text):
    1. Procedure TForm1.GetSerialNumber;
    2. var
    3.   RealPath  :String;
    4.   dg:CHANGER_PRODUCT_DATA;
    5.   Dummy   :DWord;
    6.   hDevice:HWND;
    7.   Med:MEDIA_SERIAL_NUMBER_DATA;
    8.   Serial,sd:String;
    9.   i:byte;
    10. begin
    11.    RealPath:='\\.\C:';
    12. hDevice:=CreateFile(PansiChar('\\.\PhysicalDrive1'),GENERIC_READ or GENERIC_WRITE, FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    13. {'\\.\PhysicalDrive0'}
    14. if DeviceIOControl(hDevice,IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, nil, 0, @dg, sizeof(dg), dummy, nil) then
    15.   begin
    16.     Serial:='';
    17.     for i:=0 to 31 do
    18.       Serial:=Serial+IntToStr(dg.SerialNumber[i]);
    19.       sd:=Serial;
    20.    end;
    21. ShowMessage(sd);
    22. CloseHandle(hDevice);
    23.  
    24. end;
    25.  
    26.  PMEDIASERIALNUMBERDATA=^MEDIA_SERIAL_NUMBER_DATA;
    27.    MEDIA_SERIAL_NUMBER_DATA= packed record
    28.     SerialNumberLength:Ulong;
    29.     Result:Ulong;
    30.     SerialNumberData:char;
    31.    end;
    32.  
    33. const
    34.   SERIAL_NUMBER_LENGTH = 32;
    35.   {$EXTERNALSYM SERIAL_NUMBER_LENGTH}
    36.   PRODUCT_ID_LENGTH    = 16;
    37.   {$EXTERNALSYM PRODUCT_ID_LENGTH}
    38.   REVISION_LENGTH      = 4;
    39.   VENDOR_ID_LENGTH     = 8;
    40.   {$EXTERNALSYM VENDOR_ID_LENGTH}
    41.     METHOD_BUFFERED   = 0;
    42.   FILE_ANY_ACCESS     = 0;
    43.   FILE_DEVICE_MASS_STORAGE        = $0000002d;
    44.   IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
    45.   IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER = (
    46.      (IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
    47.      ($0304 shl 2) or METHOD_BUFFERED);
    во вложении пример откуда все это взял, но там модуль и Jedi библеотеки с нима вообще не робит, так что из него взял нужные константы.
    В чем может быть ошибка?
     
  2. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    transserg
    > не "подключается" к флешке ... CreateFile(PansiChar('\\.\PhysicalDrive1')
    Причем тут флешка?

    Успешно ли выполняется CreateFile? Если нет, что сообщает GetLastError?
    Успешно ли выполняется DeviceIOControl? Если нет, что сообщает GetLastError?
     
  3. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    createfile отрабатывает без ошибок,а вот deviceioconrol с ошибкой позже скажу какая(как приду домой) phisicaldrive1 это флешка!
     
  4. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    в общем deviseiocontrol getlasterror возвращает ошибку 50! тоесть нельзя согдать запрос! почему? в чем ошибка?
     
  5. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Ну судя по всему, потому что нету такого обработчика у драйвера устройства, для запроса, который ты посылаешь.
    Ты уверен на счет IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER ? Попробуй что нибудь другое, из своего примера..
     
  6. wertyman

    wertyman Member

    Публикаций:
    0
    Регистрация:
    13 дек 2006
    Сообщения:
    74
    Да и у тебя должно быть ошибка в коде, хотя в дельфях я не силен, могу ошибаться... Переменную dummy, по ссылке надо передавать...
     
  7. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    wertyman
    Не обязательно. Если в декларации функции она описана как var, то она будет передана по ссылке автоматически.
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    transserg
    Под какой wind'ой запускаешь?
     
  9. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    sp3, в мсдн написанно что это имено она! ну если это не так то как же получить серийный?
     
  10. irrona

    irrona Member

    Публикаций:
    0
    Регистрация:
    26 май 2004
    Сообщения:
    178
    Адрес:
    Тирасполь
    transserg

    1) Структура MEDIA_SERAL_NUMBER_DATA должна иметь 5 членов, у тебя только три
    Код (Text):
    1. typedef struct _MEDIA_SERAL_NUMBER_DATA {
    2.     ULONG  msn_SerialNumberLength;          // offset 00
    3.     ULONG  msn_Result;                      // offset 04
    4.     ULONG  msn_AuthCommand;                 // offset 08
    5.     ULONG  msn_Reserved;                    // offset 12
    6.     UCHAR  msn_SerialNumberData[1];         // offset 16
    7. } MEDIA_SERIAL_NUMBER_DATA, *PMEDIA_SERIAL_NUMBER_DATA;
    2) Насколько я понял, после вызова DeviceIoControl, серийный номер возвращается в структуре MEDIA_SERAL_NUMBER_DATA, а не в CHANGER_PRODUCT_DATA. Ты же вызываешь почему-то:
    Код (Text):
    1. DeviceIOControl(hDevice,IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, nil, 0, @dg, sizeof(dg), dummy, nil)
    , где @dg - это CHANGER_PRODUCT_DATA

    3) Всё же попробуй вызвать CreateFile с указанием имени диска (например, \\.\E:), вместо гипотетического PhysicalDrive
     
  11. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    да тактоже пробовал) писал '\\.\H:' и нужную структуру справил все поля на месте но результат тот же ошибка 50
     
  12. transserg

    transserg New Member

    Публикаций:
    0
    Регистрация:
    24 мар 2009
    Сообщения:
    17
    вот то что я делаю
    констаты и структура
    Код (Text):
    1. const
    2.   METHOD_BUFFERED   = 0;
    3.   FILE_ANY_ACCESS     = 0;
    4.   FILE_DEVICE_MASS_STORAGE        = $0000002d;
    5.   IOCTL_STORAGE_BASE = FILE_DEVICE_MASS_STORAGE;
    6.   IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER = (
    7.      (IOCTL_STORAGE_BASE shl 16) or (FILE_ANY_ACCESS shl 14) or
    8.      ($0304 shl 2) or METHOD_BUFFERED);
    9.  
    10. type
    11.    PMEDIASERIALNUMBERDATA=^MEDIA_SERIAL_NUMBER_DATA;
    12.    MEDIA_SERIAL_NUMBER_DATA= packed record
    13.     SerialNumberLength:Cardinal;
    14.     Result:Cardinal;
    15.     AuthCommand:Cardinal;
    16.     Reserved:Cardinal;
    17.     SerialNumberData:Byte;
    18.    end;
    вот процедура
    Код (Text):
    1. Procedure TForm1.GetSerialNumber;
    2.   var
    3.     RealPath  :String;
    4.     Dummy   :DWord;
    5.     hDevice:HWND;
    6.     Med:PMEDIASERIALNUMBERDATA;
    7.     Serial:String;
    8.   begin
    9.     RealPath:='\\.\G:';
    10.     hDevice:=CreateFile(PAnsiChar(RealPath),GENERIC_READ or GENERIC_WRITE,
    11.              FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    12.     {'\\.\PhysicalDrive0'}
    13.     ShowMessage('CreateFile'+#13+SysErrorMessage(GetLastError)+#13+Inttostr(GetLastError));
    14.     GetMem(med,Sizeof(med));
    15.     if DeviceIOControl(hDevice,IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER, nil, 0, med, sizeof(med), dummy, nil) then
    16.       begin
    17.         Serial:='';
    18.         serial:=serial+(Med^.SerialNumberData);
    19.         ShowMessage(Serial);
    20.        end;
    21.     ShowMessage('DeviceIOControl'+#13+SysErrorMessage(GetLastError)+#13+Inttostr(GetLastError));
    22.     CloseHandle(hDevice);
    23.     Freemem(med);
    24.    end;