2012-04-14 279 views
0

我在Delphi 7中做了一个小程序来显示所有连接的HID设备的一些细节。我只使用了系统文件,如SetupAPIModuleloaderHID.pas。这工作完美。 当我使用相同的代码并在Delphi XE2或(2010)中进行编译时,它无法生成所需的输出。德尔福HID Delphi7和德尔福XE2

也许这与指针投射或某事有关,但我找不到根本原因。

任何人都可以帮忙。

这是我的代码:

unit Unit1; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, 
    Graphics, Controls, Forms, Dialogs, StdCtrls; 

type 
    TForm1 = class(TForm) 
    Button1: TButton; 
    Memo1: TMemo; 
    procedure Button1Click(Sender: TObject); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

Uses 
    SetUpAPI, HID; 

{$R *.dfm} 

Type 
    THIDUSBDeviceInfo = Record { contains interface level information of each device} 
    SymLink   : String; 
    BufferSize   : Word; 
    Handle    : THandle; 
    VID    : DWord; 
    PID    : DWord; 
    VersionNumber  : Word; 
    ManufacturerString : String; 
    ProductString  : String; 
    SerialNumberString : String; 
    end; 
    THIDDeviceList = Array of THIDUSBDeviceInfo; 

Const 
    HIDUSB_COUNTOFINTERRUPTBUFFERS = 64; // Count of buffers for interrupt data 


Procedure ScanForHIDdevices(Var DeviceList : THIDDeviceList; 
    TargetVID, TargetPID : DWord); 
Var 
    HID_GUIid  : TGUID; 
    spdid  : TSPDeviceInterfaceData; 
    pSpDidd  : PSPDEVICEINTERFACEDETAILDATAA; 
    spddd  : TSPDevInfoData; 
    HIDinfo  : HDEVINFO; 
    CurIdx  : Integer; 
    dwSize  : DWord; 
    SymbolicLink : String; 
    DevHandle : THandle; 
    HidAttrs  : THIDDAttributes; 
    FoundIdx  : Integer; 
    Info   : THIDUSBDeviceInfo; 

    Function GetHidDeviceInfo(Symlink : PChar) : THIDUSBDeviceInfo; 
    Var 
    pstr   : pWideChar; 
    preparsedData : PHIDPPreparsedData; 
    hidCaps  : THIDPCaps; 
    Begin 
    FillChar(Result, SizeOf(Result), 0); 
    Result.SymLink := SymLink+ #0; 
    GetMem(pstr, 512); 
    DevHandle := CreateFile(Symlink, 
          GENERIC_READ or GENERIC_WRITE, 
          FILE_SHARE_READ or FILE_SHARE_WRITE, 
          nil, 
          OPEN_EXISTING, 
          0, 
          0); 
    If DevHandle <> INVALID_HANDLE_VALUE then 
    begin 
     If HidD_GetAttributes(DevHandle, 
          HidAttrs) then 
     begin 
     result.VID   := HidAttrs.VendorID; 
     result.PID   := HidAttrs.ProductID; 
     result.VersionNumber := HidAttrs.VersionNumber; 
     end; 

     If HidD_GetManufacturerString(DevHandle, pstr, 512) then 
     Result.ManufacturerString := pStr; 

     If HidD_GetProductString(DevHandle, pstr, 512) then 
     Result.ProductString := pStr; 

     If HidD_GetSerialNumberString(DevHandle, pstr, 512) then 
     Result.SerialNumberString := pStr; 

     { Set Input buffer size } 
     HidD_SetNumInputBuffers(DevHandle, 
           HIDUSB_COUNTOFINTERRUPTBUFFERS); 

     { Get capabilities } 
     HidD_GetPreparsedData(DevHandle, preparsedData); 
     if (preparsedData) then 
     begin 
     HidP_GetCaps(preparsedData, hidCaps); 
     Result.BufferSize := hidCaps.OutputReportByteLength; 
     end 
     else 
     Result.BufferSize := 11; 

     closeHandle(DevHandle); 
    end; 
    FreeMem(pStr); 
    End; 

