Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > DeviceIOControl


Автор: Artem148 20.6.2011, 18:35
Здрасте!

Функция  DeviceIOControl с параметром IOCTL_STORAGE_QUERY_PROPERTY возврашает:

    1) VendorIdOffset        
    2) ProductIdOffset       
    3) ProductRevisionOffset 
    4) SerialNumberOffset    

Всё в DWORD`e

Вопрос: Как получить(конвертировать) это в String?


Заранее спасибо!

Автор: Dik0n 20.6.2011, 22:30
Цитата(Artem148 @  20.6.2011,  18:35 Найти цитируемый пост)
Вопрос: Как получить(конвертировать) это в String?

IntToStr(); - даже как то странно, этого не знать smile 

Автор: kami 20.6.2011, 23:56
Цитата(Dik0n @  20.6.2011,  22:30 Найти цитируемый пост)
IntToStr(); - даже как то странно, этого не знать

В данном случае - неверно.
Потому что указанные параметры - это смещения относительно начала выходного буфера. По этому смещению начинается ASCII строка с завершающим 0, т.е. PAnsiChar.
Добраться до нее можно как-то так (общий принцип):

Код

var
  OutBuffer: pointer; // или PSTORAGE_DEVICE_DESCRIPTOR, или как_Вы_его_обозвали, без разницы - в любом случае это указатель
  PVendorID: PAnsiChar;
begin
  ...
  DeviceIOCtl(... , OutBuffer, ...);
  // сами смещения не рассматриваю, предполагаем, что их из этого OutBuffer мы получили.
  
  PVendorID:=PAnsiChar(pointer(DWORD(OutBuffer)+OutBuffer.VendorIdOffset));
  // собственно, и всё - пусть и в Pchar, но нужный показатель получен. Перевести в string - дело техники :)
...
end;


Добавлено @ 23:59
Ну и, само собой - VendorIDOffset и т.п. для правильного получения строки не должно быть =0, о чем прямо сказано в http://msdn.microsoft.com/en-us/library/ff800835(v=vs.85).aspx

Автор: Dik0n 21.6.2011, 00:17
Цитата(kami @  20.6.2011,  23:56 Найти цитируемый пост)
В корне неверно.

Я подумал что надо просто DWORD в строку конвертировать smile 

Код

type
PSTORAGE_DEVICE_DESCRIPTOR = ^STORAGE_DEVICE_DESCRIPTOR;
_STORAGE_DEVICE_DESCRIPTOR = packed record
  Version: DWord; // Sizeof(_STORAGE_DEVICE_DESCRIPTOR)
  Size: DWord; // Total size of the descriptor, including the space for additional data and id strings
  DeviceType: Byte; // The SCSI-2 device type
  DeviceTypeModifier: Byte;  // The SCSI-2 device type modifier, if any, - this may be zero
  RemovableMedia: Boolean;
  CommandQueueing: Boolean;
  VendorIdOffset: DWord;
  ProductIdOffset: DWord;
  ProductRevisionOffset: DWord;
  SerialNumberOffset: DWord;
  BusType: STORAGE_BUS_TYPE;
  RawPropertiesLength: DWord;
  _Fill: array[0..2] of Byte;
  RawDeviceProperties: array[0..0] of Byte;
 end;

procedure Test()
var
  Buf: _STORAGE_DEVICE_DESCRIPTOR;
begin
  DeviceIOControl(... , @Buf, ...);
  Label.Caption := PAnsiChar(DWORD(Buf) + Buf.SerialNumberOffset);
end;

Автор: kami 21.6.2011, 08:33
Цитата(Dik0n @  21.6.2011,  00:17 Найти цитируемый пост)
DeviceIOControl(... , @Buf, ...);

И будете всегда получать ERROR_INSUFFICIENT_BUFFER. Потому что RawDeviceProperties - это всего лишь указатель на первый байт области памяти, в которой хранятся те самые PAnsiVendorID и т.д. В Вашем же примере размер выходного буфера постоянен. И никакие данные в 1 байт не влезут.

Автор: Artem148 21.6.2011, 13:36
[DCC Error] E2089 Invalid typecast

Автор: kami 21.6.2011, 15:26
Цитата(Artem148 @  21.6.2011,  13:36 Найти цитируемый пост)
[DCC Error]

http://lurkmore.ru/%D2%E5%EB%E5%EF%E0%F2%FB_%E2_%EE%F2%EF%F3%F1%EA%E5. Что Invalid typecast ?

Автор: Artem148 22.6.2011, 20:32
Код

type
  TSTORAGE_PROPERTY_QUERY = packed record
    PropertyId:              Integer; 
    QueryType:               Integer;  
    AdditionalParameters: array [0..1] of WORD;  
  end;

type  
  TSTORAGE_DEVICE_DESCRIPTOR           = packed record
    Version:                           DWORD;
    Size:                                DWORD;
    DeviceType:                     Byte;
    DeviceTypeModifier:         Byte;
    RemovableMedia:            Boolean;
    CommandQueueing:       Boolean;
    VendorIdOffset:              DWORD;
    ProductIdOffset:             DWORD;
    ProductRevisionOffset:   DWORD;
    SerialNumberOffset:       DWORD;
    StorageBusType:            STORAGE_BUS_TYPE;
    RawPropertiesLength:    DWORD;
    RawDeviceProperties:     array[0..1] of Byte;

var
  STORAGE_PROPERTY_QUERY:      TSTORAGE_PROPERTY_QUERY;
  STORAGE_DEVICE_DESCRIPTOR: TSTORAGE_DEVICE_DESCRIPTOR;

lblProductId.Caption := PAnsiChar(pointer(DWORD(STORAGE_DEVICE_DESCRIPTOR) +   // DWORD(STORAGE_DEVICE_DESCRIPTOR) <== Здесь "[DCC Error] E2089 Invalid typecast"
                                                           STORAGE_DEVICE_DESCRIPTOR.VendorIdOffset))




Цитата

   "телепаты в отпуске..."  

        а жаль....

Автор: kami 22.6.2011, 22:08
Цитата(Artem148 @  22.6.2011,  20:32 Найти цитируемый пост)
Здесь "[DCC Error] E2089 Invalid typecast

А Вы обратили внимание, какого типа буфер у меня в примере (приставка P о чем-нибудь говорит?):
Цитата(kami @  20.6.2011,  23:56 Найти цитируемый пост)
OutBuffer: pointer; // или PSTORAGE_DEVICE_DESCRIPTOR


и у Вас:
Цитата(Artem148 @  22.6.2011,  20:32 Найти цитируемый пост)
STORAGE_DEVICE_DESCRIPTOR: TSTORAGE_DEVICE_DESCRIPTOR;

Все равно - наступите на те же грабли, что и в коде Dik0n.

Добавлено @ 22:19
Совет: Найдите поиском в интернете код, который выкладывала Riply. Afair, дело было на DelphiMaster.

Автор: Dik0n 23.6.2011, 08:30
Цитата(kami @  22.6.2011,  22:08 Найти цитируемый пост)
Найдите поиском в интернете код, который выкладывала Riply

http://forum.sources.ru/index.php?showtopic=210411 оно не ?

Автор: Artem148 23.6.2011, 11:26
Цитата(kami @ 22.6.2011,  22:08)
А Вы обратили внимание, какого типа буфер у меня в примере (приставка P о чем-нибудь говорит?):
Цитата(kami @  20.6.2011,  23:56 Найти цитируемый пост)
OutBuffer: pointer; // или PSTORAGE_DEVICE_DESCRIPTOR


и у Вас:
Цитата(Artem148 @  22.6.2011,  20:32 Найти цитируемый пост)
STORAGE_DEVICE_DESCRIPTOR: TSTORAGE_DEVICE_DESCRIPTOR;



http://ru.wikipedia.org/wiki/Офтальмология тоже в отпуске...


Да, всё равно в Type где-то вру...   smile 
Если вас не затруднит, можете скинуть пример...

Автор: kami 23.6.2011, 15:12
Цитата(Artem148 @  23.6.2011,  11:26 Найти цитируемый пост)
Да, всё равно в Type где-то вру...    Если вас не затруднит, можете скинуть пример...

Вам была дана вся необходимая информация: ключевые моменты, ссылки на описания в MSDN и ссылка на пример использования (за Вас ее нашел Dik0n).
Вы залезли достаточно глубоко в WinAPI, где далеко не всегда существуют примеры "на все случаи жизни", а писать за Вас уже готовый код вряд ли будут. Учитесь адаптировать "под себя" то, что дано.

Добавлено через 6 минут и 17 секунд
Совет - чтобы не ошибиться в объявлении типов, рекомендую воспользоваться http://sourceforge.net/projects/jedi-apilib/

Автор: Artem148 24.6.2011, 21:55
Вопрос снят!

kami, всё дело оказалась прозаичнее: во всём виновата десятая еврейская делфи(всё ей не так!  smile  ), 
                   запустил в 2007 - работает и мой код и ваш(после небольшой доработки  smile  )


Всем спасибо за помощь  и утраченное время  smile 

P.S Delphi XE капризничает уже так не первый раз ...  smile 

Автор: kami 24.6.2011, 23:04
Цитата(Artem148 @  24.6.2011,  21:55 Найти цитируемый пост)
во всём виновата десятая еврейская делфи(всё ей не так!    ), 

Думается, Delphi здесь ни при чем smile
Отличие версии 2007 от 2010 в большинстве случаев "виноватости" состоит только в одном:
в 2007 string = AnsiString
в 2010 string = UnicodeString.
Со всеми вытекающими.

Автор: Artem148 25.6.2011, 19:29
P.S Всё равно получаю в Delphi XE китайские символы...
      Всё обгуглил; функции конвектирования нет...   Ну что ж, пойду учить китайский...  smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)