Initial check in

This commit is contained in:
2026-01-03 18:53:14 +01:00
commit b9305ab8af
36 changed files with 6720 additions and 0 deletions
+258
View File
@@ -0,0 +1,258 @@
unit mr.drv.usb;
interface
uses
WinApi.Windows,
System.Classes,
spring.Collections,
spring.Collections.Lists,
mr.drv.usb.types,
mr.drv;
type
TUsbDriver = class;
TUsbDriverClass= class of TUsbDriver;
TScanCallback = reference to procedure( DevicePath: string);
TUsbDeviceInfo = class
private
fDriverClass : TUsbDriverClass;
fDevicePath : string;
fVendorID : word;
fProductID : word;
fLocation : string;
fDescription : string;
public
property DriverClass : TUsbDriverClass read fDriverClass;
property DevicePath : string read fDevicePath;
property Location : string read fLocation;
property Description : string read fDescription;
property VendorID : word read fVendorID;
property ProductID : word read fProductID;
public
constructor Create( DevicePath: string; DriverClass: TUsbDriverClass);
destructor Destroy; override;
end;
IUsbDriverMap = IDictionary<string, TUsbDeviceInfo>;
TAnsiStringList = TList<AnsiString>;
TList = spring.Collections.IList<string>;
TUsbDriver = class abstract(TDriver, IUsbDriver)
public
class procedure Scan( ScanCallback: TScanCallback); virtual; abstract;
public
class procedure ParseInstanceId( InstanceId : string;
var VendorID : word;
var ProductID : word;
var Location : string;
var Description : string);
protected
class var fDriverID: TGUID;
protected
fVendorID : word;
fProductID : word;
fLocation : string;
fDescription : string;
fDeviceSpeed : TusbDeviceSpeed;
fDeviceDescriptor : TUsbDeviceDescriptor;
public
function GetDescriptor( DescriptorType : byte;
Index : byte;
LanguageID : word;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal) : boolean; virtual; abstract;
function GetAssociatedInterface( InterfaceIndex : byte;
var InterfaceHandle) : boolean; virtual; abstract;
function QueryInterfaceSettings( AlternateSettingNumber : byte;
var AlternateSettingDescriptor : TUsbAlternateSettingDescriptor): boolean; virtual; abstract;
function QueryPipe( AlternateInterfaceNumber : byte;
PipeIndex : byte;
var PipeInformation : TusbPipeInformation): boolean; virtual; abstract;
function ControlTransfer( SetupPacket : TUsbSetupPacket;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean; virtual; abstract;
function AbortPipe( PipeID : byte): boolean; virtual; abstract;
function FlushPipe( PipeID : byte): boolean; virtual; abstract;
function ResetPipe( PipeID : byte): boolean; virtual; abstract;
function ReadPipe( PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean; virtual; abstract;
function WritePipe( PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean; virtual; abstract;
function GetOverlappedResult( Overlapped : POverlapped;
var Transferred : cardinal;
Wait : boolean): boolean; virtual; abstract;
public
constructor Create( DevicePath: string);
public
property VendorID : word read fVendorID;
property ProductID : word read fProductID;
property Location : string read fLocation;
property Description : string read fDescription;
property DeviceSpeed : TusbDeviceSpeed read fDeviceSpeed;
end;
// TUsbDriverClass = class of TUsbDriver;
implementation
uses
mr.dev.usb,
System.SysUtils;
{ TUsbDriver }
// @@@: Construction / destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Construction / destruction
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// Create
// ================================================================================================
constructor TUsbDriver.Create( DevicePath: string);
begin
fDeviceHandle := INVALID_HANDLE_VALUE;
fDevicePath := DevicePath;
fDeviceSpeed := LowSpeed;
ParseInstanceId( fDevicePath, fVendorID, fProductID, fLocation, fDescription);
end;
// @@@: INTERNALS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// INTERNALS
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// parse instance id
// ================================================================================================
class procedure TUsbDriver.ParseInstanceId( InstanceId : string;
var VendorID : word;
var ProductID : word;
var Location : string;
var Description : string);
var
i : integer;
l : integer;
id : string;
loc: string;
dsc: string;
begin
i := 1;
l := Length(InstanceId);
while (i<=l) and (InstanceId[i] <> '\') do
inc(i);
inc(i);
while (i<=l) and (InstanceId[i] <> '\') do
begin
id := id + InstanceId[i];
inc(i)
end;
inc(i);
while (i<=l) and (InstanceId[i] <> '#') do
begin
loc := loc + InstanceId[i];
inc(i)
end;
inc(i);
while (i<=l) do
begin
dsc := dsc + InstanceId[i];
inc(i)
end;
VendorId := StrToInt('$'+Copy( id, 5, 4));
ProductId := StrToInt('$'+Copy( id, 14, 4));
Location := loc;
Description := dsc;
end;
{ TUsbDeviceInfo }
// @@@: construction / destruction ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// construction / destruction
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ================================================================================================
// constructor
// ================================================================================================
constructor TUsbDeviceInfo.Create(DevicePath: string; DriverClass: TUsbDriverClass);
begin
fDevicePath := DevicePath;
fDriverClass := DriverClass;
DriverClass.ParseInstanceId( fDevicePath, fVendorID, fProductID, fLocation, fDescription)
end;
// ================================================================================================
// destructor
// ================================================================================================
destructor TUsbDeviceInfo.Destroy;
begin
inherited;
end;
end.
+210
View File
@@ -0,0 +1,210 @@
unit mr.drv.usb.types;
interface
uses
WinApi.Windows;
const
// Standard request codes (btw not used)
CTRL_GET_STATUS = 0;
CTRL_CLEAR_FEATURE = 1;
CTRL_SET_FEATURE = 3;
CTRL_SET_ADDRESS = 5;
CTRL_GET_DESCRIPTOR = 6;
CTRL_SET_DESCRIPTOR = 7;
CTRL_GET_CONFIGURATION = 8;
CTRL_SET_CONFIGURATION = 9;
CTRL_GET_INTERFACE = 10;
CTRL_SET_INTERFACE = 11;
// Descriptor types
DSCR_DEVICE = 1;
DSCR_CONFIGURATION = 2;
DSCR_STRING = 3;
DSCR_INTERFACE = 4;
DSCR_ENDPOINT = 5;
DSCR_DEVICE_QUALIFIER = 6;
DSCR_OTHER_SPEED_CONF = 7;
DSCR_INTERFACE_POWER = 8;
type
// -----------------------------------------------------------------------------------
// USB Device Descriptor
// -----------------------------------------------------------------------------------
PUsbDeviceDescriptor = ^TUsbDeviceDescriptor;
TUsbDeviceDescriptor = packed record
Length : byte; // UCHAR bLength
DescriptorType : byte; // UCHAR bDescriptorType
bcdUSB : word; // USHORT bcdUSB
DeviceClass : byte; // UCHAR bDeviceClass
DeviceSubClass : byte; // UCHAR bDeviceSubClass
DeviceProtocol : byte; // UCHAR bDeviceProtocol
MaxPacketSize0 : byte; // UCHAR bMaxOacketSize0
VendorID : word; // USHORT idVendor
ProductID : word; // USHORT idProduct
DeviceID : word; // USHORT bcdDevice
Manufacturer : byte; // UCHAR iManufacturer
Product : byte; // UCHAR iProduct
SerialNumber : byte; // UCHAR iSerialNumber
ConfigurationCount : byte; // UCHAR bNumConfigurations
end;
// -----------------------------------------------------------------------------------
// USB Configuration Descriptor
// -----------------------------------------------------------------------------------
PUsbConfigurationDescriptor = ^TUsbConfigurationDescriptor;
TUsbConfigurationDescriptor = packed record
Length : byte; // UCHAR bLength
DescriptorType : byte; // UCHAR bDescriptorType
TotalLength : word; // USHORT wTotalLength
InterfaceCount : byte; // UCHAR bNumInterfaces
ConfigurationNumber : byte; // UCHAR Configuration Number
ConfigurationString : byte; // UCHAR Configuration String
Attributes : byte; // UCHAR bmAttributes
MaxPower : byte; // UCHAR MaxPower
end;
// -----------------------------------------------------------------------------------
// USB Interface Descriptor
// -----------------------------------------------------------------------------------
PUsbAlternateSettingDescriptor = ^TUsbAlternateSettingDescriptor;
TUsbAlternateSettingDescriptor = packed record
Length : byte; // UCHAR bLength
DescriptorType : byte; // UCHAR bDescriptorType
InterfaceNumber : byte; // UCHAR bInterfaceNumber
AlternateSetting : byte; // UCHAR bAlternateSetting
EndpointCount : byte; // UCHAR bNumEndPoints
InterfaceClass : byte; // UCHAR bInterfaceClass
InterfaceSubClass : byte; // UCHAR bInterfaceSubClass
InterfaceProtocol : byte; // UCHAR bInterfaceProtocol
InterfaceIndex : byte; // UCHAR iInterface
end;
// -----------------------------------------------------------------------------------
// USB Endpoint Descriptor
// -----------------------------------------------------------------------------------
PUsbEndpointDescriptor = ^TUsbEndpointDescriptor;
TUsbEndpointDescriptor = packed record
Length : byte; // UCHAR bLength
DescriptorType : byte; // UCHAR bDescriptorType
EndpointAddress : byte; // UCHAR bEndpointAddress
Attributes : byte; // UCHAR bmAttributes
MaxPacketSize : word; // USHORT wMaxPacketSize
Interval : byte; // UCHAR bInterval
end;
// -----------------------------------------------------------------------------------
// USB String Descriptor
// -----------------------------------------------------------------------------------
PUsbStringDescriptor = ^TUsbStringDescriptor;
TUsbStringDescriptor = packed record
Length : byte; // UCHAR bLength
DescriptorType : byte; // UCHAR bDescriptorType
Str : array of WideChar; // WCHAR String[1]
end;
// -----------------------------------------------------------------------------------
// USB Transfer Size Info
// -----------------------------------------------------------------------------------
PusbTransferSizeInfo = ^TusbTransferSizeInfo;
TusbTransferSizeInfo = packed record
EndpointAddress : byte;
TransferSize : cardinal;
end;
{$Z4}
TUsbDeviceSpeed = (LowSpeed, FullSpeed, HighSpeed);
TUsbPipeType = (ptControl, ptIsochronous, ptBulk, ptInterrupt);
{$Z1}
// Ez nekem nem teljesen vilagos itt. usb.h ???
PUsbPipeInformation = ^TUsbPipeInformation;
TUsbPipeInformation = record
PipeType : TUsbPipeType;
PipeId : byte;
MaxPacketSize : word;
Interval : byte;
end;
PUsbSetupPacket = ^TUsbSetupPacket;
TUsbSetupPacket = packed record
RequestType : byte;
case Request : byte of
0: (
Value : word;
Index : word;
Length : word;
);
1: (
SetupDat : array [2..7] of byte;
);
end;
type
IUsbDriver = interface
['{786E9A46-F7FE-4A8C-8BB8-563AB8C51BD5}']
function GetDescriptor( DescriptorType : byte;
Index : byte;
LanguageID : word;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal) : boolean;
function GetAssociatedInterface( InterfaceIndex : byte;
var InterfaceHandle) : boolean;
function QueryInterfaceSettings( AlternateSettingNumber : byte;
var AlternateSettingDescriptor : TUsbAlternateSettingDescriptor): boolean;
function QueryPipe( AlternateInterfaceNumber : byte;
PipeIndex : byte;
var PipeInformation : TusbPipeInformation): boolean;
function ControlTransfer( SetupPacket : TUsbSetupPacket;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean;
function AbortPipe( PipeID : byte): boolean;
function FlushPipe( PipeID : byte): boolean;
function ResetPipe( PipeID : byte): boolean;
function ReadPipe( PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean;
function WritePipe( PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil): boolean;
function GetOverlappedResult( Overlapped : POverlapped;
var Transferred : cardinal;
Wait : boolean): boolean;
// function GetVendorID : word;
// function GetProductID : word;
// function GetLocation : string;
// function GetDescription : string;
// function GetDeviceSpeed : TDsbDeviceSpeed;
//
//
// property VendorID : word read GetVendorID;
// property ProductID : word read GetProductID;
// property Location : string read GetLocation;
// property Description : string read GetDescription;
// property DeviceSpeed : TusbDeviceSpeed read GetDeviceSpeed;
end;
implementation
end.
+650
View File
@@ -0,0 +1,650 @@
unit mr.drv.usb.winusb;
interface
uses
Windows,
mr.drv.usb.types,
mr.drv.usb;
type
TWinUsbInterfaceHandle = THandle;
TWinUsbDriver = class( TUsbDriver)
public
class procedure Scan( ScanCallback: TScanCallback); override;
protected
fWinUsbHandle : TWinUsbInterfaceHandle;
public
procedure Open; override;
procedure Close; override;
function GetDescriptor( DescriptorType : byte;
Index : byte;
LanguageID : word;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal) : boolean; override;
function GetAssociatedInterface
(
InterfaceIndex : byte;
var InterfaceHandle): boolean; override;
function QueryInterfaceSettings( AlternateSettingNumber : byte;
var AlternateSettingDescriptor : TUsbAlternateSettingDescriptor): boolean; override;
function QueryPipe
(
AlternateInterfaceNumber : byte;
PipeIndex : byte;
var PipeInformation : TusbPipeInformation
): boolean; override;
function ControlTransfer
(
SetupPacket : TUsbSetupPacket;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil
): boolean; override;
function AbortPipe( PipeID : byte): boolean; override;
function FlushPipe( PipeID : byte): boolean; override;
function ResetPipe( PipeID : byte): boolean; override;
function ReadPipe
(
PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil
): boolean; override;
function WritePipe
(
PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped = nil
): boolean; override;
function GetOverlappedResult
(
Overlapped : POverlapped;
var Transferred : cardinal;
Wait : boolean
): boolean; override;
public
procedure AfterConstruction; override;
procedure BeforeDestruction; override;
end;
implementation
uses
System.SysUtils,
System.StrUtils,
System.Win.ComObj,
WinApi.ActiveX,
WinApi.PropSys,
WinApi.FunctionDiscovery,
mr.dev.manager;
type
TWinUsb_Initialze =
function( DeviceHandle : THandle;
var WinUsbHandle : TWinUsbInterfaceHandle) : BOOL cdecl stdcall;
TWinUsb_Free =
function( WinUsbHandle : TWinUsbInterfaceHandle) : BOOL cdecl stdcall;
TWinUsb_QueryDeviceInformation =
function( WinUsbHandle : TWinUsbInterfaceHandle;
InformationType : cardinal;
var BufferLength : cardinal;
var Buffer) : bool cdecl stdcall;
TWinUsb_GetDescriptor =
function( InterfaceHandle : TWinUsbInterfaceHandle;
DescriptorType : byte;
Index : byte;
LanguageID : word;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal) : bool cdecl stdcall;
TWinUsb_GetAssociatedInterface =
function( WinUsbHandle : TWinUsbInterfaceHandle;
InterfaceIndex : byte;
var InterfaceHandle : TWinUsbInterfaceHandle): bool cdecl stdcall;
TWinUsb_QueryInterfaceSettings =
function( InterfaceHandle : TWinUsbInterfaceHandle;
AlternateSettingNumber : byte;
var AlternateSettingDescriptor : TUsbAlternateSettingDescriptor): bool cdecl stdcall;
TWinUsb_QueryPipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
AlternateInterfaceNumber : byte;
PipeIndex : byte;
var PipeInformation : TusbPipeInformation): bool; cdecl stdcall;
TWinUsb_GetCurrentAlternateSetting =
function( InterfaceHandle : TWinUsbInterfaceHandle;
var SettingNumber : byte): bool cdecl stdcall;
TWinUsb_SetCurrentAlternateSetting =
function( InterfaceHandle : TWinUsbInterfaceHandle;
SettingNumber : byte): bool cdecl stdcall;
TWinUsb_ControlTransfer =
function( InterfaceHandle : TWinUsbInterfaceHandle;
SetupPacket : TUsbSetupPacket;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): bool cdecl stdcall;
TWinUsb_ResetPipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
PipeId : byte): bool cdecl stdcall;
TWinUsb_AbortPipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
PipeId : byte): bool cdecl stdcall;
TWinUsb_FlushPipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
PipeId : byte): bool cdecl stdcall;
TWinUsb_ReadPipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): bool cdecl stdcall;
TWinUsb_WritePipe =
function( InterfaceHandle : TWinUsbInterfaceHandle;
PipeID : byte;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): bool cdecl stdcall;
TWinUsb_GetOverlappedResult =
function( InterfaceHandle : TWinUsbInterfaceHandle;
Overlapped : POverlapped;
var Transferred : cardinal;
Wait : bool): bool cdecl stdcall;
var
hWinUsb : HMODULE = 0;
WinUsb_Initialize : TWinUsb_Initialze = nil;
WinUsb_Free : TWinUsb_Free = nil;
WinUsb_QueryDeviceInformation : TWinUsb_QueryDeviceInformation = nil;
WinUsb_GetDescriptor : TWinUsb_GetDescriptor = nil;
WinUsb_GetAssociatedInterface : TWinUsb_GetAssociatedInterface = nil;
WinUsb_QueryInterfaceSettings : TWinUsb_QueryInterfaceSettings = nil;
WinUsb_GetCurrentAlternateSetting : TWinUsb_GetCurrentAlternateSetting = nil;
WinUsb_SetCurrentAlternateSetting : TWinUsb_SetCurrentAlternateSetting = nil;
WinUsb_ControlTransfer : TWinUsb_ControlTransfer = nil;
WinUsb_QueryPipe : TWinUsb_QueryPipe = nil;
WinUsb_ResetPipe : TWinUsb_ResetPipe = nil;
WinUsb_AbortPipe : TWinUsb_AbortPipe = nil;
WinUsb_FlushPipe : TWinUsb_FlushPipe = nil;
WinUsb_ReadPipe : TWinUsb_ReadPipe = nil;
WinUsb_WritePipe : TWinUsb_WritePipe = nil;
WinUsb_GetOverlappedResult : TWinUsb_GetOverlappedResult = nil;
{ TWinUsbDriver }
// ================================================================================================
// After Construction
// ================================================================================================
procedure TWinUsbDriver.AfterConstruction;
begin
inherited;
fWinUsbHandle := INVALID_HANDLE_VALUE;
fDeviceHandle := INVALID_HANDLE_VALUE;
end;
// ================================================================================================
// Before Destrruction
// ================================================================================================
procedure TWinUsbDriver.BeforeDestruction;
begin
Close;
inherited;
end;
// ================================================================================================
// Open
//
// Note:
// fDevicePath is in the form:
// 'USB\VID_04B4&PID_8613\6&26c545a4&0&1#Cypress FX2
//
// it must be converted into:
// \\?\USB#VID_04B4&PID_8613#6&26c545a4&0&1#{CDDE880F-898A-4DAB-B0EA-51FBA32C1D82}
// ================================================================================================
procedure TWinUsbDriver.Open;
var
path : WideString;
len : cardinal;
buf : byte;
i : integer;
begin
path := WideString(fDevicePath);
// ---------------------------------------------------------------
// Prepare device path
// ---------------------------------------------------------------
// strip device description
i := Pos('#', path);
if i > 0 then
path := Copy( path, 1, i-1);
path := ReplaceStr(path,'\','#');
path := '\\?\'+path+'#'+GuidToString(fDriverID);
// ---------------------------------------------------------------
// open
// ---------------------------------------------------------------
if fDeviceHandle = INVALID_HANDLE_VALUE then
begin
fWinUsbHandle := 0;
fDeviceHandle := CreateFile( PWideChar(path),
GENERIC_READ + GENERIC_WRITE,
FILE_SHARE_READ + FILE_SHARE_WRITE,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL or FILE_FLAG_OVERLAPPED,
0);
if fDeviceHandle <> INVALID_HANDLE_VALUE then
begin
// -------------------------------------------------------------------
// Initialize WinUSB
// -------------------------------------------------------------------
WinUsb_Initialize( fDeviceHandle, fWinUsbHandle);
// -------------------------------------------------------------------
// Determine bus speed
// -------------------------------------------------------------------
len := 1;
if WinUsb_QueryDeviceInformation( fWinUsbHandle, 1, len, buf) then
case buf of
1: fDeviceSpeed := LowSpeed;
2: fDeviceSpeed := FullSpeed;
3: fDeviceSpeed := HighSpeed;
end;
// -------------------------------------------------------------------
// Get device descriptor
// -------------------------------------------------------------------
WinUsb_GetDescriptor( fWinUsbHandle,
DSCR_DEVICE,
0, // index (not used)
0, // language id (not used)
@fDeviceDescriptor,
sizeof(TUsbDeviceDescriptor),
len);
end;
{
b :=
i := 0;
while WinUsb_QueryInterfaceSettings( fWinUsbHandle, i, sss) do
INC(i);
b := WinUsb_GetCurrentAlternateSetting( fWinUsbHandle, setting);
b := WinUsb_SetCurrentAlternateSetting( fWinUsbHandle, setting);
}
end
end;
// ================================================================================================
// Close
// ================================================================================================
procedure TWinUsbDriver.Close;
begin
if fWinUsbHandle <> INVALID_HANDLE_VALUE then
begin
WinUsb_Free( fWinUsbHandle);
fWinUsbHandle := INVALID_HANDLE_VALUE;
end;
if fDeviceHandle <> INVALID_HANDLE_VALUE then
begin
CloseHandle( fDeviceHandle);
fDeviceHandle := INVALID_HANDLE_VALUE;
end
end;
// ================================================================================================
// Get Descriptor
// ================================================================================================
function TWinUsbDriver.GetDescriptor( DescriptorType : byte;
Index : byte;
LanguageID : word;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal) : boolean;
begin
result := false;
if Assigned( WinUsb_GetDescriptor) then
result := WinUsb_GetDescriptor( fWinUsbHandle,
DescriptorType,
Index,
LanguageID,
Buffer,
BufferLength,
Transferred);
end;
// ================================================================================================
// Get Associated Interface
// ================================================================================================
function TWinUsbDriver.GetAssociatedInterface( InterfaceIndex: byte;
var InterfaceHandle): boolean;
begin
result := false
end;
// ================================================================================================
// QueryInterfaceSettings
// ================================================================================================
function TWinUsbDriver.QueryInterfaceSettings( AlternateSettingNumber : byte;
var AlternateSettingDescriptor: TUsbAlternateSettingDescriptor): boolean;
begin
result := false;
if Assigned( WinUsb_QueryInterfaceSettings) then
result := WinUsb_QueryInterfaceSettings( fWinUsbHandle,
AlternateSettingNumber,
AlternateSettingDescriptor);
end;
// ================================================================================================
// Query Pipe
// ================================================================================================
function TWinUsbDriver.QueryPipe( AlternateInterfaceNumber: byte;
PipeIndex : byte;
var PipeInformation : TusbPipeInformation): boolean;
begin
result := false;
if Assigned( WinUsb_QueryPipe) then
result := WinUsb_QueryPipe( fWinUsbHandle,
AlternateInterfaceNumber,
PipeIndex,
PipeInformation);
end;
// ================================================================================================
// Abort Pipe
// ================================================================================================
function TWinUsbDriver.AbortPipe( PipeID: byte): boolean;
begin
if Assigned( WinUsb_AbortPipe)
then result := WinUsb_AbortPipe( fWinUsbHandle, PipeID)
else result := false
end;
// ================================================================================================
// Flush Pipe
// ================================================================================================
function TWinUsbDriver.FlushPipe( PipeID: byte): boolean;
begin
if Assigned( WinUsb_FlushPipe)
then result := WinUsb_FlushPipe( fWinUsbHandle, PipeID)
else result := false
end;
// ================================================================================================
// Reset Pipe
// ================================================================================================
function TWinUsbDriver.ResetPipe( PipeID: byte): boolean;
begin
if Assigned( WinUsb_ResetPipe)
then result := WinUsb_ResetPipe( fWinUsbHandle, PipeID)
else result := false
end;
// ================================================================================================
// Read Pipe
// ================================================================================================
function TWinUsbDriver.ReadPipe( PipeID : byte;
Buffer : pointer;
BufferLength: cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): boolean;
begin
result := false;
if Assigned( WinUsb_ReadPipe) then
result := WinUsb_ReadPipe( fWinUsbHandle,
PipeID,
Buffer,
BufferLength,
Transferred,
Overlapped)
end;
// ================================================================================================
// Write Pipe
// ================================================================================================
function TWinUsbDriver.WritePipe( PipeID : byte;
Buffer : pointer;
BufferLength: cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): boolean;
begin
result := false;
if Assigned( WinUsb_WritePipe) then
result := WinUsb_WritePipe( fWinUsbHandle,
PipeID,
Buffer,
BufferLength,
Transferred,
Overlapped)
end;
// ================================================================================================
// Control Transfer
// ================================================================================================
function TWinUsbDriver.ControlTransfer( SetupPacket : TUsbSetupPacket;
Buffer : pointer;
BufferLength : cardinal;
var Transferred : cardinal;
Overlapped : POverlapped): boolean;
begin
result := false;
if Assigned( WinUsb_ControlTransfer) then
result := WinUsb_ControlTransfer( fWinUsbHandle,
SetupPacket,
Buffer,
BufferLength,
Transferred,
Overlapped)
end;
// ================================================================================================
// Get Overlapped Result
// ================================================================================================
function TWinUsbDriver.GetOverlappedResult( Overlapped : POverlapped;
var Transferred : cardinal;
Wait : boolean): boolean;
begin
result := false;
if Assigned( WinUsb_GetOverlappedResult) then
result := WinUsb_GetOverlappedResult( fWinUsbHandle, Overlapped, Transferred, Wait)
end;
// ================================================================================================
// scan
// ================================================================================================
class procedure TWinUsbDriver.Scan( ScanCallback: TScanCallback);
var
dsc : IFunctionDiscovery;
fcts : IFunctionInstanceCollection;
fct : IFunctionInstance;
props : IPropertyStore;
propv : TPropVariant;
hr : HResult;
cat : PWChar;
cnt : DWORD;
i : integer;
s : string;
begin
dsc := CreateComObject( CLSID_FunctionDiscovery) as IFunctionDiscovery;
try
cat := FCTN_CATEGORY_PNP;
hr := dsc.GetInstanceCollection(cat, nil, true, fcts);
if Succeeded(hr) and Succeeded(fcts.GetCount(cnt)) then
for i := 0 to cnt -1 do
if Succeeded( fcts.Item(i,fct)) then
begin
fct.OpenPropertyStore( STGM_READ, props);
if Succeeded( props.GetValue(PKEY_Device_Service, propv)) then
begin
if 'WinUSB' = propv.pwszVal then
begin
props.GetValue( PKEY_Device_InstanceId, propv);
s := propv.pwszVal;
props.GetValue( PKEY_Device_DeviceDesc, propv);
s := s +'#'+ propv.pwszVal;
ScanCallback( s);
// if Map.ContainsKey( s) then
// Map.Remove( s);
//
// Map.Add( s, TUsbDeviceInfo.Create(s, self))
end
end
end
finally
end
end;
// @@@: Initialization / finalization +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//
// Initialization / finalization
//
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
var
x: pointer = nil;
initialization
CoInitialize(x);
hWinUsb := LoadLibrary('WinUsb.dll');
if hWinUsb <> 0 then
begin
@WinUsb_Initialize := GetProcAddress( hWinUsb, 'WinUsb_Initialize');
@WinUsb_Free := GetprocAddress( hWinUsb, 'WinUsb_Free');
@WinUsb_QueryDeviceInformation := GetProcAddress( hWinUsb, 'WinUsb_QueryDeviceInformation');
@WinUsb_GetDescriptor := GetProcAddress( hWinUsb, 'WinUsb_GetDescriptor');
@WinUsb_GetCurrentAlternateSetting := GetProcAddress( hWinUsb, 'WinUsb_GetCurrentAlternateSetting');
@WinUsb_SetCurrentAlternateSetting := GetProcAddress( hWinUsb, 'WinUsb_SetCurrentAlternateSetting');
@WinUsb_GetAssociatedInterface := GetProcAddress( hWinUsb, 'WinUsb_GetAssociatedInterface');
@WinUsb_QueryInterfaceSettings := GetProcAddress( hWinUsb, 'WinUsb_QueryInterfaceSettings');
@WinUsb_ControlTransfer := GetProcAddress( hWinUsb, 'WinUsb_ControlTransfer');
@WinUsb_QueryPipe := GetProcAddress( hWinUsb, 'WinUsb_QueryPipe');
@WinUsb_ResetPipe := GetProcAddress( hWinUsb, 'WinUsb_ResetPipe');
@WinUsb_AbortPipe := GetProcAddress( hWinUsb, 'WinUsb_AbortPipe');
@WinUsb_FlushPipe := GetProcAddress( hWinUsb, 'WinUsb_FlushPipe');
@WinUsb_ReadPipe := GetProcAddress( hWinUsb, 'WinUsb_ReadPipe');
@WinUsb_WritePipe := GetProcAddress( hWinUsb, 'WinUsb_WritePipe');
@WinUsb_GetOverlappedResult := GetProcAddress( hWinUsb, 'WinUsb_GetOverlappedResult');
// --------------------------------------------------------------------------------
// from driver 'inf' file
// [Dev_AddReg]
// HKR,,DeviceInterfaceGUIDs,0x10000,"{CDDE880F-898A-4DAB-B0EA-51FBA32C1D82}"
//
// This guid needed in 'CreateFile' function to open the device !!!
//
// The device path must look like this:
// \\?\USB#VID_04B4&PID_8613#6&26c545a4&0&1#Cypress-FX2
// --------------------------------------------------------------------------------
TWinUsbDriver.fDriverID := StringToGuid('{CDDE880F-898A-4DAB-B0EA-51FBA32C1D82}');
RegisterDriver( TWinUsbDriver);
end;
finalization
if hWinUsb <> 0 then
FreeLibrary( hWinUsb);
CoUninitialize;
end.