Begin 
    FoundIdx := 0; 
    DeviceList := Nil; 
    { Get GUID of hid class } 
    HidD_GetHidGuid(HID_GUIid); 
    { Get a list of devices belonging to HID class } 
    HIDinfo := SetupDiGetClassDevs(@HID_GUIid, 
            nil, 
            GetDesktopWindow(), 
            DIGCF_DEVICEINTERFACE or DIGCF_PRESENT); 
    { Go through list of devices } 
    If thandle(HIDinfo) <> INVALID_HANDLE_VALUE then 
    begin 
    CurIdx := 0; 
    spdid.cbSize := SizeOf(spdid); 
    While SetupDiEnumDeviceInterfaces(HIDinfo, 
             nil, 
             HID_GUIid, 
             curIdx, 
             spdid) do 
    begin 
     dwSize := 0; 
     { Get device path for Createfile calls } 
     SetupDiGetDeviceInterfaceDetail(HIDinfo, 
             @spdid, 
             nil, 
             dwSize, 
             @dwSize, 
             nil); 
     If dwSize > 0 then 
     begin 
     GetMem(pSpDidd, dwSize); 
     pSpDidd^.cbSize := SizeOf(TSPDEVICEINTERFACEDETAILDATAA); 
     spddd.cbSize := SizeOf(spddd); 
     If SetupDiGetDeviceInterfaceDetail(HIDinfo, 
              @spdid, 
              pSpDidd, 
              dwSize, 
              @dwSize, 
              @spddd) then 
     begin 
      SymbolicLink := PChar(@(pSpDidd^.DevicePath)); 

      { Get information about the device (Vendor and 
      Product IDs, Strings, ...) } 
      FillChar(info, SizeOf(Info), 0); 
      Info  := GetHidDeviceInfo(@(pSpDidd^.DevicePath)); 
      Info.Handle := INVALID_HANDLE_VALUE; 

      { check if VID/PID match targets } 
      If (Info.VID = TargetVID) AND 
      (Info.PID = TargetPID) then 
      begin 
      { Add Devices to result list } 
      SetLength(DeviceList, FoundIdx + 1); 
      DeviceList[foundIdx] := Info; 
      Inc(FoundIdx); 
      end 
      else // list all HID devices if no target is specified 
      If (TargetVID = 0) AND (TargetPID = 0) then 
      begin 
       { Add Devices to result list } 
       SetLength(DeviceList, FoundIdx + 1); 
       DeviceList[FoundIdx] := Info; 

       Inc(FoundIdx); 
      end; 
     end; 

     FreeMem(pSpDidd); 
     end; 
     inc(CurIdx); 
    end; 
    SetupDiDestroyDeviceInfoList(HIDinfo); 
    end; 
End; 

procedure TForm1.Button1Click(Sender: TObject); 
Var 
    DeviceList : THIDDeviceList; 
    I   : Integer; 
begin 
    ScanForHIDdevices(DeviceList, 0, 0); 
    Memo1.Lines.Clear; 
    Memo1.Lines.Add(IntToStr(Length(DeviceList)) + ' device(s) found'); 
    If Length(DeviceList) > 0 then 
    For I := 0 to Length(DeviceList)-1 do 
     With DeviceList[I] do 
     begin 
     Memo1.Lines.Add('Device Number : ' + IntToStr(I)); 
     Memo1.Lines.Add('Symbolic link : ' + SymLink); 
     Memo1.Lines.Add('Handle  : 0x' + IntToHex(Handle, 1)); 
     Memo1.Lines.Add('Buffer size : ' + IntToStr(BufferSize)); 
     Memo1.Lines.Add('VID   : 0x' + IntToHex(VID, 4)); 
     Memo1.Lines.Add('PID   : 0x' + IntToHex(PID, 4)); 
     Memo1.Lines.Add('Version  : ' + IntToStr(VersionNumber)); 
     Memo1.Lines.Add('Manufacturer : ' + ManufacturerString); 
     Memo1.Lines.Add('Product name : ' + ProductString); 
     Memo1.Lines.Add('Serial number : ' + SerialNumberString); 
     Memo1.Lines.Add(' '); 
     end; 
    Memo1.SetFocus; 
end; 
+6

欢迎来到StackOverflow。我已经对代码进行了格式化,使其更具可读性(在编写问题时可以这样做,顺便说一句,您可以在输入文本的位置下方实时预览)。如果我们不知道“失败”是什么意思,那么您需要提供更多细节 - “无法产生期望的输出”意味着什么。我怀疑这个问题涉及到所有的字符串变量,因为Delphi 2009和更高版本在使用字符串变量时使用Unicode字符串,而以前的版本使用ANSI字符串。但是,没有关于问题的信息,我不能说。 :) – 2012-04-14 16:11:48

+0

如何使用'GetHidDeviceInfo'获取有关USB驱动器的信息?参数应该是什么样子?驱动器号? – 2013-11-06 14:53:08

回答

1

您必须在调用任何这些功能之前加载DLL模块:

LoadHid(); 
LoadSetupApi(); 

我想我们要卸载DLL时完成该程序。然后使用此代码:

UnloadHid; 
UnloadSetupApi