怎么根据盘符获取物理序列号?

日总是我哥 2008-10-29 02:32:34
怎么根据盘符获取物理序列号?
...全文
504 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
日总是我哥 2008-11-01
  • 打赏
  • 举报
回复
算了,结贴~
超度逗比 2008-10-31
  • 打赏
  • 举报
回复
可以搜索下 实战DeviceIoControl 之一到六 等系列文章参考学习,还有就是对DeviceIoControl的用法相关的资料,源码可以下载 DiskID32 这样的来参考。以前写按键精灵取硬盘物理序列号插件时候搜索收集参考学习过这样的资料,这玩意对高手来说都是不屑的,呵呵。
JeffChung 2008-10-30
  • 打赏
  • 举报
回复
这个搞不定!

顶贴接分吧。
masterjames 2008-10-30
  • 打赏
  • 举报
回复
http://blog.csdn.net/masterjames/archive/2008/09/24/2972006.aspx
这里有硬件的。
CaiBirdy 2008-10-30
  • 打赏
  • 举报
回复
逻辑序列号有API用,物理的貌似不可以吧
用这个API GetVolumeInformation
日总是我哥 2008-10-30
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 gyk120 的回复:]
楼主做出来的话麻烦通知一声,我们一定力挺你去微软工作……
玩笑话……别当真
[/Quote]
我会当真的-_-!!
日总是我哥 2008-10-30
  • 打赏
  • 举报
回复
回楼上:根据盘符,如果这个盘符是U盘怎么调用?


[Quote=引用 16 楼 CaiBirdy 的回复:]
逻辑序列号有API用,物理的貌似不可以吧
用这个API GetVolumeInformation
[/Quote]
这里逻辑序列号
penang 2008-10-30
  • 打赏
  • 举报
回复

function GetIdeSerialNumber: pchar; //获取硬盘的出厂系列号;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE;
bSectorCountReg: BYTE;
bSectorNumberReg: BYTE;
bCylLowReg: BYTE;
bCylHighReg: BYTE;
bDriveHeadReg: BYTE;
bCommandReg: BYTE;
bReserved: BYTE;
end;
TSendCmdInParams = packed record
cBufferSize: DWORD;
irDriveRegs: TIDERegs;
bDriveNumber: BYTE;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte;
end;
TIdSector = packed record
wGenConfig: Word;
wNumCyls: Word;
wReserved: Word;
wNumHeads: Word;
wBytesPerTrack: Word;
wBytesPerSector: Word;
wSectorsPerTrack: Word;
wVendorUnique: array[0..2] of Word;
sSerialNumber: array[0..19] of CHAR;
wBufferType: Word;
wBufferSize: Word;
wECCSize: Word;
sFirmwareRev: array[0..7] of Char;
sModelNumber: array[0..39] of Char;
wMoreVendorUnique: Word;
wDoubleWordIO: Word;
wCapabilities: Word;
wReserved1: Word;
wPIOTiming: Word;
wDMATiming: Word;
wBS: Word;
wNumCurrentCyls: Word;
wNumCurrentHeads: Word;
wNumCurrentSectorsPerTrack: Word;
ulCurrentSectorCapacity: DWORD;
wMultSectorStuff: Word;
ulTotalAddressableSectors: DWORD;
wSingleWordDMA: Word;
wMultiWordDMA: Word;
bReserved: array[0..127] of BYTE;
end;
PIdSector = ^TIdSector;
TDriverStatus = packed record
bDriverError: Byte;
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
cBufferSize: DWORD;
DriverStatus: TDriverStatus;
bBuffer: array[0..0] of BYTE;
end;
var
hDevice: Thandle;
cbBytesReturned: DWORD;
SCIP: TSendCmdInParams;
aIdOutCmd: array[0..(SizeOf(TSendCmdOutParams) + IDENTIFY_BUFFER_SIZE-1)-1] of Byte;
IdOutCmd: TSendCmdOutParams absolute aIdOutCmd;
procedure ChangeByteOrder(var Data; Size: Integer);
var
ptr: Pchar;
i: Integer;
c: Char;
begin
ptr := @Data;
for I := 0 to (Size shr 1) - 1 do begin
c := ptr^;
ptr^ := (ptr + 1)^;
(ptr + 1)^ := c;
Inc(ptr, 2);
end;
end;
begin
Result := '';
if SysUtils.Win32Platform = VER_PLATFORM_WIN32_NT then begin // Windows NT, Windows 2000
hDevice := CreateFile('\\.\PhysicalDrive0', GENERIC_READ or GENERIC_WRITE,
FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
end else // Version Windows 95 OSR2, Windows 98
hDevice := CreateFile('\\.\SMARTVSD', 0, 0, nil, CREATE_NEW, 0, 0);
if hDevice = INVALID_HANDLE_VALUE then Exit;
try
FillChar(SCIP, SizeOf(TSendCmdInParams) - 1, #0);
FillChar(aIdOutCmd, SizeOf(aIdOutCmd), #0);
cbBytesReturned := 0;
with SCIP do begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
with irDriveRegs do begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
bDriveHeadReg := $A0;
bCommandReg := $EC;
end;
end;
if not DeviceIoControl(hDevice, $0007C088, @SCIP, SizeOf(TSendCmdInParams) - 1,
@aIdOutCmd, SizeOf(aIdOutCmd), cbBytesReturned, nil) then Exit;
finally
CloseHandle(hDevice);
end;
with PIdSector(@IdOutCmd.bBuffer)^ do begin
ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
(Pchar(@sSerialNumber) + SizeOf(sSerialNumber))^:= #0;
Result := Pchar(@sSerialNumber);
end;
end;




qkhhxkj102 2008-10-29
  • 打赏
  • 举报
回复
我的天呀,小弟路过
gyk120 2008-10-29
  • 打赏
  • 举报
回复
楼主做出来的话麻烦通知一声,我们一定力挺你去微软工作……
玩笑话……别当真
hongqi162 2008-10-29
  • 打赏
  • 举报
回复
这个搞不定!

顶贴接分吧。
日总是我哥 2008-10-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 fangsp 的回复:]
呵呵 帮楼主高手顶一个了
[/Quote]
看到你这话,楼上的都笑了。。。。:)

fangsp 2008-10-29
  • 打赏
  • 举报
回复
呵呵 帮楼主高手顶一个了
ahjoe 2008-10-29
  • 打赏
  • 举报
回复
GetDriveType确实是有问题。
daily66 2008-10-29
  • 打赏
  • 举报
回复
呵呵
日总是我哥 2008-10-29
  • 打赏
  • 举报
回复
怪不得ChipGenius一枝独秀~~~
CloneCenter 2008-10-29
  • 打赏
  • 举报
回复
这个搞不定!

顶贴接分吧。
lxpbuaa 2008-10-29
  • 打赏
  • 举报
回复
CoolSB
aiirii 2008-10-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 ly_liuyang 的回复:]
DeviceIoControl的IOCTL_STORAGE_QUERY_PROPERTY方法
[/Quote]

参考LY的说法
日总是我哥 2008-10-29
  • 打赏
  • 举报
回复
网站上前篇一律的文章“获取U盘序列号的代码”http://www.delphifans.com/InfoView/Article_940.html


执行到这里

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;

的时候,Str就没有了任何内容,也就是说,DosDevices\下面不一定都含有RemovableMedia字符。


而且,这段代码

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;

的GetDriveType也存在问题,并不是所有U盘的类型都是DRIVE_REMOVABLE
加载更多回复(2)

1,183

社区成员

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

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