Перейти к содержанию
    

Получить имя устройства USB

Есть 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, но её нет в библиотеке винды :(

Изменено пользователем Timofey

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И еще, чем отличаются функции SetupDiGetClassDevsA от SetupDiGetClassDevsW? В мсдн вобще про них ничего не нашел, есть просто SetupDiGetClassDevs, но её нет в библиотеке винды :(

 

С буквой W идут функции, у которых стринговый аргумент widechar, т.е. такой, когда символ занимает два байта вместо одного. Только обычно комилятор сам решает, с буквой A ему выбирать функцию или с буквой W, а программист эти буквы не пишет, а только в опциях устанавливает то, с какого рода символами он работает.

 

А на счет вашего вопроса вот тут почитайте, может поможет:

http://borland.xportal.ru/forum/printview....f9c7e2ae9c64f9e

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое.

Я натыкался уже на такой пост.

Я тут переделал под делфи 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"

Вобщем эти то функции работают :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да и в системе определяется в ветке усб устройств. Где ошибка тогда? Ведь не может же быть, что в системе вобще ни одного устройства с интерфесом? о_О

Где ошибка, ищите сами, но такой код работает:

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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

//подключаем библиотеки из setupapi.dll

 

function SetupDiGetClassDevsA(

ClassGuid: PGUID;

Enumerator: PBYTE;

hwndParent: HWND;

Flags: DWORD): HDEVINFO; stdcall; external 'SetupApi.dll';

 

Убрали бы вы от греха подальше подключения такого рода. Тем более, что у вас есть Delphi.

Вставьте хидер

#include <setupapi.h>

в котором все эти функции определены и рабоотайте спокойно (буквы A заодно уберёте). По крайней мере будет полная уверенность, что параметры функций пересылаются правильно.

И еще хотелось бы знать, на каком C-компиляторе вы работаете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

 

Спасибо за код. Но что то у меня также он не выводит ни одного устройства. А какой GUID вы передаете этой функции?

У меня остались подозрения, что либо я передаю не тот GUID, либо .... пока незнаю что еще ...

 

 

Писал сначала в вижуал студии 2005, ибо просили на шарпе программу сделать. Но потом тихо переполз на делфи 7.

Да и понять надо, почему же если работаю напрямую с библиотекой, не работает эта функция :laughing:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

hDevInfoSet:=SetupDiGetClassDevsA(@GUID_DEVCLASS,@DevInfoData, 0, (DIGCF_ALLCLASSES or DIGCF_DEVICEINTERFACE));

При таких флагах, функция возвращает INVALID_HANDLE_VALUE

Я так понимаю что тут должны быть просто указаны все классы поддерживающие интерфейсы (не взирая какой укащан в первом параметре)?

Получается у меня в системе нет ни одного? о_О

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но что то у меня также он не выводит ни одного устройства. А какой 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';

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

> 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

Изменено пользователем rezident
Оформление цитаты исходника.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

какую древнюю тему подняли)) уже почти год прошел

А раз уж подняли тему, мож кто знает, ка коткрыть устройство с драйвером CyUSB.sys в эксклюзивном режиме ?

Получаю имя устройство и открываю через GUID, примерно как описано выше.

Подробнее: http://electronix.ru/forum/index.php?showtopic=76441

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

hDevInfo = SetupDiGetClassDevs(&DeviceInfoData.ClassGuid, 0,0,DIGCF_PRESENT|DIGCF_DEVICEINTERFACE );

А у меня, если так пишу (вместе с флагом DIGCF_DEVICEINTERFACE), то натуральные COM-порты находит, а виртуальные (порождаемые USB-устрйоством) не видит. Но как только флаг DIGCF_DEVICEINTERFACE убираешь (оставляя только один DIGCF_PRESENT), то находит виртульные COM-порты от USB-устройств, но не видит COM-портов натуральных.

Такая вот странность...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...