const
DIGCF_PRESENT = $00000002;
DIGCF_DEVICEINTERFACE = $00000010;
ANYSIZE_ARRAY = 1;
SetupAPI = 'SetupAPI.DLL';
type
HDEVINFO = Pointer;
ULONG_PTR = DWord;
PSPDevInfoData = ^TSPDevInfoData;
SP_DEVINFO_DATA = packed record
cbSize: DWord;
ClassGuid: TGUID;
DevInst: DWord;
Reserved: ULONG_PTR;
end;
{$EXTERNALSYM SP_DEVINFO_DATA}
TSPDevInfoData = SP_DEVINFO_DATA;
PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;
SP_DEVICE_INTERFACE_DATA = packed record
cbSize: DWord;
InterfaceClassGuid: TGUID;
Flags: DWord;
Reserved: ULONG_PTR;
end;
{$EXTERNALSYM SP_DEVICE_INTERFACE_DATA}
TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;
PSPDeviceInterfaceDetailDataA = ^TSPDeviceInterfaceDetailDataA;
SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record
cbSize: DWord;
DevicePath: array[0..ANYSIZE_ARRAY - 1] of AnsiChar;
end;
{$EXTERNALSYM SP_DEVICE_INTERFACE_DETAIL_DATA_A}
TSPDeviceInterfaceDetailDataA = SP_DEVICE_INTERFACE_DETAIL_DATA_A;
function SetupDiGetClassDevsA(ClassGuid: PGUID; const Enumerator: PAnsiChar;
hwndParent: HWND; Flags: DWord): HDEVINFO; stdcall; external SetupAPI;
function SetupDIEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;
DeviceInfoData: PSPDevInfoData; const InterfaceClassGuid: TGUID;
MemberIndex: DWord; var DeviceInterfaceData: TSPDeviceInterfaceData):
BOOL; stdcall; external SetupAPI;
{$EXTERNALSYM SetupDIEnumDeviceInterfaces}
function SetupDiGetDeviceInterfaceDetailA(DeviceInfoSet: HDEVINFO;
DeviceInterfaceData: PSPDeviceInterfaceData;
DeviceInterfaceDetailData: PSPDeviceInterfaceDetailDataA;
DeviceInterfaceDetailDataSize: DWord; var RequiredSize: DWord;
Device: PSPDevInfoData): BOOL; stdcall; external SetupAPI;
function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL;
stdcall; external SetupAPI;
function GetUSBDiskID(const DiskID: string; var PID: string): Boolean;
var
USBGuid: TGUID;
USBHandle: HDEVINFO;
Success: LongBool;
Devn: Integer;
DevData: TSPDevInfoData;
DeviceInterfaceData: TSPDeviceInterfaceData;
FunctionClassDeviceData: PSPDeviceInterfaceDetailDataA;
BytesReturned: DWord;
Reg: TRegistry;
RegData: array of Char;
i, RegSize: Integer;
Str, USBPath: string;
begin
Result := false;
Pid := '';
Reg := TRegistry.Create;
try
Reg.RootKey := HKEY_LOCAL_MacHINE;
Reg.OpenKey('SYSTEM\MountedDevices', false);
RegSize := Reg.GetDataSize(Format('\DOSDevices\%s', [DiskID]));
SetLength(RegData, RegSize + 1);
Reg.ReadBinaryData(Format('\DOSDevices\%s', [DiskID]), RegData[0], RegSize + 1); for i := 0 to RegSize - 1 do if RegData[i] <> #0 then Str := Str + RegData[i]; Str := Copy(Str, Pos('#RemovableMedia#', Str) + 16, Length(Str)); Str := Copy(Str, 1, Pos('RM', Str) - 2); Str := UpperCase(Str); Reg.CloseKey; USBGuid := StringToGUID('{53f56307-b6bf-11d0-94f2-00a0c91efb8b}'); USBHandle := SetupDiGetClassDevsA(@USBGuid, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE); if USBHandle = Pointer(INVALID_HANDLE_VALUE) then Exit; Devn := 0; repeat DeviceInterfaceData.cbSize := SizeOf(TSPDeviceInterfaceData); Success := SetupDIEnumDeviceInterfaces(USBHandle, nil, USBGuid, Devn, DeviceInterfaceData); if Success then begin DevData.cbSize := SizeOf(DevData); BytesReturned := 0; SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevData); if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin FunctionClassDeviceData := AllocMem(BytesReturned); FunctionClassDeviceData^.cbSize := SizeOf(TSPDeviceInterfaceDetailDataA); if SetupDiGetDeviceInterfaceDetailA(USBHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevData) then begin USBPath := StrPas(PChar(@FunctionClassDeviceData.DevicePath)); if Reg.OpenKeyReadOnly(Format('SYSTEM\CurrentControlSet\Enum%s', [StringReplace(Copy(USBPath, 4, Pos('{', USBPath) - 5), '#', '\', [rfReplaceAll])])) then if UpperCase(Reg.ReadString('ParentIdPrefix')) = Str then begin Delete(USBPath, 1, Pos('#', USBPath)); PID := Copy(USBPath, Pos('#', USBPath) + 1, Length(USBPath)); PID := Copy(PID, 1, Pos('#{', PID) - 1); PID := UpperCase(StringReplace(PID, '&', '', [rfReplaceAll])); Result := True; Break; end; Reg.CloseKey; Inc(Devn); end; FreeMem(FunctionClassDeviceData); end; end; until not Success; SetupDiDestroyDeviceInfoList(USBHandle); finally Reg.Free; end; end; 使用方法:procedure TForm1.Button1Click(Sender: TObject);
var
Drv, Pid: string;
begin
Drv := ExtractFileDrive(ParamStr(0));
if GetDriveType(PChar(Drv + '\')) <> DRIVE_REMOVABLE then
Application.MessageBox('對不起,請把本程序放至到優盤上使用!', 'Error', MB_ICONHAND)
else if GetUSBDiskID(Drv, Pid) then ShowMessage(Pid);
end;