Mammad Khafan
کاربر تازه وارد
- تاریخ عضویت
- 9 ژوئن 2004
- نوشتهها
- 5
- لایکها
- 0
مي خواستم بدونم چطوري ميشه يه مشخصه اي كه براي هر كامپيوتر منحصر به فرد باشه رو از طريق C بخونم
Public Declare Function GetVolumeInformation& Lib "kernel32" _
Alias "GetVolumeInformationA" (ByVal lpRootPathName _
As String, ByVal pVolumeNameBuffer As String, ByVal _
nVolumeNameSize As Long, lpVolumeSerialNumber As Long, _
lpMaximumComponentLength As Long, lpFileSystemFlags As _
Long, ByVal lpFileSystemNameBuffer As String, ByVal _
nFileSystemNameSize As Long)
#include <stdio.h>
//Written By : F0ruD
//No waranty at all!!!
struct cpuid_struct
{
unsigned long id0;
unsigned long id1;
unsigned long id2;
unsigned long id3;
};
inline cpuid_struct getCPUID(unsigned long func_idx)
{
cpuid_struct id;
__asm{
mov eax, func_idx
cpuid
mov id.id0, eax
mov id.id1, ebx
mov id.id2, ecx
mov id.id3, edx
}
return id;
}
void main()
{
for(int j=0; j<2; j++)
{
for(int i=0; i<4; i++)
{
unsigned long k=i+(j?0x80000000:0);
cpuid_struct id=getCPUID(k);
printf("your CPU id is: [0x%xH]%x-%x-%x-%x\n", k, id.id0, id.id1, id.id2, id.id3);
}
}
}
قربون مرامت همون دلفي رو واسمون بفرست كارمون رو راه ميندازه.به نقل از littlerabbit :اين كه مختص سخت افزار نيست! با هر فرمت عوض ميشه. ميتوني از دستور CPUID استفاده کنی. این دستور شماره سی پی یو رو تو eax و ebx و ecx میذاره. من دلفیشو زیاد استفاده میکنم. اگه دلفی بکارت میاد بنویسمش؟
به نقل از cracki :جواب منم بده
يه دستور بگو كه به فورمت بستگي نداشته باشه و مستقل به هارد باشه
من منتظرم
unit Unit2;
{
Author : F0ruD
}
interface
uses
Windows,SysUtils;
type
TSerialNumber = String;
THDDResult = record
HDDSerial : TSerialNumber;
HDDRevision : TSerialNumber;
HDDModel : TSerialNumber;
end;
function GetIdeSerialNumber : THDDResult;
implementation
// Get first IDE harddisk serial number
function GetIdeSerialNumber : THDDResult;
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
// Error code from driver, or 0 if no error.
bDriverError : Byte;
// Contents of IDE Error register.
// Only valid when bDriverError is SMART_IDE_ERROR.
bIDEStatus : Byte;
bReserved : Array[0..1] of Byte;
dwReserved : Array[0..1] of DWORD;
end;
TSendCmdOutParams = packed record
// Size of bBuffer in bytes
cBufferSize : DWORD;
// Driver status structure.
DriverStatus : TDriverStatus;
// Buffer of arbitrary length in which to store the data read from the drive.
bBuffer : Array[0..0] of BYTE;
end;
var hDevice : THandle;
cbBytesReturned : DWORD;
// ptr : PChar;
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;
var
Tmp : TIdSector;
Res : array [0..40] of Char;
begin
// Result := ''; // return empty string on error
if SysUtils.Win32Platform=VER_PLATFORM_WIN32_NT then // WinNT, Win2000
begin
// warning! change name for other drives:
// ex.: second drive '\\.\PhysicalDrive1\'
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;
// 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;
Tmp:=PIdSector(@IdOutCmd.bBuffer)^;
with Tmp do
begin
ChangeByteOrder( sSerialNumber, SizeOf(sSerialNumber) );
ChangeByteOrder( sFirmwareRev ,SizeOf(sFirmwareRev) );
ChangeByteOrder( sModelNumber , SizeOf(sModelNumber) );
// (PChar(@sSerialNumber)+SizeOf(sSerialNumber))^ := #0;
// (PChar(@sFirmwareRev)+SizeOf(sFirmwareRev))^:=#0;
// (PChar(@sModelNumber)+ SizeOf(sModelNumber))^:=#0;
FillChar(Res,sizeof(Res),0);
StrLCopy(Res,PChar(@sSerialNumber),SizeOf(sSerialNumber));
Result.HDDSerial:=Trim(Res);
FillChar(Res,sizeof(Res),0);
StrLCopy(Res,PChar(@sFirmwareRev),SizeOf(sFirmwareRev));
Result.HDDRevision:=Trim(Res);
FillChar(Res,sizeof(Res),0);
StrLCopy(Res,PChar(@sModelNumber),SizeOf(sModelNumber));
Result.HDDModel:=Trim(Res);
// Result := PChar(@sSerialNumber);
end;
end;
end.
unit fMain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, AppEvnts;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
procedure CustomHint1ShowHint(var HintStr: String;
var CanShow: Boolean; var HintInfo: THintInfo);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
ID_BIT = $200000; // EFLAGS ID bit
type
TCPUID = array[1..4] of Longint;
TVendor = array [0..11] of char;
function IsCPUID_Available : Boolean;
asm
MOV Result,False {Set initial result to false}
PUSHFD {direct access to flags no possible, only via stack}
POP EAX {flags to EAX}
MOV EDX,EAX {save current flags}
XOR EAX,ID_BIT {not ID bit}
PUSH EAX {onto stack}
POPFD {from stack to flags, with not ID bit}
PUSHFD {back to stack}
POP EAX {get back to EAX}
XOR EAX,EDX {check if ID bit affected}
JZ @exit {no, CPUID not availavle}
MOV Result,True {Result=True}
@exit:
end;
function GetCPUID(Index : Integer) : TCPUID;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,Result {Move result to EDI}
MOV EAX,Index
DW $A20F {CPUID Command we can use CPUID}
STOSD {CPUID[1]}
MOV EAX,EBX
STOSD {CPUID[2]}
MOV EAX,ECX
STOSD {CPUID[3]}
MOV EAX,EDX
STOSD {CPUID[4]}
POP EDI {Restore registers}
POP EBX
end;
function GetCPUVendor : TVendor;
asm
PUSH EBX {Save affected register}
PUSH EDI
MOV EDI,Result {@Result (TVendor)}
MOV EAX,0
DW $A20F {CPUID Command}
MOV EAX,EBX
XCHG EBX,ECX {save ECX result}
MOV ECX,4
@1:
STOSB
SHR EAX,8
LOOP @1
MOV EAX,EDX
MOV ECX,4
@2:
STOSB
SHR EAX,8
LOOP @2
MOV EAX,EBX
MOV ECX,4
@3:
STOSB
SHR EAX,8
LOOP @3
POP EDI {Restore registers}
POP EBX
end;
procedure TForm1.FormCreate(Sender: TObject);
var
S : TCPUID;
I : Cardinal;
begin
Memo1.Clear;
if IsCPUID_Available then begin
for I:=0 to 3 do begin
S:=GetCPUID(I);
Memo1.Lines.Add(Format('%x-%x-%x-%x',[S[1],S[2],S[3],S[4]]));
end;
for I:=$80000000 to $80000003 do begin
S:=GetCPUID(I);
Memo1.Lines.Add(Format('%x-%x-%x-%x',[S[1],S[2],S[3],S[4]]));
end;
Memo1.Lines.Add(GetCPUVendor)
end
else
Memo1.Lines.Add('CPUID Not available')
end;
Private Declare Function GetVolumeInformation Lib "kernel32.dll" Alias "GetVolumeInformationA" (ByVal lpRootPathName As String, ByVal lpVolumeNameBuffer As String, ByVal nVolumeNameSize As Integer, lpVolumeSerialNumber As Long, lpMaximumComponentLength As Long, lpFileSystemFlags As Long, ByVal lpFileSystemNameBuffer As String, ByVal nFileSystemNameSize As Long) As Long
Private Sub Command1_Click()
Dim objs
Dim obj
Dim WMI
Set WMI = GetObject("WinMgmts:")
Set objs = WMI.InstancesOf("Win32_BaseBoard")
For Each obj In objs
Label2.Caption = "MotherBoard Num: " & obj.SerialNumber
Next
Label1.Caption = "HDD Serial Num: " & GetSerialNumber("C:\")
End Sub
Function GetSerialNumber(strDrive As String) As Long
Dim SerialNum As Long
Dim Res As Long
Dim Temp1 As String
Dim Temp2 As String
Temp1 = String$(255, Chr$(0))
Temp2 = String$(255, Chr$(0))
Res = GetVolumeInformation(strDrive, Temp1, Len(Temp1), SerialNum, 0, 0, Temp2, Len(Temp2))
GetSerialNumber = SerialNum
End Function
ما هم درباره سريال CPU حرفي نزديم. در ضمن وقتي ميشه سريال مادربرد رو با دو تا خط VB درآورد چه نيازي به نوشتن اسمبلي يا يه DLL ديگه براي گرفتن سریال CPU هست؟به نقل از littlerabbit :شما اصلا سزی به بخش مقالات زدید؟؟؟ اونجا نوشتم. برای گرفتن شماره CPU نیاز به اسمبلی هست. اما وی بی نمیتونه میتونید با دلفی به صورت دی ال ال بنویسید و تو وی بی فراخوانی کنید
چون اينجا به مباحث VB مربوط میشه من هم کد VB نوشتم اگه هم مجبور به گرفتن سریال CPU بشم این کار رو با دلفی نمیکنم چون اصلا نمیدونم چی هست.به نقل از Niloufar :سلام
آقا مصطفي (يا به قول فرود: آقاي آرنولد)، ما كه كد شما را نوشتيم و اجرا كرديم ولي هيچ چي به عنوان سريال مادربورد برنگردوند (البته باور كنيد كه كامپيوترم مادربورد داره )
در مورد CPU يا هر چيز ديگه هم بالاخره بودنش بهتر از نبودنشه و اگه بشه آدم چند تا سريال رو بگيره بهتر از اينه كه يه سريال رو بگيره (از لحاظ امنيتي بهتره)، تازه اگه آدم مطمئن باشه كه اونايي كه داره رو همه سيستم ها جواب ميده (نه مثل اين كد كه همين الان رو مادربورد من كه جواب نداد، بقيه رو نميدونم)
در مورد شماره هارد هم بايد اونا افراد مختلف، روي هاردهاي مختلف آزمايش كنند و نتيجه رو اينجا بذارند تا ببينيم چقدر ميشه بهش اعتماد كرد (خصوصا روي هارد ساتا و همينطور خصوصا اگه هارد رو در حالت هاي مختلف Master و Slave و Primary و ... تست كنيم. ضمن اينكه اگه پارتيشن بندي تغيير كنه هم بايد جواب بده). اگه دوستان نتيجه هايشونو اينجا بذارند ممنون ميشم.
آقا فرود هم اگه بتونند در مورد CPU يا هر سخت افزار به درد بخور ديگه اي كمك كنند (البته اگه رو همه حتي AMD يا روي NoteBook هم جواب بده) ممنون ميشم. (البته نگي كه بخش مقالات را نخوندي، خوندم ولي اولا هر چي داشتي واسه سي يا دلفي بود و ثانيا معلوم نكرده بودي كه حيطه كاركردن آن چقدر است (البته غير از اينكه گفته بودي CPU براي قديمي ها كار نميكنه).
ساير دوستان هم اگه ايده اي دارند بگن تا ببينيم به كجا ميرسيم.
خلاصه اگه هر كي هر چي داره اينجا بريزه تا همه دوستان (كه مطمئنا هر كي يه نوع سخت افزار داره) اونا رو تست كنند و جواب بدند تا بتونيم يه چيز خوب و همه جا كار كن گير بياريم. (فكر كنم به درد همه بخوره)
ممنون