admin

[系统应用] 获取U盘序列号

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;


#1楼
发帖时间:6月前   |   查看数:0   |   回复数:0
游客组