如何编程识别U盘的唯一特征身份呢,不限方法,得要对每种U盘都适用,针对特定芯片的方法作为参考,如果提供的类型比较全,也可以得全分(但想全不太容易吧),或者没有完美方法的话,可以在散分的时候多得点。
    但反对上来不思考、不搜索资料就说接分,这样都抱着接分心理,问题就不容易解决了。给分还可能考虑给,不会多。
    也不要上来,不经过调查就说不现实,因为U盘,无论哪个厂商出品,都该给个特征识别方法(通用也好、厂用也好),都什么年头了,生产瓶汽水可乐都加条形码呢,更何况电子产品乎?然否?
    别说我偷懒啊,也搜索了一下,净是些使用上的识别,而不是编程识别U盘特征。如果可以建立不可见的(如果谁说加系统S和隐藏H属性的,赶紧出去)更主要得是不可复制的特殊特征文件(例如人为创建坏道等,但都是老方式,会不会因为修复而改变也难以保证)也可考虑,就是想为软件实现一个U盘身份识别的功能,对U盘,不对主机。我用过电子KEY盘,那是专门加工的一种,不想再用它,就是让用户在U盘上运行软件,限定只在该U盘上运行,用户有一定常识,普通方法都不行。
    由于这个问题不限定编程语言,得各版块都发一下,因此现在给分不能太多。如果回答的资料好,可以开专帖追加分数,本人信用情况,从论坛功能也看得出来还算可以吧。其实主要的,也是高手们出来晾一晾。
    编程语言最好是VB,如果是DELPHI,C,也可以。

解决方案 »

  1.   

    其它版的分要了无用,只对DELPHI版的分感兴趣,你这个问题给了20分,虽然我可以解决,但还是决定帮你顶一下贴子让不在乎分的人来帮你吧。
      

  2.   

    给你贴一段代码
    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;
      

  3.   

    xiedewei 
    的代码是可行的,我以前用过.