mirror of
http://gitlab.expertsoft.com.ua/git/expertcad
synced 2026-01-12 00:45:40 +02:00
1064 lines
40 KiB
ObjectPascal
1064 lines
40 KiB
ObjectPascal
unit U_USB;
|
||
|
||
interface
|
||
|
||
uses
|
||
Windows, SysUtils, Variants, Classes, ShellApi, Forms, ioctl, FastStrings;
|
||
|
||
const
|
||
CR_SUCCESS = $00000000;
|
||
|
||
MAX_PATH = 260;
|
||
ANYSIZE_ARRAY = 1;
|
||
SetupApiModuleName = 'SetupApi.dll';
|
||
setupapi = 'SetupApi.dll';
|
||
DIGCF_PRESENT = $00000002;
|
||
DIGCF_DEVICEINTERFACE = $00000010;
|
||
GUID_CLASS_USBHUB:TGUID='{f18a0e88-c30c-11d0-8815-00a0c906bed8}';
|
||
GUID_CLASS_USB_DEVICE:TGUID='{A5DCBF10-6530-11D2-901F-00C04FB951ED}';
|
||
GUID_CLASS_USB_HOST_CONTROLLER:TGUID='{3ABF6F2D-71C4-462a-8A92-1E6861E6AF27}';
|
||
GUID_DEVINTERFACE_VOLUME:TGUID='{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}';
|
||
GUID_DEVINTERFACE_DISK:TGUID='{53f56307-b6bf-11d0-94f2-00a0c91efb8b}';
|
||
GUID_DEVCLASS_DISKDRIVE: TGUID = (D1: $4D36E967; D2: $E325; D3: $11CE; D4: ($BF, $C1, $08, $00, $2B, $E1, $03, $18));
|
||
SPDRP_DEVICEDESC = $00000000; // DeviceDesc (R/W)
|
||
{$EXTERNALSYM SPDRP_DEVICEDESC}
|
||
SPDRP_HARDWAREID = $00000001; // HardwareID (R/W)
|
||
{$EXTERNALSYM SPDRP_HARDWAREID}
|
||
SPDRP_COMPATIBLEIDS = $00000002; // CompatibleIDs (R/W)
|
||
{$EXTERNALSYM SPDRP_COMPATIBLEIDS}
|
||
SPDRP_UNUSED0 = $00000003; // unused
|
||
{$EXTERNALSYM SPDRP_UNUSED0}
|
||
SPDRP_SERVICE = $00000004; // Service (R/W)
|
||
{$EXTERNALSYM SPDRP_SERVICE}
|
||
SPDRP_UNUSED1 = $00000005; // unused
|
||
{$EXTERNALSYM SPDRP_UNUSED1}
|
||
SPDRP_UNUSED2 = $00000006; // unused
|
||
{$EXTERNALSYM SPDRP_UNUSED2}
|
||
SPDRP_CLASS = $00000007; // Class (R--tied to ClassGUID)
|
||
{$EXTERNALSYM SPDRP_CLASS}
|
||
SPDRP_CLASSGUID = $00000008; // ClassGUID (R/W)
|
||
{$EXTERNALSYM SPDRP_CLASSGUID}
|
||
SPDRP_DRIVER = $00000009; // Driver (R/W)
|
||
{$EXTERNALSYM SPDRP_DRIVER}
|
||
SPDRP_CONFIGFLAGS = $0000000A; // ConfigFlags (R/W)
|
||
{$EXTERNALSYM SPDRP_CONFIGFLAGS}
|
||
SPDRP_MFG = $0000000B; // Mfg (R/W)
|
||
{$EXTERNALSYM SPDRP_MFG}
|
||
SPDRP_FRIENDLYNAME = $0000000C; // FriendlyName (R/W)
|
||
{$EXTERNALSYM SPDRP_FRIENDLYNAME}
|
||
SPDRP_LOCATION_INFORMATION = $0000000D; // LocationInformation (R/W)
|
||
{$EXTERNALSYM SPDRP_LOCATION_INFORMATION}
|
||
SPDRP_PHYSICAL_DEVICE_OBJECT_NAME = $0000000E; // PhysicalDeviceObjectName (R)
|
||
{$EXTERNALSYM SPDRP_PHYSICAL_DEVICE_OBJECT_NAME}
|
||
SPDRP_CAPABILITIES = $0000000F; // Capabilities (R)
|
||
{$EXTERNALSYM SPDRP_CAPABILITIES}
|
||
SPDRP_UI_NUMBER = $00000010; // UiNumber (R)
|
||
{$EXTERNALSYM SPDRP_UI_NUMBER}
|
||
SPDRP_UPPERFILTERS = $00000011; // UpperFilters (R/W)
|
||
{$EXTERNALSYM SPDRP_UPPERFILTERS}
|
||
SPDRP_LOWERFILTERS = $00000012; // LowerFilters (R/W)
|
||
{$EXTERNALSYM SPDRP_LOWERFILTERS}
|
||
SPDRP_BUSTYPEGUID = $00000013; // BusTypeGUID (R)
|
||
{$EXTERNALSYM SPDRP_BUSTYPEGUID}
|
||
SPDRP_LEGACYBUSTYPE = $00000014; // LegacyBusType (R)
|
||
{$EXTERNALSYM SPDRP_LEGACYBUSTYPE}
|
||
SPDRP_BUSNUMBER = $00000015; // BusNumber (R)
|
||
{$EXTERNALSYM SPDRP_BUSNUMBER}
|
||
SPDRP_ENUMERATOR_NAME = $00000016; // Enumerator Name (R)
|
||
{$EXTERNALSYM SPDRP_ENUMERATOR_NAME}
|
||
SPDRP_SECURITY = $00000017; // Security (R/W, binary form)
|
||
{$EXTERNALSYM SPDRP_SECURITY}
|
||
SPDRP_SECURITY_SDS = $00000018; // Security (W, SDS form)
|
||
{$EXTERNALSYM SPDRP_SECURITY_SDS}
|
||
SPDRP_DEVTYPE = $00000019; // Device Type (R/W)
|
||
{$EXTERNALSYM SPDRP_DEVTYPE}
|
||
SPDRP_EXCLUSIVE = $0000001A; // Device is exclusive-access (R/W)
|
||
{$EXTERNALSYM SPDRP_EXCLUSIVE}
|
||
SPDRP_CHARACTERISTICS = $0000001B; // Device Characteristics (R/W)
|
||
{$EXTERNALSYM SPDRP_CHARACTERISTICS}
|
||
SPDRP_ADDRESS = $0000001C; // Device Address (R)
|
||
{$EXTERNALSYM SPDRP_ADDRESS}
|
||
{$IFDEF WINXP_UP}
|
||
SPDRP_UI_NUMBER_DESC_FORMAT = $0000001D; // UiNumberDescFormat (R/W)
|
||
{$EXTERNALSYM SPDRP_UI_NUMBER_DESC_FORMAT}
|
||
SPDRP_DEVICE_POWER_DATA = $0000001E; // Device Power Data (R)
|
||
{$EXTERNALSYM SPDRP_DEVICE_POWER_DATA}
|
||
SPDRP_REMOVAL_POLICY = $0000001F; // Removal Policy (R)
|
||
{$EXTERNALSYM SPDRP_REMOVAL_POLICY}
|
||
SPDRP_REMOVAL_POLICY_HW_DEFAULT = $00000020; // Hardware Removal Policy (R)
|
||
{$EXTERNALSYM SPDRP_REMOVAL_POLICY_HW_DEFAULT}
|
||
SPDRP_REMOVAL_POLICY_OVERRIDE = $00000021; // Removal Policy Override (RW)
|
||
{$EXTERNALSYM SPDRP_REMOVAL_POLICY_OVERRIDE}
|
||
SPDRP_INSTALL_STATE = $00000022; // Device Install State (R)
|
||
{$EXTERNALSYM SPDRP_INSTALL_STATE}
|
||
|
||
SPDRP_MAXIMUM_PROPERTY = $00000023; // Upper bound on ordinals
|
||
{$EXTERNALSYM SPDRP_MAXIMUM_PROPERTY}
|
||
{$ELSE}
|
||
SPDRP_UI_NUMBER_DESC_FORMAT = $0000001E; // UiNumberDescFormat (R/W)
|
||
{$EXTERNALSYM SPDRP_UI_NUMBER_DESC_FORMAT}
|
||
SPDRP_MAXIMUM_PROPERTY = $0000001F; // Upper bound on ordinals
|
||
{$EXTERNALSYM SPDRP_MAXIMUM_PROPERTY}
|
||
{$ENDIF WINXP_UP}
|
||
SPCRP_SECURITY = $00000017; // Security (R/W, binary form)
|
||
{$EXTERNALSYM SPCRP_SECURITY}
|
||
SPCRP_SECURITY_SDS = $00000018; // Security (W, SDS form)
|
||
{$EXTERNALSYM SPCRP_SECURITY_SDS}
|
||
SPCRP_DEVTYPE = $00000019; // Device Type (R/W)
|
||
{$EXTERNALSYM SPCRP_DEVTYPE}
|
||
SPCRP_EXCLUSIVE = $0000001A; // Device is exclusive-access (R/W)
|
||
{$EXTERNALSYM SPCRP_EXCLUSIVE}
|
||
SPCRP_CHARACTERISTICS = $0000001B; // Device Characteristics (R/W)
|
||
{$EXTERNALSYM SPCRP_CHARACTERISTICS}
|
||
SPCRP_MAXIMUM_PROPERTY = $0000001C; // Upper bound on ordinals
|
||
{$EXTERNALSYM SPCRP_MAXIMUM_PROPERTY}
|
||
|
||
type
|
||
HDEVINFON = THandle;
|
||
|
||
HDEVINFO = Pointer;
|
||
|
||
PSP_DEVINFO_DATA = ^SP_DEVINFO_DATA;
|
||
PSPDevInfoData = ^TSPDevInfoData;
|
||
SP_DEVINFO_DATA = packed record
|
||
cbSize: DWORD;
|
||
ClassGuid: TGUID;
|
||
DevInst: DWORD;
|
||
Reserved: DWORD;
|
||
end;
|
||
TSPDevInfoData = SP_DEVINFO_DATA;
|
||
|
||
PSTORAGE_DEVICE_NUMBER = ^STORAGE_DEVICE_NUMBER;
|
||
STORAGE_DEVICE_NUMBER = packed record
|
||
DeviceType: DWORD;
|
||
DeviceNumber: Longint;
|
||
PartitionNumber: Longint;
|
||
end;
|
||
TSTORAGE_DEVICE_NUMBER = STORAGE_DEVICE_NUMBER;
|
||
|
||
type
|
||
PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;
|
||
SP_DEVICE_INTERFACE_DATA = packed record
|
||
cbSize: DWORD;
|
||
InterfaceClassGuid: TGUID;
|
||
Flags: DWORD;
|
||
Reserved: DWORD;
|
||
end;
|
||
TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;
|
||
|
||
type
|
||
PSPDeviceInterfaceDetailData = ^TSPDeviceInterfaceDetailData;
|
||
SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record
|
||
cbSize: DWORD;
|
||
DevicePath: array [0..ANYSIZE_ARRAY - 1] of AnsiChar;
|
||
end;
|
||
TSPDeviceInterfaceDetailData = SP_DEVICE_INTERFACE_DETAIL_DATA_A;
|
||
|
||
TUSBDev = class(TObject)
|
||
private
|
||
public
|
||
FDeviceID: DWORD;
|
||
FDevicePath: Ansistring;
|
||
FCapabilities: DWORD;
|
||
FClassDescr: Ansistring;
|
||
FClassGUID: Ansistring;
|
||
FCompatibleIDs: TStringList;
|
||
FConfigFlags: DWORD;
|
||
FDeviceDescr: Ansistring;
|
||
FDriver: Ansistring;
|
||
FFriendlyName: Ansistring;
|
||
FHardwareID: TStringList;
|
||
FLowerFilters: TStringList;
|
||
FMfg: Ansistring;
|
||
FUpperFilters: TStringList;
|
||
FAddress: Ansistring;
|
||
FBusNumber: DWORD;
|
||
FBusType: Ansistring;
|
||
FCharacteristics: Ansistring;
|
||
FDevType: DWORD;
|
||
FEnumeratorName: Ansistring;
|
||
FExclusive: DWORD;
|
||
FLegacyBusType: DWORD;
|
||
FLocationInfo: Ansistring;
|
||
FPhysDevObjName: Ansistring;
|
||
FSecuritySDS: Ansistring;
|
||
FService: Ansistring;
|
||
FUINumber: DWORD;
|
||
FUINumberFormat: Ansistring;
|
||
FDevData: TSPDevInfoData;
|
||
FPnPHandle: HDEVINFO;
|
||
constructor Create;
|
||
procedure GetInfoForDev(APnPHandle: HDEVINFO; ADevData: TSPDevInfoData; ADevicePath: PAnsiChar);
|
||
function GetRegistryPropertyDWord(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): DWORD;
|
||
function GetRegistryPropertyString(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): Ansistring;
|
||
function GetRegistryPropertyStringList(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): TStringList;
|
||
end;
|
||
|
||
function GetTempDir: Ansistring;
|
||
function GetDevNum(aPath: Ansistring): LongInt;
|
||
function USBDeviceFind(GUID:TGUID; aPhysDevObjName: Ansistring): TUSBDev;
|
||
//function GetDEVID(aDevPath: string): string;
|
||
function GetDEVID(aDevPath: Ansistring): Ansistring;
|
||
|
||
//function GetDEVIDOther(aDevPath: string): string;
|
||
function GetDEVIDOther(aDevPath: AnsiString): AnsiString;
|
||
|
||
//function GetDEVIDOtherSCSI(aDevPath: string): string;
|
||
function GetDEVIDOtherSCSI(aDevPath: AnsiString): AnsiString;
|
||
|
||
//function IsRemoveable(aDevPath: string): Boolean;
|
||
function IsRemoveable(aDevPath: Ansistring): Boolean;
|
||
|
||
function IsRemoveableUSBHard(aDevPath: Ansistring): Boolean;
|
||
//procedure EjectDrive(aDrive: string);
|
||
procedure EjectDrive(aDrive: Ansistring);
|
||
|
||
procedure SelfRemoteEject;
|
||
function EnumDiskDriveVista(aDevSerial: Ansistring): Ansistring;
|
||
function USBDeviceSerial(GUID:TGUID; aPhysDevNumber: LongInt): Ansistring;
|
||
|
||
function USBDeviceSerialSCSI(GUID:TGUID; aPhysDevNumber: LongInt): Ansistring;
|
||
|
||
var
|
||
G_PARENT_SCSI: Ansistring;
|
||
G_FHardwareID0: Ansistring;
|
||
|
||
implementation
|
||
|
||
function SetupDiGetDeviceRegistryProperty(DeviceInfoSet: HDEVINFO;
|
||
const DeviceInfoData: TSPDevInfoData; Property_: DWORD;
|
||
var PropertyRegDataType: DWORD; PropertyBuffer: PBYTE; PropertyBufferSize: DWORD;
|
||
var RequiredSize: DWORD): LongBool; stdcall; external SetupApiModuleName name 'SetupDiGetDeviceRegistryPropertyA';
|
||
|
||
function SetupDiGetClassDevs(ClassGuid: PGUID; const Enumerator: PAnsiChar;
|
||
hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external SetupApiModuleName name 'SetupDiGetClassDevsA';
|
||
|
||
function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO;
|
||
MemberIndex: DWORD; var DeviceInfoData: TSPDevInfoData): LongBool; stdcall; external SetupApiModuleName name 'SetupDiEnumDeviceInfo';
|
||
|
||
function SetupDiEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;
|
||
DeviceInfoData: PSPDevInfoData; const InterfaceClassGuid: TGUID;
|
||
MemberIndex: DWORD; var DeviceInterfaceData: TSPDeviceInterfaceData): LongBool; stdcall; external SetupApiModuleName name 'SetupDiEnumDeviceInterfaces';
|
||
|
||
function SetupDiGetDeviceInterfaceDetail(DeviceInfoSet: HDEVINFO;
|
||
DeviceInterfaceData: PSPDeviceInterfaceData;
|
||
DeviceInterfaceDetailData: PSPDeviceInterfaceDetailData;
|
||
DeviceInterfaceDetailDataSize: DWORD; var RequiredSize: DWORD;
|
||
Device: PSPDevInfoData): LongBool; stdcall; external SetupApiModuleName name 'SetupDiGetDeviceInterfaceDetailA';
|
||
|
||
//function GetVolumeNameForVolumeMountPoint(volumeName: string;
|
||
// uniqueVolumeName: PChar;
|
||
// uniqueNameBufferCapacity: integer): LongBool; stdcall; external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPointA';
|
||
|
||
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): LongBool; stdcall; external SetupApiModuleName name 'SetupDiDestroyDeviceInfoList';
|
||
|
||
function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCSTR;
|
||
lpszVolumeName: LPSTR; cchBufferLength: DWORD): BOOL; stdcall; external 'kernel32.dll' name 'GetVolumeNameForVolumeMountPointA';
|
||
|
||
function CM_Get_Parent(pdnDevInst: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
|
||
function CM_Get_Device_ID_Size(pulLen: PDWORD; dnDevInst: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
|
||
function CM_Get_Device_IDA(dnDevInst: DWORD; Buffer: PAnsiChar; BufferLen: DWORD; ulFlags: DWORD): DWORD; stdcall; external setupapi;
|
||
function CM_Locate_DevNodeA(pdnDevInst: PDWORD; pDeviceID: PAnsiChar; ulFlags: DWORD): DWORD; stdcall; external setupapi;
|
||
function CM_Request_Device_EjectA(dnDevInst: DWORD; pVetoType: Pointer; pszVetoName: PAnsiChar; ulNameLength: DWORD;
|
||
ulFlags: DWORD): DWORD; stdcall; external setupapi;
|
||
function CM_Query_And_Remove_SubTree(dnDevInst: DWORD; pVetoType: Pointer; pszVetoName: PAnsiChar; ulNameLength: DWORD;
|
||
ulFlags: DWORD): DWORD; stdcall; external setupapi name 'CM_Query_And_Remove_SubTreeA';
|
||
|
||
|
||
function SetupDiGetClassDevsA(ClassGuid: PGUID; Enumerator: PAnsiChar; hwndParent: HWND; Flags: DWORD): HDEVINFON; stdcall; external setupapi name 'SetupDiGetClassDevsA';
|
||
function SetupDiEnumDeviceInfoN(DeviceInfoSet: HDEVINFON; MemberIndex: DWORD; DeviceInfoData: PSP_DEVINFO_DATA): boolean; stdcall; external setupapi name 'SetupDiEnumDeviceInfo';
|
||
function SetupDiDestroyDeviceInfoListN(DeviceInfoSet: HDEVINFON): boolean; stdcall; external setupapi name 'SetupDiDestroyDeviceInfoList';
|
||
|
||
|
||
function GetDeviceName(aDevInst: THandle): Ansistring;
|
||
var
|
||
IDLen: Integer;
|
||
begin
|
||
Result := '';
|
||
if (CM_Get_Device_ID_Size(@IDLen, aDevInst, 0) = CR_SUCCESS) and (IDLen > 0) then begin
|
||
SetLength(Result, IDLen);
|
||
if CM_Get_Device_IDA(aDevInst, PAnsiChar(Result), IDLen + 1, 0) <> CR_SUCCESS then
|
||
Result := ''
|
||
end
|
||
end;
|
||
|
||
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GetDEVIDOther(aDrive);
|
||
// <20><><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
function EnumDiskDriveVista(aDevSerial: Ansistring): Ansistring;
|
||
var
|
||
hDevInfoSet: HDEVINFON;
|
||
DevInfo: SP_DEVINFO_DATA;
|
||
i: Integer;
|
||
str1: Ansistring;
|
||
begin
|
||
result := '';
|
||
DevInfo.cbSize := sizeof(SP_DEVINFO_DATA);
|
||
hDevInfoSet := SetupDiGetClassDevsA(@GUID_DEVCLASS_DISKDRIVE, nil, 0, 2);
|
||
i := 0;
|
||
if hDevInfoSet <> INVALID_HANDLE_VALUE then
|
||
begin
|
||
while (SetupDiEnumDeviceInfoN(hDevInfoSet, i, @DevInfo)) do begin
|
||
str1 := GetDeviceName(DevInfo.DevInst);
|
||
if pos(aDevSerial, AnsiLowerCase(str1)) > 0 then
|
||
begin
|
||
result := AnsiLowerCase(str1);
|
||
break;
|
||
end;
|
||
Inc(i)
|
||
end;
|
||
SetupDiDestroyDeviceInfoListN(hDevInfoSet);
|
||
end
|
||
end;
|
||
|
||
|
||
{ TUSBDev }
|
||
|
||
constructor TUSBDev.Create;
|
||
begin
|
||
inherited;
|
||
end;
|
||
|
||
procedure TUSBDev.GetInfoForDev(APnPHandle: HDEVINFO; ADevData: TSPDevInfoData; ADevicePath: PAnsiChar);
|
||
begin
|
||
FDeviceID := ADevData.DevInst;
|
||
FDevicePath := ADevicePath;
|
||
|
||
FDevData := ADevData;
|
||
FPnPHandle := APnPHandle;
|
||
|
||
// primary information
|
||
FCapabilities := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_CAPABILITIES);
|
||
FClassDescr := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_CLASS);
|
||
FClassGUID := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_CLASSGUID);
|
||
FCompatibleIDs := GetRegistryPropertyStringList(APnPHandle, ADevData, SPDRP_COMPATIBLEIDS);
|
||
FConfigFlags := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_CONFIGFLAGS);
|
||
FDeviceDescr := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_DEVICEDESC);
|
||
FDriver := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_DRIVER);
|
||
FFriendlyName := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_FRIENDLYNAME);
|
||
FHardwareID := GetRegistryPropertyStringList(APnPHandle, ADevData, SPDRP_HARDWAREID);
|
||
FLowerFilters := GetRegistryPropertyStringList(APnPHandle, ADevData, SPDRP_LOWERFILTERS);
|
||
FMfg := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_MFG);
|
||
FUpperFilters := GetRegistryPropertyStringList(APnPHandle, ADevData, SPDRP_UPPERFILTERS);
|
||
FService := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_SERVICE);
|
||
|
||
// secondary information not all likely to exist for a HID device
|
||
FAddress := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_ADDRESS);
|
||
FBusNumber := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_BUSNUMBER);
|
||
FBusType := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_BUSTYPEGUID);
|
||
FCharacteristics := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_CHARACTERISTICS);
|
||
FDevType := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_DEVTYPE);
|
||
FEnumeratorName := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_ENUMERATOR_NAME);
|
||
FExclusive := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_EXCLUSIVE);
|
||
FLegacyBusType := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_LEGACYBUSTYPE);
|
||
FLocationInfo := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_LOCATION_INFORMATION);
|
||
FPhysDevObjName := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME);
|
||
FSecuritySDS := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_SECURITY_SDS);
|
||
FUINumber := GetRegistryPropertyDWord(APnPHandle, ADevData, SPDRP_UI_NUMBER);
|
||
FUINumberFormat := GetRegistryPropertyString(APnPHandle, ADevData, SPDRP_UI_NUMBER_DESC_FORMAT);
|
||
end;
|
||
|
||
function TUSBDev.GetRegistryPropertyDWord(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): DWORD;
|
||
var
|
||
BytesReturned: DWORD;
|
||
RegDataType: DWORD;
|
||
begin
|
||
BytesReturned := 0;
|
||
RegDataType := 0;
|
||
Result := 0;
|
||
SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
|
||
RegDataType, PBYTE(@Result), SizeOf(Result), BytesReturned);
|
||
end;
|
||
|
||
function TUSBDev.GetRegistryPropertyString(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): Ansistring;
|
||
var
|
||
BytesReturned: DWORD;
|
||
RegDataType: DWORD;
|
||
Buffer: array [0..1023] of AnsiChar;
|
||
begin
|
||
BytesReturned := 0;
|
||
RegDataType := 0;
|
||
Buffer[0] := #0;
|
||
SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
|
||
RegDataType, PByte(@Buffer[0]), SizeOf(Buffer), BytesReturned);
|
||
Result := Buffer;
|
||
end;
|
||
|
||
function TUSBDev.GetRegistryPropertyStringList(PnPHandle: HDEVINFO;
|
||
const DevData: TSPDevInfoData; Prop: DWORD): TStringList;
|
||
var
|
||
BytesReturned: DWORD;
|
||
RegDataType: DWORD;
|
||
Buffer: array [0..16383] of AnsiChar;
|
||
P: PAnsiChar;
|
||
begin
|
||
BytesReturned := 0;
|
||
RegDataType := 0;
|
||
Buffer[0] := #0;
|
||
SetupDiGetDeviceRegistryProperty(PnPHandle, DevData, Prop,
|
||
RegDataType, PBYTE(@Buffer[0]), SizeOf(Buffer), BytesReturned);
|
||
Result := TStringList.Create;
|
||
P := @Buffer[0];
|
||
while P[0] <> #0 do
|
||
begin
|
||
Result.Add(P);
|
||
P := P + StrLen(P) + 1;
|
||
end;
|
||
end;
|
||
|
||
function GetTempDir: Ansistring;
|
||
var
|
||
buff: pchar;
|
||
s: string;
|
||
begin
|
||
// Tolik 24/06/2019 --
|
||
s := '';
|
||
s := GetEnvironmentVariable('tmp');
|
||
if ((s = '') or (not DirectoryExists(s))) then
|
||
begin
|
||
s := GetEnvironmentVariable('temp');
|
||
if ((s = '') or (not DirectoryExists(s))) then
|
||
s := 'c:\';
|
||
end;
|
||
{
|
||
// Tolik 21/06/2019 - -
|
||
//getmem(buff, 1255);
|
||
getmem(buff, 1255*2);
|
||
//
|
||
s := '';
|
||
if (GetEnvironmentVariable('tmp', buff, 1254) > 0)
|
||
and (DirectoryExists(buff)) then
|
||
begin
|
||
s := buff;
|
||
end
|
||
else
|
||
if (GetEnvironmentVariable('temp',buff, 1254) >0)
|
||
and (DirectoryExists(buff)) then
|
||
begin
|
||
s := buff;
|
||
end
|
||
else
|
||
s := 'c:\';
|
||
freemem(buff, 1255);
|
||
}
|
||
//
|
||
result := s;
|
||
end;
|
||
|
||
function USBDeviceFind(GUID:TGUID; aPhysDevObjName: Ansistring): TUSBDev;
|
||
var
|
||
PnPHandle: HDEVINFO;
|
||
DevData: TSPDevInfoData;
|
||
DeviceInterfaceData: TSPDeviceInterfaceData;
|
||
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
|
||
Success: LongBool;
|
||
Devn: Integer;
|
||
BytesReturned: DWORD;
|
||
aUSBDev: TUSBDev;
|
||
|
||
begin
|
||
try
|
||
Result := nil;
|
||
|
||
PnPHandle:= SetupDiGetClassDevs(@Guid, nil, 0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
|
||
|
||
if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
try
|
||
Devn := 0;
|
||
repeat
|
||
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
|
||
Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, Guid, Devn, DeviceInterfaceData);
|
||
if Success then
|
||
begin
|
||
DevData.cbSize := SizeOf(SP_DEVINFO_DATA);
|
||
DeviceInterfaceData.cbSize := SizeOf(SP_DEVICE_INTERFACE_DATA);
|
||
BytesReturned := 0;
|
||
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
|
||
if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
|
||
begin
|
||
FunctionClassDeviceData := AllocMem(BytesReturned);
|
||
try
|
||
FunctionClassDeviceData.cbSize := 5;
|
||
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
|
||
begin
|
||
aUSBDev := TUSBDev.Create;
|
||
aUSBDev.GetInfoForDev(PnPHandle, DevData, @FunctionClassDeviceData.DevicePath);
|
||
if aPhysDevObjName = aUSBDev.FPhysDevObjName then
|
||
begin
|
||
result := aUSBDev;
|
||
break;
|
||
end
|
||
else
|
||
aUSBDev.Free;
|
||
end;
|
||
Inc(Devn);
|
||
finally
|
||
FreeMem(FunctionClassDeviceData);
|
||
end;
|
||
end;
|
||
end;
|
||
until not Success;
|
||
finally
|
||
if result = nil then
|
||
SetupDiDestroyDeviceInfoList(PnPHandle);
|
||
end;
|
||
finally
|
||
end;
|
||
end;
|
||
|
||
function USBDeviceEject(GUID:TGUID; aPhysDevNumber: LongInt): Boolean;
|
||
var
|
||
PnPHandle: HDEVINFO;
|
||
DevData: TSPDevInfoData;
|
||
DeviceInterfaceData: TSPDeviceInterfaceData;
|
||
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
|
||
Success: LongBool;
|
||
Devn: Integer;
|
||
BytesReturned: DWORD;
|
||
i: integer;
|
||
|
||
aUSBDev: TUSBDev;
|
||
Parent: DWORD;
|
||
VetoName: PAnsiChar;
|
||
begin
|
||
try
|
||
Result := False;
|
||
|
||
PnPHandle:= SetupDiGetClassDevs(@Guid, nil, 0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
|
||
|
||
if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
try
|
||
Devn := 0;
|
||
repeat
|
||
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
|
||
Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, Guid, Devn, DeviceInterfaceData);
|
||
if Success then
|
||
begin
|
||
DevData.cbSize := SizeOf(SP_DEVINFO_DATA);
|
||
DeviceInterfaceData.cbSize := SizeOf(SP_DEVICE_INTERFACE_DATA);
|
||
BytesReturned := 0;
|
||
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
|
||
if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
|
||
begin
|
||
FunctionClassDeviceData := AllocMem(BytesReturned);
|
||
try
|
||
FunctionClassDeviceData.cbSize := 5;
|
||
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
|
||
begin
|
||
aUSBDev := TUSBDev.Create;
|
||
aUSBDev.GetInfoForDev(PnPHandle, DevData, @FunctionClassDeviceData.DevicePath);
|
||
if aPhysDevNumber = GetDevNum(aUSBDev.FDevicePath) then
|
||
begin
|
||
if CM_Get_Parent(@Parent, aUSBDev.FDevData.DevInst, 0) = 0 then
|
||
begin
|
||
sleep(200);
|
||
// Tolik 21/06/2019 --
|
||
//VetoName := GetMemory(260);
|
||
VetoName := GetMemory(260*2);
|
||
//
|
||
// if (CM_Request_Device_EjectA(aUSBDev.FDevData.DevInst, nil, VetoName, 260, 0) <> 0) then
|
||
// if (CM_Query_And_Remove_SubTree(aUSBDev.FDevData.DevInst, nil, VetoName, 260, 0) <> 0) then
|
||
// if (CM_Query_And_Remove_SubTree(Parent, nil, VetoName, 260, 0) <> 0) then
|
||
if (CM_Request_Device_EjectA(Parent, nil, VetoName, 260, 0) <> 0) then
|
||
begin
|
||
if (CM_Locate_DevNodeA(@Parent, VetoName, 0) <> 0) then
|
||
begin
|
||
FreeMemory(VetoName);
|
||
exit;
|
||
end;
|
||
FreeMemory(VetoName);
|
||
if (CM_Request_Device_EjectA(Parent, nil, nil, 0, 0) <> 0) then
|
||
exit
|
||
else
|
||
result := True;
|
||
end
|
||
else
|
||
result := True;
|
||
FreeMemory(VetoName);
|
||
end;
|
||
aUSBDev.Free;
|
||
break;
|
||
end
|
||
else
|
||
aUSBDev.Free;
|
||
end;
|
||
Inc(Devn);
|
||
finally
|
||
FreeMem(FunctionClassDeviceData);
|
||
end;
|
||
end;
|
||
end;
|
||
until not Success;
|
||
finally
|
||
end;
|
||
finally
|
||
SetupDiDestroyDeviceInfoList(PnPHandle);
|
||
end;
|
||
end;
|
||
|
||
function USBDeviceSerial(GUID:TGUID; aPhysDevNumber: LongInt): Ansistring;
|
||
var
|
||
PnPHandle: HDEVINFO;
|
||
DevData: TSPDevInfoData;
|
||
DeviceInterfaceData: TSPDeviceInterfaceData;
|
||
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
|
||
Success: LongBool;
|
||
Devn: Integer;
|
||
BytesReturned: DWORD;
|
||
i: integer;
|
||
|
||
aUSBDev: TUSBDev;
|
||
Parent: DWORD;
|
||
VetoName: PAnsiChar;
|
||
begin
|
||
try
|
||
Result := '';
|
||
|
||
PnPHandle:= SetupDiGetClassDevs(@Guid, nil, 0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
|
||
|
||
if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
try
|
||
Devn := 0;
|
||
repeat
|
||
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
|
||
Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, Guid, Devn, DeviceInterfaceData);
|
||
if Success then
|
||
begin
|
||
DevData.cbSize := SizeOf(SP_DEVINFO_DATA);
|
||
DeviceInterfaceData.cbSize := SizeOf(SP_DEVICE_INTERFACE_DATA);
|
||
BytesReturned := 0;
|
||
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
|
||
if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
|
||
begin
|
||
FunctionClassDeviceData := AllocMem(BytesReturned);
|
||
try
|
||
FunctionClassDeviceData.cbSize := 5;
|
||
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
|
||
begin
|
||
aUSBDev := TUSBDev.Create;
|
||
aUSBDev.GetInfoForDev(PnPHandle, DevData, @FunctionClassDeviceData.DevicePath);
|
||
if aPhysDevNumber = GetDevNum(aUSBDev.FDevicePath) then
|
||
begin
|
||
result := aUSBDev.FDevicePath;
|
||
aUSBDev.Free;
|
||
break;
|
||
end
|
||
else
|
||
aUSBDev.Free;
|
||
end;
|
||
Inc(Devn);
|
||
finally
|
||
FreeMem(FunctionClassDeviceData);
|
||
end;
|
||
end;
|
||
end;
|
||
until not Success;
|
||
finally
|
||
end;
|
||
finally
|
||
SetupDiDestroyDeviceInfoList(PnPHandle);
|
||
end;
|
||
end;
|
||
|
||
function USBDeviceSerialSCSI(GUID:TGUID; aPhysDevNumber: LongInt): Ansistring;
|
||
var
|
||
PnPHandle: HDEVINFO;
|
||
DevData: TSPDevInfoData;
|
||
DeviceInterfaceData: TSPDeviceInterfaceData;
|
||
FunctionClassDeviceData: PSPDeviceInterfaceDetailData;
|
||
Success: LongBool;
|
||
Devn: Integer;
|
||
BytesReturned: DWORD;
|
||
i: integer;
|
||
|
||
aUSBDev: TUSBDev;
|
||
Parent: DWORD;
|
||
VetoName: PAnsiChar;
|
||
|
||
begin
|
||
try
|
||
Result := '';
|
||
|
||
G_PARENT_SCSI := '';
|
||
G_FHardwareID0 := '';
|
||
|
||
PnPHandle:= SetupDiGetClassDevs(@Guid, nil, 0,DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);
|
||
|
||
if PnPHandle = Pointer(INVALID_HANDLE_VALUE) then
|
||
Exit;
|
||
try
|
||
Devn := 0;
|
||
repeat
|
||
DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData);
|
||
Success := SetupDiEnumDeviceInterfaces(PnPHandle, nil, Guid, Devn, DeviceInterfaceData);
|
||
if Success then
|
||
begin
|
||
DevData.cbSize := SizeOf(SP_DEVINFO_DATA);
|
||
DeviceInterfaceData.cbSize := SizeOf(SP_DEVICE_INTERFACE_DATA);
|
||
BytesReturned := 0;
|
||
SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData);
|
||
if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then
|
||
begin
|
||
FunctionClassDeviceData := AllocMem(BytesReturned);
|
||
try
|
||
FunctionClassDeviceData.cbSize := 5;
|
||
if SetupDiGetDeviceInterfaceDetail(PnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then
|
||
begin
|
||
aUSBDev := TUSBDev.Create;
|
||
aUSBDev.GetInfoForDev(PnPHandle, DevData, @FunctionClassDeviceData.DevicePath);
|
||
if aPhysDevNumber = GetDevNum(aUSBDev.FDevicePath) then
|
||
begin
|
||
if CM_Get_Parent(@Parent, aUSBDev.FDevData.DevInst, 0) = 0 then
|
||
begin
|
||
//Tolik 21/06/2019 --
|
||
//VetoName := GetMemory(260);
|
||
VetoName := GetMemory(256*2);
|
||
//
|
||
CM_Get_Device_IDA(Parent, VetoName, 200, 0);
|
||
G_PARENT_SCSI := VetoName;
|
||
if Pos('USB\', G_PARENT_SCSI) = 1 then
|
||
begin
|
||
if aUSBDev.FHardwareID.Count > 0 then
|
||
G_FHardwareID0 := aUSBDev.FHardwareID[0];
|
||
end
|
||
else
|
||
G_PARENT_SCSI := '';
|
||
//showmessage('veto name - ' + VetoName);
|
||
//showmessage('Hardware ids - ' + aUSBDev.FHardwareID[0]);
|
||
FreeMemory(VetoName);
|
||
end;
|
||
if G_PARENT_SCSI <> '' then
|
||
begin
|
||
result := aUSBDev.FDevicePath;
|
||
aUSBDev.Free;
|
||
break;
|
||
end
|
||
else
|
||
aUSBDev.Free;
|
||
end
|
||
else
|
||
begin
|
||
aUSBDev.Free;
|
||
end;
|
||
end;
|
||
Inc(Devn);
|
||
finally
|
||
FreeMem(FunctionClassDeviceData);
|
||
end;
|
||
end;
|
||
end;
|
||
until not Success;
|
||
finally
|
||
end;
|
||
finally
|
||
SetupDiDestroyDeviceInfoList(PnPHandle);
|
||
end;
|
||
end;
|
||
|
||
function GetDevNum(aPath: Ansistring): LongInt;
|
||
var
|
||
hFile: THandle;
|
||
DevNum: TSTORAGE_DEVICE_NUMBER;
|
||
tmp: Dword;
|
||
begin
|
||
result := 0;
|
||
hFile := CreateFileA(PAnsiChar(aPath), 0 {GENERIC_READ} { $C0}, FILE_SHARE_READ OR FILE_SHARE_WRITE {4}, nil, OPEN_EXISTING {3}, 0 {FILE_ATTRIBUTE_NORMAL}, 0);
|
||
// hFile := CreateFile(PChar(aPath), $C0, 4, nil, 3, FILE_ATTRIBUTE_NORMAL, 0);
|
||
if hFile > 0 then
|
||
begin
|
||
DeviceIoControl(hFile, IOCTL_STORAGE_GET_DEVICE_NUMBER, nil, 0, @DevNum, sizeof(DevNum), Tmp, nil);
|
||
Result := DevNum.DeviceNumber;
|
||
end;
|
||
CloseHandle(hFile);
|
||
end;
|
||
|
||
function GetDEVID(aDevPath: Ansistring): Ansistring;
|
||
var
|
||
TempStr: Ansistring;
|
||
//ResDosDev : Array [1..MAX_PATH] of Char;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
|
||
begin
|
||
result := '';
|
||
try
|
||
If (QueryDosDeviceA(PAnsiChar(aDevPath), @ResDosDev, MAX_PATH) <> 0) then
|
||
begin
|
||
//TempStr := StrPas(@ResDosDev);
|
||
//TempStr := StrPas(ResDosDev);
|
||
|
||
TempStr := StrPas(PAnsiChar(@ResDosDev));
|
||
aUSBDev := USBDeviceFind(GUID_DEVINTERFACE_VOLUME, TempStr);
|
||
if assigned(aUSBDev) then
|
||
begin
|
||
if (Pos('removablemedia', AnsiLowerCase(aUSBDev.FDevicePath)) > 0) or (Pos('usbstor', AnsiLowerCase(aUSBDev.FDevicePath)) > 0)
|
||
then// or (Pos('scsi#disk', AnsiLowerCase(TempStr)) > 0) then
|
||
begin
|
||
DevNumber := GetDevNum(aUSBDev.FDevicePath);
|
||
tempstr := AnsiLowerCase(USBDeviceSerial(GUID_DEVINTERFACE_DISK, DevNumber));
|
||
end;
|
||
tempstr := copy(tempstr, pos('&rev', tempstr), pos('{', tempstr) - pos('&rev', tempstr) - 1);
|
||
tempstr := FastReplace(tempstr, '#', '\');
|
||
result := tempstr;
|
||
SetupDiDestroyDeviceInfoList(aUSBDev.FPnPHandle);
|
||
aUSBDev.Free;
|
||
end;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
function GetDEVIDOther(aDevPath: Ansistring): Ansistring;
|
||
var
|
||
TempStr: Ansistring;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
begin
|
||
result := '';
|
||
|
||
try
|
||
If (QueryDosDeviceA(PAnsiChar(aDevPath), @ResDosDev, MAX_PATH) <> 0) then
|
||
begin
|
||
TempStr := StrPas(PAnsiChar(@ResDosDev));
|
||
aUSBDev := USBDeviceFind(GUID_DEVINTERFACE_VOLUME, TempStr);
|
||
if assigned(aUSBDev) then
|
||
begin
|
||
DevNumber := GetDevNum(aUSBDev.FDevicePath);
|
||
SetupDiDestroyDeviceInfoList(aUSBDev.FPnPHandle);
|
||
aUSBDev.Free;
|
||
result := USBDeviceSerial(GUID_DEVINTERFACE_DISK, DevNumber);
|
||
if result <> '' then
|
||
begin
|
||
if (Pos('usbstor', AnsiLowerCase(result)) <= 0) and
|
||
(Pos('scsi#disk', AnsiLowerCase(result)) <= 0) then
|
||
result := ''
|
||
else
|
||
begin
|
||
//<2F><><EFBFBD><EFBFBD> scsi - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>;
|
||
if (Pos('scsi#disk', AnsiLowerCase(result)) > 0) then
|
||
begin
|
||
//ShowMessage(result);
|
||
Result := GetDEVIDOtherSCSI(aDevPath);
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
function GetDEVIDOtherSCSI(aDevPath: Ansistring): Ansistring;
|
||
var
|
||
TempStr: Ansistring;
|
||
TempStr2: Ansistring;
|
||
TempStrExcl: Ansistring;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
tempstrlist: TStringList;
|
||
i: integer;
|
||
begin
|
||
result := '';
|
||
|
||
try
|
||
If (QueryDosDeviceA(PAnsiChar(aDevPath), @ResDosDev, MAX_PATH) <> 0) then
|
||
begin
|
||
TempStr := StrPas(PAnsiChar(@ResDosDev));
|
||
aUSBDev := USBDeviceFind(GUID_DEVINTERFACE_VOLUME, TempStr);
|
||
|
||
if assigned(aUSBDev) then
|
||
begin
|
||
DevNumber := GetDevNum(aUSBDev.FDevicePath);
|
||
SetupDiDestroyDeviceInfoList(aUSBDev.FPnPHandle);
|
||
aUSBDev.Free;
|
||
result := USBDeviceSerialSCSI(GUID_DEVINTERFACE_DISK, DevNumber);
|
||
if result <> '' then
|
||
begin
|
||
if (Pos('usbstor', AnsiLowerCase(result)) <= 0) and
|
||
(Pos('scsi#disk', AnsiLowerCase(result)) <= 0) then
|
||
result := ''
|
||
else
|
||
begin
|
||
//if (Pos('scsi#disk', AnsiLowerCase(result)) <= 0) then
|
||
begin
|
||
tempstr := '';
|
||
if FileExists(ExtractFileDir(Application.ExeName) + '\usb_rev.ini') then
|
||
begin
|
||
tempstrlist := TStringList.Create;
|
||
tempstrlist.LoadFromFile(ExtractFileDir(Application.ExeName) + '\usb_rev.ini');
|
||
tempstr := trim(ansilowercase(tempstrlist.Text));
|
||
tempstrlist.Free;
|
||
end
|
||
else
|
||
begin
|
||
tempstr := ansilowercase(G_FHardwareID0);
|
||
if Pos('____', tempstr) > 0 then
|
||
begin
|
||
tempstr := trim(copy(tempstr, Pos('____', tempstr), $FFFF));
|
||
tempstr := trim(FastReplace(TempStr, '_', ''));
|
||
end;
|
||
end;
|
||
TempStr2 := '';
|
||
if length(G_PARENT_SCSI) > 0 then
|
||
begin
|
||
for i := length(G_PARENT_SCSI) downto 1 do
|
||
begin
|
||
if G_PARENT_SCSI[i] <> '\' then
|
||
TempStr2 := G_PARENT_SCSI[i] + TempStr2
|
||
else
|
||
break;
|
||
end;
|
||
end;
|
||
TempStr2 := Trim(AnsiLowerCase(TempStr2));
|
||
if FileExists(ExtractFileDir(Application.ExeName) + '\usb_excl.ini') then
|
||
begin
|
||
tempstrlist := TStringList.Create;
|
||
tempstrlist.LoadFromFile(ExtractFileDir(Application.ExeName) + '\usb_excl.ini');
|
||
TempStrExcl := trim(ansilowercase(tempstrlist.Text));
|
||
tempstrlist.Free;
|
||
end
|
||
else
|
||
begin
|
||
TempStrExcl := 'msft30';
|
||
end;
|
||
TempStr2 := FastReplace(TempStr2, TempStrExcl, '', False);
|
||
result := 'scsi#disk&rev_' + TempStr + '#' + TempStr2 + '&0#{';
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
//function IsRemoveable(aDevPath: string): Boolean;
|
||
function IsRemoveable(aDevPath: Ansistring): Boolean;
|
||
var
|
||
TempStr: Ansistring;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
begin
|
||
try
|
||
result := False;
|
||
If (QueryDosDeviceA(PAnsiChar(aDevPath), @ResDosDev, MAX_PATH) <> 0) then
|
||
begin
|
||
TempStr := StrPas(PAnsiChar(@ResDosDev));
|
||
aUSBDev := USBDeviceFind(GUID_DEVINTERFACE_VOLUME, TempStr);
|
||
if assigned(aUSBDev) then
|
||
begin
|
||
if (Pos('removablemedia', AnsiLowerCase(aUSBDev.FDevicePath)) > 0) or (Pos('usbstor', AnsiLowerCase(aUSBDev.FDevicePath)) > 0)
|
||
then //or (Pos('scsi#disk', AnsiLowerCase(aUSBDev.FDevicePath)) > 0) then
|
||
begin
|
||
Result := True;
|
||
end;
|
||
SetupDiDestroyDeviceInfoList(aUSBDev.FPnPHandle);
|
||
aUSBDev.Free;
|
||
end;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
function IsRemoveableUSBHard(aDevPath: Ansistring): Boolean;
|
||
var
|
||
TempStr: string;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
begin
|
||
try
|
||
result := False;
|
||
G_PARENT_SCSI := '';
|
||
tempstr := GetDEVIDOther(aDevPath); // <20><><EFBFBD><EFBFBD> SCSI - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GetDEVIDOtherSCSI <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20> GParent
|
||
//if tempstr <> '' then
|
||
// ShowMessage('IsRemoveableUSBHard tempstr = ' + tempstr);
|
||
if (Pos('removablemedia', AnsiLowerCase(TempStr)) > 0) or (Pos('usbstor', AnsiLowerCase(TempStr)) > 0)
|
||
or (Pos('scsi#disk', AnsiLowerCase(TempStr)) > 0) then
|
||
begin
|
||
if (Pos('scsi#disk', AnsiLowerCase(TempStr)) > 0) then
|
||
begin
|
||
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> - <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> USB
|
||
// <20><> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
//ShowMessage('G_PARENT_SCSI = ' + G_PARENT_SCSI);
|
||
if Pos('USB\', G_PARENT_SCSI) = 1 then
|
||
Result := True;
|
||
end
|
||
else
|
||
Result := True;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
procedure EjectDrive(aDrive: Ansistring);
|
||
var
|
||
aUSBDev: TUSBDev;
|
||
DevNumber: LongInt;
|
||
ResDosDev : Array [1..MAX_PATH] of AnsiChar;
|
||
TempStr: Ansistring;
|
||
begin
|
||
try
|
||
If (QueryDosDeviceA(PAnsiChar(aDrive), @ResDosDev, MAX_PATH) <> 0) then
|
||
begin
|
||
sleep(1500);
|
||
TempStr := StrPas(PAnsiChar(@ResDosDev));
|
||
aUSBDev := USBDeviceFind(GUID_DEVINTERFACE_VOLUME, TempStr);
|
||
if assigned(aUSBDev) then
|
||
begin
|
||
if (Pos('removablemedia', AnsiLowerCase(aUSBDev.FDevicePath)) > 0) or (Pos('usbstor', AnsiLowerCase(aUSBDev.FDevicePath)) > 0)
|
||
or (Pos('scsi#disk', AnsiLowerCase(aUSBDev.FDevicePath)) > 0)then
|
||
begin
|
||
DevNumber := GetDevNum(aUSBDev.FDevicePath);
|
||
USBDeviceEject(GUID_DEVINTERFACE_DISK, DevNumber);
|
||
end
|
||
{TODO: USB Fixed}
|
||
else
|
||
tempstr := GetDEVIDOther(aDrive);
|
||
if (Pos('removablemedia', AnsiLowerCase(TempStr)) > 0) or (Pos('usbstor', AnsiLowerCase(TempStr)) > 0)
|
||
or (Pos('scsi#disk', AnsiLowerCase(aUSBDev.FDevicePath)) > 0) then
|
||
begin
|
||
DevNumber := GetDevNum(aUSBDev.FDevicePath);
|
||
USBDeviceEject(GUID_DEVINTERFACE_DISK, DevNumber);
|
||
end;
|
||
{TODO: END}
|
||
SetupDiDestroyDeviceInfoList(aUSBDev.FPnPHandle);
|
||
aUSBDev.Free;
|
||
end;
|
||
end;
|
||
except
|
||
end;
|
||
end;
|
||
|
||
procedure SelfRemoteEject;
|
||
var
|
||
TempStr1: Ansistring;
|
||
Handle: THandle;
|
||
begin
|
||
try
|
||
TempStr1 := ExtractFileDir(Application.ExeName);
|
||
DeleteFile(PChar(GetTempDir + '\EjectUSB.exe'));
|
||
// if Not FileExists(GetTempDir + '\EjectUSB.exe') then
|
||
CopyFile(PChar(TempStr1 + '\EjectUSB.exe'), PChar(GetTempDir + '\EjectUSB.exe'), False);
|
||
TempStr1 := copy(TempStr1, 1, 2);
|
||
// sleep(100);
|
||
Handle := GetDesktopWindow;
|
||
ShellExecute(Handle, PChar('open'), PChar(GetTempDir + '\EjectUSB.exe'), PChar(TempStr1), PChar(GetTempDir), SW_HIDE);
|
||
except
|
||
end;
|
||
end;
|
||
|
||
|
||
end.
|