реклама на сайте
подробности

 
 
> Получить имя устройства USB
Timofey
сообщение Jul 25 2009, 19:06
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



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

Сообщение отредактировал Timofey - Jul 25 2009, 19:12
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Timofey
сообщение Jul 26 2009, 05:12
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 119
Регистрация: 3-07-06
Пользователь №: 18 528



Спасибо большое.
Я натыкался уже на такой пост.
Я тут переделал под делфи 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"
Вобщем эти то функции работают sad.gif
Go to the top of the page
 
+Quote Post
alexkok
сообщение Jul 26 2009, 06:53
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 609
Регистрация: 3-03-07
Из: San Jose
Пользователь №: 25 837



Цитата(Timofey @ Jul 26 2009, 08:12) *
Да и в системе определяется в ветке усб устройств. Где ошибка тогда? Ведь не может же быть, что в системе вобще ни одного устройства с интерфесом? о_О

Где ошибка, ищите сами, но такой код работает:
Код
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;


--------------------
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 16:57
Рейтинг@Mail.ru


Страница сгенерированна за 0.01421 секунд с 7
ELECTRONIX ©2004-2016