Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SetupDiGetDeviceInterfaceDetail - ошибка 1784 [D6, WinXP]


Artog ©   (2007-07-17 11:40:00) 

Здравствуйте. Хочу получить список всех COM портов с friendly name. Использую следующий код:


procedure EnumComPorts(List:TStrings);
const
 GUID_SERENUM_BUS_ENUMERATOR : TGuid = '{4D36E978-E325-11CE-BFC1-08002BE10318}';
var
 DevInfo          : HDEVINFO;
 devData         : SP_DEVICE_INTERFACE_DATA;
 devDetailData  : PSP_DEVICE_INTERFACE_DETAIL_DATA;
 A, Size          : DWORD;
 err                : integer;
 res               : boolean;
 s                  : string;
begin
 DevInfo :=  
 SetupDiGetClassDevs(@GUID_SERENUM_BUS_ENUMERATOR, nil, 0,
                              DIGCF_PRESENT OR  
                              DIGCF_DEVICEINTERFACE);
 if DevInfo=HDEVINFO(INVALID_HANDLE_VALUE) then Exit;
 try
   A:=0;
   devData.cbSize := Sizeof(SP_DEVICE_INTERFACE_DATA);
   while SetupDiEnumDeviceInterfaces(DevInfo,
                                     nil,
                                     @GUID_SERENUM_BUS_ENUMERATOR,
                                     A,
                                     devData) do begin
        Size := 0;
        res := SetupDiGetDeviceInterfaceDetail(DevInfo,
                                               @devData,
                                               nil,
                                               0,
                                               @Size,
                                               nil);
        GetMem(devDetailData, Size);
        devDetailData.cbSize :=
                         sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

        res := SetupDiGetDeviceInterfaceDetail(DevInfo,
                                               @devData,
                                               devDetailData,
                                               Size,
                                               nil,
                                               nil);
             err := GetLastError;
             S:= devDetailData.DevicePath;
        Inc(A);
      end;
 finally
   SetupDiDestroyDeviceInfoList(DevInfo);
 end;
end;


При этом в err возвращается ошибка 1784 - ERROR_INVALID_USER_BUFFER. Может кто подскажет в чем проблема? Спасибо.


Artog   (2007-07-17 12:29:00) [1]

>QueryDosDevice или из реестра читать HARDWARE\DEVICEMAP\SERIALCOMM

QueryDosDevice не возвращает friendly name.

>Тык вот, попробуй цикл, где с некоторого нижнего порога наращивается переменная

Действительно, оказался не тот размер структуры.


MBo   (2007-07-17 12:20:00) [2]

а более простые способы не подойдут, например, с использованием
QueryDosDevice или из реестра читать HARDWARE\DEVICEMAP\SERIALCOMM


Сергей М.   (2007-07-17 12:13:00) [3]


> Вроде я так и делаю


Так то оно так, да вот сама декларация структуры SP_DEVICE_INTERFACE_DETAIL_DATA под сомнением ..


Dib@zol   (2007-07-17 12:12:00) [4]

МСДН тоже не всегда точен. Напр в справке по структуре OPENFILENAME пишется что в cb надо прописать размер структуры, фактически SIZEOF. Но в ВЦЛ однако действуют так:

var
 i : Word;
 OSV : OSVERSIONINFO;

...

 FillChar(OSV, SIZEOF(OSVERSIONINFO), 0);
 OSV.dwOSVersionInfoSize:=SIZEOF(OSVERSIONINFO);
 GetVersionEx(OSV);
 with OSV do begin
   if (dwMajorVersion>=5)and
      (dwPlatformId=VER_PLATFORM_WIN32_NT)or // Win 2000
     ((dwPlatformId=VER_PLATFORM_WIN32_WINDOWS)and
      (dwMajorVersion>=4)and
      (dwMinorVersion>=90)) then             // Win ME
     i:=SIZEOF(OPENFILENM)
   else
     i:=SIZEOF(OPENFILENM)-(SIZEOF(DWORD) shl 1)-SIZEOF(Pointer);
 end;

где i и есть нужный размер.
Тык вот, попробуй цикл, где с некоторого нижнего порога наращивается переменная и как только возвратится результат "операция выполнилась успешно", раздавался гррррооомкий звук и мессиджБокс приносил тебе на тарелочке результат :)


Artog   (2007-07-17 12:03:00) [5]

Выдержка из msdn: The caller must set DeviceInterfaceDetailData.cbSize to sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) before calling this function. The cbSize field always contains the size of the fixed part of the data structure, not a size reflecting the variable-length string at the end.
Вроде я так и делаю.


Сергей М.   (2007-07-17 11:54:00) [6]


> в чем проблема?


Не исключено что в неверном передаваемом тобой значении devDetailData.cbSize


Наверх

Титульная страница Поиск, карта сайта Написать письмо