buffer:array[0..255]of char;
a,b:dword;
serialNum:pdword;
begin
GetVolumeInformation('c:\', Buffer, SizeOf(Buffer), SerialNum, a, b, nil, 0);
Serial:=inttostr(SerialNum^);
end;我用以上代码为何读过来的序列号都不一样,急
a,b:dword;
serialNum:pdword;
begin
GetVolumeInformation('c:\', Buffer, SizeOf(Buffer), SerialNum, a, b, nil, 0);
Serial:=inttostr(SerialNum^);
end;我用以上代码为何读过来的序列号都不一样,急
function TForm1.GetIdeSerialNumber(Index: byte): PChar;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
TSendCmdInParams = packed record
// Buffer size in bytes
cBufferSize: DWORD;
// Structure with drive register values.
irDriveRegs: TIDERegs;
// Physical drive number to send command to (0,1,2,3).
bDriveNumber: BYTE;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte; // Input buffer.
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
// Çý¶¯Æ÷·µ»ØµÄ´íÎó´úÂ룬ÎÞ´íÔò·µ»Ø0
bDriverError: Byte;
// IDE³ö´í¼Ä´æÆ÷µÄÄÚÈÝ£¬Ö»Óе±bDriverError Ϊ SMART_IDE_ERROR ʱÓÐЧ
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// bBufferµÄ´óС
cBufferSize: DWORD;
// Çý¶¯Æ÷״̬
DriverStatus: TDriverStatus;
// ÓÃÓÚ±£´æ´ÓÇý¶¯Æ÷¶Á³öµÄÊý¾ÝµÄ»º³åÇø£¬Êµ¼Ê³¤¶ÈÓÉcBufferSize¾ö¶¨
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/2000/XP/.net ¸Ä±äÃû³Æ¿ÉÊÊÓÃÓÚÆäËüÇý¶¯Æ÷£¬ÈçµÚ¶þ¸öÇý¶¯Æ÷£º '\\.\PhysicalDrive1\'
// also can be SCSI0 SCSI1
hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Index)), 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;
// Set up data structures for IDENTIFY command.
with SCIP do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
// bDriveNumber := 0;
with irDriveRegs do
begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
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;
function TForm1.GetIdeSerialNumber(Index: byte): PChar;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
TSendCmdInParams = packed record
// Buffer size in bytes
cBufferSize: DWORD;
// Structure with drive register values.
irDriveRegs: TIDERegs;
// Physical drive number to send command to (0,1,2,3).
bDriveNumber: BYTE;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte; // Input buffer.
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
// Çý¶¯Æ÷·µ»ØµÄ´íÎó´úÂ룬ÎÞ´íÔò·µ»Ø0
bDriverError: Byte;
// IDE³ö´í¼Ä´æÆ÷µÄÄÚÈÝ£¬Ö»Óе±bDriverError Ϊ SMART_IDE_ERROR ʱÓÐЧ
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// bBufferµÄ´óС
cBufferSize: DWORD;
// Çý¶¯Æ÷״̬
DriverStatus: TDriverStatus;
// ÓÃÓÚ±£´æ´ÓÇý¶¯Æ÷¶Á³öµÄÊý¾ÝµÄ»º³åÇø£¬Êµ¼Ê³¤¶ÈÓÉcBufferSize¾ö¶¨
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/2000/XP/.net ¸Ä±äÃû³Æ¿ÉÊÊÓÃÓÚÆäËüÇý¶¯Æ÷£¬ÈçµÚ¶þ¸öÇý¶¯Æ÷£º '\\.\PhysicalDrive1\'
// also can be SCSI0 SCSI1
hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Index)), 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;
// Set up data structures for IDENTIFY command.
with SCIP do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
// bDriveNumber := 0;
with irDriveRegs do
begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
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;
function TForm1.GetIdeSerialNumber(Index: byte): PChar;
const IDENTIFY_BUFFER_SIZE = 512;
type
TIDERegs = packed record
bFeaturesReg: BYTE; // Used for specifying SMART "commands".
bSectorCountReg: BYTE; // IDE sector count register
bSectorNumberReg: BYTE; // IDE sector number register
bCylLowReg: BYTE; // IDE low order cylinder value
bCylHighReg: BYTE; // IDE high order cylinder value
bDriveHeadReg: BYTE; // IDE drive/head register
bCommandReg: BYTE; // Actual IDE command.
bReserved: BYTE; // reserved for future use. Must be zero.
end;
TSendCmdInParams = packed record
// Buffer size in bytes
cBufferSize: DWORD;
// Structure with drive register values.
irDriveRegs: TIDERegs;
// Physical drive number to send command to (0,1,2,3).
bDriveNumber: BYTE;
bReserved: array[0..2] of Byte;
dwReserved: array[0..3] of DWORD;
bBuffer: array[0..0] of Byte; // Input buffer.
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
// Çý¶¯Æ÷·µ»ØµÄ´íÎó´úÂ룬ÎÞ´íÔò·µ»Ø0
bDriverError: Byte;
// IDE³ö´í¼Ä´æÆ÷µÄÄÚÈÝ£¬Ö»Óе±bDriverError Ϊ SMART_IDE_ERROR ʱÓÐЧ
bIDEStatus: Byte;
bReserved: array[0..1] of Byte;
dwReserved: array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// bBufferµÄ´óС
cBufferSize: DWORD;
// Çý¶¯Æ÷״̬
DriverStatus: TDriverStatus;
// ÓÃÓÚ±£´æ´ÓÇý¶¯Æ÷¶Á³öµÄÊý¾ÝµÄ»º³åÇø£¬Êµ¼Ê³¤¶ÈÓÉcBufferSize¾ö¶¨
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/2000/XP/.net ¸Ä±äÃû³Æ¿ÉÊÊÓÃÓÚÆäËüÇý¶¯Æ÷£¬ÈçµÚ¶þ¸öÇý¶¯Æ÷£º '\\.\PhysicalDrive1\'
// also can be SCSI0 SCSI1
hDevice := CreateFile(PChar('\\.\PhysicalDrive'+IntToStr(Index)), 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;
// Set up data structures for IDENTIFY command.
with SCIP do
begin
cBufferSize := IDENTIFY_BUFFER_SIZE;
// bDriveNumber := 0;
with irDriveRegs do
begin
bSectorCountReg := 1;
bSectorNumberReg := 1;
// if Win32Platform=VER_PLATFORM_WIN32_NT then bDriveHeadReg := $A0
// else bDriveHeadReg := $A0 or ((bDriveNum and 1) shl 4);
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;
function Tdenglu.GetHDSerialNumber: LongInt; //得到硬盘序列号
{$IFDEF WIN32}
var
pdw : pDWord;
mc, fl : dword;
{$ENDIF}
begin
{$IfDef WIN32}
New(pdw);
GetVolumeInformation('c:\',nil,0,pdw,mc,fl,nil,0);
Result := pdw^;
dispose(pdw);
{$ELSE}
Result := GetWinFlags;
{$ENDIF}
end;Function Tdenglu.UnLockHard(aStr,NetId:String):String; //解密。
var
i,len : integer;
p : byte;
tmp,str : String;
Source : String;
begin
str := '';
Source:= '';
len := Length(NetId);
while Length(aStr) < (len div 3) do aStr := aStr + '0';
for i:=len downto 1 do str := str + NetId[i]; //字符串倒转
try
begin
len := len div 3;
for i:= 1 to len do
begin
tmp := copy(str, i*3-2, 3);
p := StrToInt(tmp) - ord(aStr[i]);
Source := Source + chr( p );
end;
end
except
Source := ''; //若口令或角色编号中含有非法字符, 则置空
end;
Result := Source;
end;
我的经验是:
序列号:serialNum 不可定义为指针类型pdword,而应该定义为值类型DWORD
不同分区有不同序列号
修改后程序:procedure TForm1.Button1Click(Sender: TObject);
var
buffer:array[0..255]of char;
a,b:dword;
serialNum:Dword;
begin
GetVolumeInformation('D:\', Buffer, SizeOf(Buffer), @SerialNum, a, b, nil, 0);
Edit1.Text:=inttohex(SerialNum,8);
end;
var
buffer:array[0..255]of char;
a,b:dword;
serialNum:Dword;
begin
GetVolumeInformation('D:\', Buffer, SizeOf(Buffer), @SerialNum, a, b, nil, 0);
Edit1.Text:=inttohex(SerialNum,8);
end;
SN:DWORD;//磁盘序列号
ML:DWORD;
FSF:DWORD;
Key:string[8];
begin
GetVolumeInformation(PChar('C:\'),nil,0,@SN,ML,FSF,nil,0);
Key:=IntToHex((SN),8);
end;