Timofey_219 0 25 июля, 2009 Опубликовано 25 июля, 2009 (изменено) · Жалоба Есть USB устройство. Подключаю его к компу. Драйвер ставится, все хорошо. Устройство видно в диспетчере. У него есть один интерфейс с тремя точками (кроме нулевой): 1 - от хоста в устройство (2 байта длиной), 4 и 5 - от устройства к хосту (256 байт длиной). Пишу следующие строки HDEVINFO hDevInfo; PSP_DEVICE_INTERFACE_DATA pDevInfoData = NULL; PSP_DEVICE_INTERFACE_DETAIL_DATA pDevInfoDetail = NULL; ULONG nNameLen; Driver = INVALID_HANDLE_VALUE; hDevInfo = SetupDiGetClassDevsA((GUID*)&GUID_USBSRV_TYPE_DEVICE,NULL,NULL,DIGCF_PRESENT|DIGCF_INTERFACEDEVICE); pDevInfoData = new SP_DEVICE_INTERFACE_DATA; pDevInfoData->cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if (SetupDiEnumDeviceInterfaces(hDevInfo,NULL,(GUID*)&GUID_USBSRV_TYPE_DEVICE,0,pDevInfoData)) { SetupDiGetInterfaceDeviceDetail(hDevInfo,pDevInfoData,NULL,0,&nNameLen,NULL); pDevInfoDetail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) new unsigned char[nNameLen]; pDevInfoDetail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); SetupDiGetInterfaceDeviceDetailA(hDevInfo,pDevInfoData,pDevInfoDetail,nNameLen,&nNameLen,NULL); Driver = CreateFile(pDevInfoDetail->DevicePath,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPE N_EXISTING,0,0); } delete pDevInfoData; delete[] pDevInfoDetail; GUID_USBSRV_TYPE_DEVICE= (D1: $36FC9E60; D2: $C465; D3: $11CF; D4: ($80, $56, $44, $45, $53, $54, $00, $00)); Проблема в том, что функция SetupDiEnumDeviceInterfaces всегда возвращает мне ошибку, что интерфейсов не найдено. Я даже перебрал остальные GUID ради интереса, которые нашел в реестре. В чем может быть причина? Или может есть другие способы получения имени и открытия устройства как файла? З.Ы. Выравнивания в программе отключено для структур. З.Ы.Ы. И еще, чем отличаются функции SetupDiGetClassDevsA от SetupDiGetClassDevsW? В мсдн вобще про них ничего не нашел, есть просто SetupDiGetClassDevs, но её нет в библиотеке винды :( Изменено 25 июля, 2009 пользователем Timofey Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 25 июля, 2009 Опубликовано 25 июля, 2009 · Жалоба И еще, чем отличаются функции SetupDiGetClassDevsA от SetupDiGetClassDevsW? В мсдн вобще про них ничего не нашел, есть просто SetupDiGetClassDevs, но её нет в библиотеке винды :( С буквой W идут функции, у которых стринговый аргумент widechar, т.е. такой, когда символ занимает два байта вместо одного. Только обычно комилятор сам решает, с буквой A ему выбирать функцию или с буквой W, а программист эти буквы не пишет, а только в опциях устанавливает то, с какого рода символами он работает. А на счет вашего вопроса вот тут почитайте, может поможет: http://borland.xportal.ru/forum/printview....f9c7e2ae9c64f9e Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба Спасибо большое. Я натыкался уже на такой пост. Я тут переделал под делфи 7 код, получилось следующее unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private declarations } public { Public declarations } end; var Form1: TForm1; ss:String; Driver,Drivers:Cardinal; implementation {$R *.dfm} const GUID_DEVCLASS: TGUID = (D1: $36FC9E60; D2: $C465; D3: $11CF; D4: ($80, $56, $44, $45, $53, $54, $00, $00)); {36FC9E60-C465-11CF-8056-444553540000} DIGCF_PRESENT = $00000002; SPDRP_DEVICEDESC = $00000000; DIGCF_DEVICEINTERFACE = $00000010; DIGCF_DEFAULT = $00000001; DIGCF_ALLCLASSES = $00000004; DIGCF_PROFILE = $00000008; type HDEVINFO = THandle; RETURN_TYPE = DWORD; CONFIGRET = RETURN_TYPE; SP_DEVINFO_DATA = packed record cbSize: DWORD; ClassGuid: TGUID; DevInst: DWORD; Reserved: DWORD; end; PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA; SP_DEVICE_INTERFACE_DATA= packed record cbSize:DWORD; InterfaceClassGuid:TGUID; Flags:DWORD; Reserved: DWORD; end; PSP_DEVICE_INTERFACE_DATA=^SP_DEVICE_INTERFACE_DATA; SP_DEVICE_INTERFACE_DETAIL_DATA= packed record cbSize:DWORD; DevicePath: array of PAnsiChar end; PSP_DEVICE_INTERFACE_DETAIL_DATA=^SP_DEVICE_INTERFACE_DETAIL_DATA; //============================================================================== //подключаем библиотеки из setupapi.dll function SetupDiGetClassDevsA( ClassGuid: PGUID; Enumerator: PBYTE; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external 'SetupApi.dll'; function SetupDiEnumDeviceInfo( DeviceInfoSet: HDEVINFO; MemberIndex: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): boolean; stdcall; external 'SetupApi.dll'; function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): boolean; stdcall; external 'SetupApi.dll'; function SetupDiGetDeviceRegistryPropertyA( DeviceInfoSet: HDEVINFO; DeviceInfoData: PSP_DEVINFO_DATA; Property_: DWORD; PropertyRegDataType: PDWORD; PropertyBuffer: PBYTE; PropertyBufferSize: DWORD; RequiredSize: PDWORD): BOOL; stdcall; external 'SetupApi.dll'; function SetupDiGetDeviceInterfaceDetailA( DeviceInfoSet:HDEVINFO; DeviceInterfaceData:PSP_DEVICE_INTERFACE_DATA; DeviceInterfaceDetailData:PSP_DEVICE_INTERFACE_DETAIL_DATA; DeviceInterfaceDetailDataSize:DWORD; RequiredSize:PDWORD; DeviceInfoData :PSP_DEVINFO_DATA): boolean; stdcall; external 'SetupApi.dll'; function SetupDiEnumDeviceInterfaces( DeviceInfoSet: HDEVINFO; DeviceInfoData:PSP_DEVINFO_DATA; InterfaceClassGuid:PGUID; MemberIndex:DWORD; DeviceInterfaceData:PSP_DEVICE_INTERFACE_DATA ):BOOL; stdcall; external 'SetupApi.dll'; function SetupDiGetDeviceInstanceIdA( DeviceInfoSet: HDEVINFO; DeviceInfoData:PSP_DEVINFO_DATA; DeviceInstanceId:PBYTE; DeviceInstanceIdSize:DWORD; RequiredSize:PDWORD ):BOOL; stdcall; external 'SetupApi.dll'; //========================================================================= procedure TForm1.Button1Click(Sender: TObject); var hDevInfoSet: HDEVINFO; i: integer; DevDeviceInterfaceData : SP_DEVICE_INTERFACE_DATA; begin hDevInfoSet:=SetupDiGetClassDevsA(@GUID_DEVCLASS,nil, 0, (DIGCF_PRESENT or DIGCF_DEVICEINTERFACE)); if (hDevInfoSet <> INVALID_HANDLE_VALUE) then begin DevDeviceInterfaceData.cbSize:=0; DevDeviceInterfaceData.Flags:=0; DevDeviceInterfaceData.Reserved:=0; DevDeviceInterfaceData.InterfaceClassGuid.D1:=0; DevDeviceInterfaceData.InterfaceClassGuid.D2:=0; DevDeviceInterfaceData.InterfaceClassGuid.D3:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[0]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[1]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[2]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[3]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[4]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[5]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[6]:=0; DevDeviceInterfaceData.InterfaceClassGuid.D4[7]:=0; DevDeviceInterfaceData.cbSize := sizeof(SP_DEVICE_INTERFACE_DATA); i:=0; while (SetupDiEnumDeviceInterfaces(hDevInfoSet,0,@GUID_DEVCLASS,i,@DevDeviceInterfaceData)) do begin Memo1.Lines.Add('est'); Inc(i); end; SetupDiDestroyDeviceInfoList(hDevInfoSet); end; end; end. На форме тупо одно мемо и одна кнопка, при нажатии на которую должен быть по идее перебор, сколько устройств с интерфейсом в системе с класом усб. Но функция SetupDiEnumDeviceInterfaces опять таки возвращает ноль. Можно также прочитать последнюю ошибку, будет сообщение, что нет с доступным интерфейсом. Рыская по инету, наткнулся всего на ОДИН пост, где сообщалось, что GUID устройства и интерфейса - разные понятия. Но в системе этих интерфейсов зарегина куча, может есть способ узнать какой нужно подставить? Хотя во всех примерах и там и там один GUID используется. Заглянул в инф файл драйвера там есть строки Class=USB ClassGuid={36FC9E60-C465-11CF-8056-444553540000} Да и в системе определяется в ветке усб устройств. Где ошибка тогда? Ведь не может же быть, что в системе вобще ни одного устройства с интерфесом? о_О Самое интересное, что если делать разбор функциями SetupDiEnumDeviceInfo и SetupDiGetDeviceRegistryPropertyA я могу получать данные HardwareID имя устройства вида "Device", еще такого вида "\Device\000011" Вобщем эти то функции работают :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexkok 0 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба Да и в системе определяется в ветке усб устройств. Где ошибка тогда? Ведь не может же быть, что в системе вобще ни одного устройства с интерфесом? о_О Где ошибка, ищите сами, но такой код работает: function FindDevices(guid: TGUID): integer; var i,j: integer; DevAttr: TDevAttr; Error,n: cardinal; parent: HWND; DeviceInfoSet: hDevInfo; DeviceInfoData: TSPDevInfoData; DeviceInterfaceData: TSPDeviceInterfaceData; RequiredSize: cardinal; predictedLength: cardinal; pDeviceInterfaceDetailData: PSP_DEVICE_INTERFACE_DETAIL_DATA; begin DevList.Clear; DeviceInfoSet := SetupDiGetClassDevs(@guid, NIL, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE); Error := GetLastError; if (DeviceInfoSet <> pointer(INVALID_HANDLE_VALUE)) then begin for i := 0 to 126 do begin DeviceInterfaceData.cbSize := sizeof(DeviceInterfaceData); if SetupDiEnumDeviceInterfaces ( DeviceInfoSet, NIL, @guid, i, DeviceInterfaceData) then begin if GetLastError = ERROR_NO_MORE_ITEMS then break; DevAttr := TDevAttr.Create; DeviceInfoData.cbSize := sizeof(DeviceInfoData); SetupDiGetDeviceInterfaceDetail ( DeviceInfoSet, @DeviceInterfaceData, NIL, 0, RequiredSize, NIL); Error := GetLastError; predictedLength := RequiredSize; pDeviceInterfaceDetailData := AllocMem(predictedLength); pDeviceInterfaceDetailData^.cbSize := sizeof (TSPDeviceInterfaceDetailData); if SetupDiGetDeviceInterfaceDetail ( DeviceInfoSet, @DeviceInterfaceData, pDeviceInterfaceDetailData, predictedLength, RequiredSize, @DeviceInfoData) then begin Error := GetLastError; n := StrLen(pDeviceInterfaceDetailData^.DevicePath); SetLength(DevAttr.DevicePath,n+1); for j := 0 to n-1 do begin DevAttr.DevicePath[j+1] := pDeviceInterfaceDetailData^.DevicePath[j]; end; DevAttr.DevicePath[n+1] := #0; DevAttr.DevInst := DeviceInfoData.DevInst; //??????????? DevList.Add(DevAttr); end { else Error := GetLastError}; FreeMem(pDeviceInterfaceDetailData); //Error := GetLastError; end; end; end {else Error := GetLastError}; SetupDiDestroyDeviceInfoList(DeviceInfoSet); result := DevList.Count; end; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба //подключаем библиотеки из setupapi.dll function SetupDiGetClassDevsA( ClassGuid: PGUID; Enumerator: PBYTE; hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external 'SetupApi.dll'; Убрали бы вы от греха подальше подключения такого рода. Тем более, что у вас есть Delphi. Вставьте хидер #include <setupapi.h> в котором все эти функции определены и рабоотайте спокойно (буквы A заодно уберёте). По крайней мере будет полная уверенность, что параметры функций пересылаются правильно. И еще хотелось бы знать, на каком C-компиляторе вы работаете. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба Спасибо за код. Но что то у меня также он не выводит ни одного устройства. А какой GUID вы передаете этой функции? У меня остались подозрения, что либо я передаю не тот GUID, либо .... пока незнаю что еще ... Писал сначала в вижуал студии 2005, ибо просили на шарпе программу сделать. Но потом тихо переполз на делфи 7. Да и понять надо, почему же если работаю напрямую с библиотекой, не работает эта функция :laughing: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timofey_219 0 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба hDevInfoSet:=SetupDiGetClassDevsA(@GUID_DEVCLASS,@DevInfoData, 0, (DIGCF_ALLCLASSES or DIGCF_DEVICEINTERFACE)); При таких флагах, функция возвращает INVALID_HANDLE_VALUE Я так понимаю что тут должны быть просто указаны все классы поддерживающие интерфейсы (не взирая какой укащан в первом параметре)? Получается у меня в системе нет ни одного? о_О Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexkok 0 26 июля, 2009 Опубликовано 26 июля, 2009 · Жалоба Но что то у меня также он не выводит ни одного устройства. А какой GUID вы передаете этой функции? //guid for FX2LP w/o EEPROM 04b4 8613 CYUSBDRV_GUID: TGUID = '{AE18AA60-7F6A-11D4-97DD-00010229B959}'; У меня остались подозрения, что либо я передаю не тот GUID, либо .... пока незнаю что еще ... У меня тоже были проблемы, но уже не помню конкретно. Вызовы апишных функций я переопределил. function SetupDiGetClassDevs( ClassGuid: PGUID; Enumerator: pchar; hwndParent: HWND; Flags: cardinal ): HDEVINFO; stdcall; external 'setupapi.dll' name 'SetupDiGetClassDevsA'; function SetupDiEnumDeviceInfo( DeviceInfoSet: HDEVINFO; MemberIndex: cardinal; var DeviceInfoData: TSPDevInfoData ): LongBool stdcall; external 'setupapi.dll' name 'SetupDiEnumDeviceInfo'; function SetupDiEnumDeviceInterfaces( DeviceInfoSet: HDEVINFO; PDeviceInfoData: PSP_DEVINFO_DATA; InterfaceClassGuid: PGUID; MemberIndex: cardinal; var DeviceInterfaceData: TSPDeviceInterfaceData ): LongBool stdcall; external 'setupapi.dll' name 'SetupDiEnumDeviceInterfaces'; function SetupDiGetDeviceInterfaceDetail( DeviceInfoSet: HDEVINFO; DeviceInterfaceData: PSP_DEVICE_INTERFACE_DATA; pDeviceInterfaceDetailData: PSP_DEVICE_INTERFACE_DETAIL_DATA; //OPTIONAL DeviceInterfaceDetailDataSize: cardinal; var RequiredSize: cardinal; //OPTIONAL pDeviceInfoData: PSP_DEVINFO_DATA //OPTIONAL ): LongBool stdcall; external 'setupapi.dll' name 'SetupDiGetDeviceInterfaceDetailA'; function SetupDiDestroyDeviceInfoList( DeviceInfoSet: HDEVINFO ): LongBool stdcall; external 'setupapi.dll' name 'SetupDiDestroyDeviceInfoList'; function DeviceIoControl( hDevice :cardinal; dwIoControlCode :cardinal; lpInBuffer :pointer; InBufferSize :cardinal; lpOutBuffer :pointer; OutBufferSize :cardinal; //var BytesReturned :cardinal; lpBytesReturned :pointer; lpOverlapped :POverlapped ): LongBool stdcall; external kernel32 name 'DeviceIoControl'; function GetOverlappedResult( hDevice :cardinal; lpOverlapped :POverlapped; var NumberOfBytesTransferred :cardinal; bWait :LongBool ): LongBool stdcall; external kernel32 name 'GetOverlappedResult'; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
liebvit 0 4 мая, 2010 Опубликовано 4 мая, 2010 (изменено) · Жалоба > GUID_USBSRV_TYPE_DEVICE= (D1: $36FC9E60; D2: $C465; D3: $11CF; D4: ($80, $56, $44, $45, $53, $54, $00, $00)); > Проблема в том, что функция SetupDiEnumDeviceInterfaces всегда возвращает мне ошибку, что интерфейсов не найдено. Попробуй GUID_USBSRV_TYPE_DEVICE = "A5DCBF10-6530-11D2-901F-00C04FB951ED" Вот код который подсчитывает количество активных (DIGCF_PRESENT) интерфейсов (DIGCF_DEVICEINTERFACE): HDEVINFO hDevInfo; SP_DEVINFO_DATA DeviceInfoData; SP_DEVICE_INTERFACE_DATA DeviceInterfaceData; struct __declspec(uuid("A5DCBF10-6530-11D2-901F-00C04FB951ED")) uuidUsbDevClass { }; GUID GUID_USB = __uuidof(uuidUsbDevClass); DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); ZeroMemory(&DeviceInterfaceData, sizeof(SP_DEVICE_INTERFACE_DATA)); DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); DeviceInfoData.ClassGuid = __uuidof(uuidUsbDevClass); hDevInfo = SetupDiGetClassDevs(&DeviceInfoData.ClassGuid, 0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE ); if (hDevInfo == INVALID_HANDLE_VALUE) { // Insert error handling here. printf("Invalid handle\n"); return 1; } BOOL bRet = FALSE; DWORD dwIndex = 0; char szTraceBuf[256]; while(TRUE) { bRet = SetupDiEnumDeviceInterfaces( hDevInfo, NULL, &DeviceInfoData.ClassGuid, dwIndex, &DeviceInterfaceData ); if (!bRet) { sprintf(szTraceBuf, "SetupDiEnumDeviceInterfaces failed " \ "GetLastError() returns: 0x%x\n", GetLastError()); //OutputDebugString(szTraceBuf); printf("SetupDiEnumDeviceInterfaces failed " \ "GetLastError() returns: 0x%x\n", GetLastError()); if (GetLastError() == ERROR_NO_MORE_ITEMS) { break; } } dwIndex++; } больше можно найти здесь http://www.codeguru.com/forum/archive/inde...p/t-331907.html Изменено 11 мая, 2010 пользователем rezident Оформление цитаты исходника. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aag 0 11 мая, 2010 Опубликовано 11 мая, 2010 · Жалоба какую древнюю тему подняли)) уже почти год прошел Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alevnew 0 20 мая, 2010 Опубликовано 20 мая, 2010 · Жалоба какую древнюю тему подняли)) уже почти год прошел А раз уж подняли тему, мож кто знает, ка коткрыть устройство с драйвером CyUSB.sys в эксклюзивном режиме ? Получаю имя устройство и открываю через GUID, примерно как описано выше. Подробнее: http://electronix.ru/forum/index.php?showtopic=76441 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 45 20 мая, 2010 Опубликовано 20 мая, 2010 · Жалоба hDevInfo = SetupDiGetClassDevs(&DeviceInfoData.ClassGuid, 0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE ); А у меня, если так пишу (вместе с флагом DIGCF_DEVICEINTERFACE), то натуральные COM-порты находит, а виртуальные (порождаемые USB-устрйоством) не видит. Но как только флаг DIGCF_DEVICEINTERFACE убираешь (оставляя только один DIGCF_PRESENT), то находит виртульные COM-порты от USB-устройств, но не видит COM-портов натуральных. Такая вот странность... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться