📄 usbio.pas
字号:
unit USBIO;
interface
uses Windows, usbio_i, usbspec, usbio_i_delphi;
{************************************************************************
*
* Module: UsbIo.h and UsbIo.cpp
* Long name: CUsbIo class
* Description: CUsbIo base device class definition
*
* Runtime Env.: Win32, Part of UsbioLib
* Author(s): Guenter Hildebrandt, Udo Eberhardt, Thomas Fr鰄lich
* Company: Thesycon GmbH, Ilmenau
************************************************************************}
const
USBIO_DEVICE_NAME = 'USBIO_Device';
type
TUsbIo = class
protected
FileHandle : THandle;
Overlapped : TOVERLAPPED;
CritSect : TRTLCriticalSection;
CheckedBuildDetected : Boolean;
DemoVersionDetected : Boolean;
mDevDetail : PSP_DEVICE_INTERFACE_DETAIL_DATA_A;
public
constructor Create; //is CUsbIo() in c++
destructor Destroy; override; //is ~CUsbIo() in c++
function CreateDeviceList(InterfaceGuid:PGUID): HDEVINFO;
procedure DestroyDeviceList(DeviceList: HDEVINFO);
function Open(
DeviceNumber : integer;
DeviceList : HDEVINFO=nil;
InterfaceGuid : PGUID=nil
): DWORD;
procedure Close;
function GetDevicePathName():PCHAR;
function GetDriverInfo(DriverInfo: PUSBIO_DRIVER_INFO): DWORD;
function GetDescriptor(
Buffer : Pointer;
var ByteCount : DWORD;
Recipient : USBIO_REQUEST_RECIPIENT;
DescriptorType : UCHAR;
DescriptorIndex : UCHAR = 0;
LanguageId : USHORT = 0
): DWORD;
function SetDescriptor(
Buffer : Pointer;
var ByteCount : LongInt;
Recipient : USBIO_REQUEST_RECIPIENT;
DescriptorType : UCHAR;
DescriptorIndex : UCHAR = 0;
LanguageId : USHORT = 0
): DWORD;
function SetFeature(
Recipient : USBIO_REQUEST_RECIPIENT;
FeatureSelector : USHORT;
Index : USHORT = 0
): DWORD;
function ClearFeature(
Recipient : USBIO_REQUEST_RECIPIENT;
FeatureSelector : USHORT;
Index : USHORT = 0
): DWORD;
function GetStatus(
var StatusValue : USHORT;
Recipient : USBIO_REQUEST_RECIPIENT;
Index : USHORT = 0
): DWORD;
function GetConfiguration(var ConfigurationValue: UCHAR): DWORD;
function GetInterface(
var AlternateSetting: UCHAR;
_Interface : USHORT = 0
): DWORD;
function StoreConfigurationDescriptor(Desc: PUSB_CONFIGURATION_DESCRIPTOR): DWORD;
function SetConfiguration(Conf: PUSBIO_SET_CONFIGURATION): DWORD;
function UnconfigureDevice: DWORD;
function SetInterface(Setting: PUSBIO_INTERFACE_SETTING): DWORD;
function ClassOrVendorInRequest(
Buffer : Pointer;
var ByteCount : DWORD;
Request : PUSBIO_CLASS_OR_VENDOR_REQUEST
): DWORD;
function ClassOrVendorOutRequest(
Buffer : Pointer;
var ByteCount : DWORD;
Request : PUSBIO_CLASS_OR_VENDOR_REQUEST
): DWORD;
function GetDeviceParameters(DevParam: PUSBIO_DEVICE_PARAMETERS): DWORD;
function SetDeviceParameters(DevParam: PUSBIO_DEVICE_PARAMETERS): DWORD;
function GetConfigurationInfo(Info: PUSBIO_CONFIGURATION_INFO): DWORD;
function ResetDevice: DWORD;
function CyclePort: DWORD;
function GetCurrentFrameNumber(var FrameNumber: DWORD): DWORD;
function GetDevicePowerState(var DevicePowerState: USBIO_DEVICE_POWER_STATE): DWORD;
function SetDevicePowerState( DevicePowerState: USBIO_DEVICE_POWER_STATE): DWORD;
function GetDeviceDescriptor(Desc: PUSB_DEVICE_DESCRIPTOR): DWORD;
function GetConfigurationDescriptor(
Desc : PUSB_CONFIGURATION_DESCRIPTOR;
var ByteCount : DWORD;
Index : UCHAR = 0
): DWORD;
function GetStringDescriptor(
Desc : PUSB_STRING_DESCRIPTOR;
var ByteCount : DWORD;
Index : UCHAR = 0
): DWORD;
function ErrorText(ErrorCode: DWORD): string;
function IoctlSync(
IoctlCode : DWORD;
InBuffer : Pointer;
InBufferSize : DWORD;
OutBuffer : Pointer;
OutBufferSize : DWORD;
BytesReturned : PDWORD
): DWORD;
function CancelIo: BOOL;
property IsCheckedBuild: boolean read CheckedBuildDetected;
property IsDemoVersion : boolean read DemoVersionDetected;
end;
implementation
uses Sysutils;
constructor TUsbIo.Create;
begin
inherited Create;
FileHandle:=0;
ZeroMemory(@Overlapped,sizeof(Overlapped));
InitializeCriticalSection(CritSect);
CheckedBuildDetected:=FALSE;
DemoVersionDetected:=FALSE;
mDevDetail:=nil;
end;
destructor TUsbIo.Destroy;
begin
Close;
DeleteCriticalSection(CritSect);
inherited Destroy;
end;
function TUsbIo.CreateDeviceList(InterfaceGuid:PGUID): HDEVINFO;
var
h : HDEVINFO;
begin
h:=SetupDiGetClassDevsA(InterfaceGuid, // LPGUID ClassGuid,
nil, // PCTSTR Enumerator,
0, // HWND hwndParent,
DIGCF_DEVICEINTERFACE or DIGCF_PRESENT // DWORD Flags
);
if DWORD(h)=INVALID_HANDLE_VALUE then result:=nil
else result:=h;
end;
procedure TUsbIo.DestroyDeviceList(DeviceList: HDEVINFO);
begin
if DeviceList<>nil then
SetupDiDestroyDeviceInfoList(DeviceList);
end;
function TUsbIo.Open(DeviceNumber : integer;
DeviceList : HDEVINFO=nil;
InterfaceGuid : PGUID=nil): DWORD;
var
status : DWORD;
h : THandle;
name : string;
DevData : SP_DEVICE_INTERFACE_DATA;
succ : boolean;
RegLen : DWORD;
info : USBIO_DRIVER_INFO ;
begin
if FileHandle <> 0 then
begin
Result := USBIO_ERR_SUCCESS;
exit;
end;
if DeviceList = nil then
begin
Name := '\\.\'+USBIO_DEVICE_NAME+IntToStr(DeviceNumber);
end else
begin
if InterfaceGuid=nil then
begin
result:=USBIO_ERR_INVALID_FUNCTION_PARAM;
exit;
end;
if mDevDetail<>nil then
begin
dispose(mDevDetail);
mDevDetail:=nil;
end;
ZeroMemory(@DevData,sizeof(DevData));
DevData.cbSize := sizeof(SP_DEVICE_INTERFACE_DATA);
succ:=SetupDiEnumDeviceInterfaces(DeviceList, nil, InterfaceGuid, DeviceNumber, @DevData );
if not(succ) then
begin
Status:=GetLastError();
if Status=ERROR_NO_MORE_ITEMS then Status:=USBIO_ERR_NO_SUCH_DEVICE_INSTANCE;
result:=Status;
exit;
end;
SetupDiGetDeviceInterfaceDetailA(DeviceList,@DevData,nil,0,@RegLen,nil);
try
getmem(mDevDetail,reglen);
except
result:=USBIO_ERR_NO_MEMORY;
exit;
end;
ZeroMemory(mDevDetail,RegLen);
mDevDetail^.cbSize:=sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_A);
succ:=SetupDiGetDeviceInterfaceDetailA(DeviceList, @DevData, mDevDetail, RegLen, @RegLen, nil);
if not(succ) then
begin
result:=GetLastError();
exit;
end;
Name:=string(pchar(@mDevDetail^.DevicePath));
end; {else}
h:=CreateFile(PChar(Name),
GENERIC_READ or GENERIC_WRITE, // access mode
FILE_SHARE_WRITE or FILE_SHARE_READ, // share mode
nil, // security desc.
OPEN_EXISTING, // how to create
FILE_FLAG_OVERLAPPED, // file attributes
0); // template file
if h=INVALID_HANDLE_VALUE then
status:=USBIO_ERR_DEVICE_NOT_FOUND
else
begin
FileHandle:=h;
Overlapped.hEvent:=CreateEvent(nil, false, false, nil);
if Overlapped.hEvent=0 then
begin
status:=USBIO_ERR_NO_MEMORY;
Close;
end else
begin
status:=GetDriverInfo(@info);
if status <> USBIO_ERR_SUCCESS then
Close
else
begin
CheckedBuildDetected:=(info.Flags and USBIO_INFOFLAG_CHECKED_BUILD) <> 0;
DemoVersionDetected :=(info.Flags and USBIO_INFOFLAG_DEMO_VERSION) <> 0;
if info.APIVersion <> USBIO_API_VERSION then
begin
status:=USBIO_ERR_VERSION_MISMATCH;
Close;
end
else
status:=USBIO_ERR_SUCCESS;
end;
end;
end;
result:=status;
end;
procedure TUsbIo.Close;
begin
if FileHandle<>0 then
begin
Windows.CloseHandle(FileHandle);
FileHandle:=0;
end;
if Overlapped.hEvent <> 0 then
begin
Windows.CloseHandle(Overlapped.hEvent);
Overlapped.hEvent:=0;
end;
if mDevDetail<>nil then dispose(mDevDetail);
end;
function TUsbIo.GetDevicePathName():PCHAR;
begin
if mDevDetail<>nil then result:=@(mDevDetail^.DevicePath)
else result:=nil;
end;
function TUsbIo.GetDriverInfo(DriverInfo: PUSBIO_DRIVER_INFO): DWORD;
begin
Result:=IoctlSync(IOCTL_USBIO_GET_DRIVER_INFO,
nil,
0,
DriverInfo,
sizeof(USBIO_DRIVER_INFO),
nil);
end;
function TUsbIo.GetDescriptor(
Buffer : Pointer;
var ByteCount : DWORD;
Recipient : USBIO_REQUEST_RECIPIENT;
DescriptorType : UCHAR;
DescriptorIndex : UCHAR = 0;
LanguageId : USHORT = 0
): DWORD;
var
req : USBIO_DESCRIPTOR_REQUEST;
begin
ZeroMemory(@req,sizeof(req));
req.Recipient :=Recipient;
req.DescriptorType :=DescriptorType;
req.DescriptorIndex:=DescriptorIndex;
req.LanguageId :=LanguageId;
Result:=IoctlSync(IOCTL_USBIO_GET_DESCRIPTOR,
@req,
sizeof(req),
Buffer,
ByteCount,
@ByteCount);
end;
function TUsbIo.SetDescriptor(
Buffer : Pointer;
var ByteCount : LongInt;
Recipient : USBIO_REQUEST_RECIPIENT;
DescriptorType : UCHAR;
DescriptorIndex : UCHAR = 0;
LanguageId : USHORT = 0
): DWORD;
var
req : USBIO_DESCRIPTOR_REQUEST;
begin
ZeroMemory(@req,sizeof(req));
req.Recipient :=Recipient;
req.DescriptorType :=DescriptorType;
req.DescriptorIndex:=DescriptorIndex;
req.LanguageId :=LanguageId;
Result:=IoctlSync(IOCTL_USBIO_SET_DESCRIPTOR,
@req,
sizeof(req),
Buffer,
ByteCount,
@ByteCount);
end;
function TUsbIo.SetFeature(
Recipient : USBIO_REQUEST_RECIPIENT;
FeatureSelector : USHORT;
Index : USHORT = 0
): DWORD;
var
req : USBIO_FEATURE_REQUEST;
begin
ZeroMemory(@req,sizeof(req));
req.Recipient := Recipient;
req.FeatureSelector:= FeatureSelector;
req.Index := Index;
Result := IoctlSync(IOCTL_USBIO_SET_FEATURE,
@req,
sizeof(req),
nil,
0,
nil);
end;
function TUsbIo.ClearFeature(
Recipient : USBIO_REQUEST_RECIPIENT;
FeatureSelector : USHORT;
Index : USHORT = 0
): DWORD;
var
req : USBIO_FEATURE_REQUEST;
begin
ZeroMemory(@req,sizeof(req));
req.Recipient :=Recipient;
req.FeatureSelector:=FeatureSelector;
req.Index :=Index;
Result:=IoctlSync(IOCTL_USBIO_CLEAR_FEATURE,
@req,
sizeof(req),
nil,
0,
nil);
end;
function TUsbIo.GetStatus(
var StatusValue : USHORT;
Recipient : USBIO_REQUEST_RECIPIENT;
Index : USHORT = 0
): DWORD;
var
req : USBIO_STATUS_REQUEST;
data : USBIO_STATUS_REQUEST_DATA;
begin
ZeroMemory(@req, sizeof(req));
ZeroMemory(@data,sizeof(data));
req.Recipient:= Recipient;
req.Index := Index;
Result:=IoctlSync(IOCTL_USBIO_GET_STATUS,
@req,
sizeof(req),
@data,
sizeof(data),
nil);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -