请指点编程识别U盘特征的思路,有源码更好

theseraph 2008-12-08 09:01:32
如何编程识别U盘的唯一特征身份呢,不限方法,得要对每种U盘都适用,针对特定芯片的方法作为参考,如果提供的类型比较全,也可以得全分(但想全不太容易吧),或者没有完美方法的话,可以在散分的时候多得点。
但反对上来不思考、不搜索资料就说接分,这样都抱着接分心理,问题就不容易解决了。给分还可能考虑给,不会多。
也不要上来,不经过调查就说不现实,因为U盘,无论哪个厂商出品,都该给个特征识别方法(通用也好、厂用也好),都什么年头了,生产瓶汽水可乐都加条形码呢,更何况电子产品乎?然否?
别说我偷懒啊,也搜索了一下,净是些使用上的识别,而不是编程识别U盘特征。如果可以建立不可见的(如果谁说加系统S和隐藏H属性的,赶紧出去)更主要得是不可复制的特殊特征文件(例如人为创建坏道等,但都是老方式,会不会因为修复而改变也难以保证)也可考虑,就是想为软件实现一个U盘身份识别的功能,对U盘,不对主机。我用过电子KEY盘,那是专门加工的一种,不想再用它,就是让用户在U盘上运行软件,限定只在该U盘上运行,用户有一定常识,普通方法都不行。
由于这个问题不限定编程语言,得各版块都发一下,因此现在给分不能太多。如果回答的资料好,可以开专帖追加分数,本人信用情况,从论坛功能也看得出来还算可以吧。其实主要的,也是高手们出来晾一晾。
编程语言最好是VB,如果是DELPHI,C,也可以。
...全文
171 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
tanqth 2008-12-30
  • 打赏
  • 举报
回复
对了,补充一下,还有方法是使用量产工具,但这通常需要与U盘型\厂家配套。
另,可直接读写“磁道”。
tanqth 2008-12-30
  • 打赏
  • 举报
回复
xiedewei
的代码是可行的,我以前用过.
WWX330 2008-12-29
  • 打赏
  • 举报
回复
学习过`~,
楼上的好像没提到U盘的特证吧
不解
hnityd 2008-12-23
  • 打赏
  • 举报
回复
U盘序列号一般都是唯一的
yuehaiyang 2008-12-23
  • 打赏
  • 举报
回复
判优盘序列号
xiedewei 2008-12-23
  • 打赏
  • 举报
回复
给你贴一段代码
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;
lahcs 2008-12-09
  • 打赏
  • 举报
回复
可以获取U盘的序列号啊
这个应该比较唯一了吧
具体代码你上网搜索一下
找不到的话把邮箱给我...我发给你
无条件为你 2008-12-08
  • 打赏
  • 举报
回复
其它版的分要了无用,只对DELPHI版的分感兴趣,你这个问题给了20分,虽然我可以解决,但还是决定帮你顶一下贴子让不在乎分的人来帮你吧。
qiujsh 2008-12-08
  • 打赏
  • 举报
回复
关注

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