Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.11;
Скачать: CL | DM;

Вниз

Определение серийного номера материнской платы   Найти похожие ветки 

 
M@Rt   (2004-02-02 17:38) [0]

Подскажите как можно определить серийный номер материнской платы для 9х/w2k/XP, очень бы хотелось с примером.


 
DC-AC   (2004-02-03 07:50) [1]

M@Rt : а ты уверен, что у твоей MB он есть ? Найди в инете какой-нибудь софт (хоть Sandra, хоть любой SMBUS-монитор), который тебе его покажет. Вот тогда и поговорим дальше.


 
M@Rt   (2004-02-03 11:31) [2]

А разве при загрузке Биос не выдает дату биоса и серийный номер?


 
Anatoly Podgoretsky ©   (2004-02-03 11:38) [3]

Дату выдает, а серийный номер не выдает, поскольку нечего выдавать. Только два или три производителя материнских плат поддерживают серийный номер, это Dell, Compaq и еще кто то.


 
M@Rt   (2004-02-03 11:46) [4]

DC-AC, Anatoly Podgoretsky
Спасибо за объяснение, тогда может подскажите что кроме харда имеет обязательно серийный номер который вшит внутрь железеза, и который можно прочитать (например видеокарта) И как можно прочитать этот серийный номер (желательно не через реестр).


 
alexey_ar   (2004-02-03 13:54) [5]

А вот не надо ля-ля, я не видел ни одной матери со времен 386, которая бы при показе заставки биоса (там где список IDE-устройств, инфа о протзводителе биоса и тест памяти) не выводила в нижней строке надписи
"Press <...> to enter bios"
"yy//mm//dd-**********"
где ***** - это строчка из ~10 букв и цифр, которую я одинаковой у двух компов не видел. Давайте эту строчку назовем условно серийником матери (биоса?).
Внимание, вопрос! Эту строчку на любой матери в любой операционке (95/NT) выводит aida32 и некоторые другие проги. Хочется уметь считывать ее для лицензирования проги. Известно, что под Win95/98/ME ее можно получить просто строчкой как PChar($FEC71). КАК ПОЛУЧИТЬ ЭТУ СТРОЧКУ - СЕРИЙНИК МАТЕРИ (БИОСА?) ИЗ ПОД WIN2000/XP?


 
NightAngel ©   (2004-02-03 15:12) [6]

> КАК ПОЛУЧИТЬ ЭТУ СТРОЧКУ - СЕРИЙНИК МАТЕРИ (БИОСА?)


unit GetBiosInformation;

interface

uses windows, Sysutils;

type
 PRomBiosDump = ^TRomBiosDump;
 TRomBiosDump = array [$000F0000..$000FFFFF] of Byte;

type
 TReadRomBiosMethod = (
   rrbmAutomatic,
   rrbmGeneric,
   rrbmMemory,
   rrbmPhysical
 );

type
 NTSTATUS = Integer;

type
 PUnicodeString = ^TUnicodeString;
 TUnicodeString = packed record
   Length: Word;
   MaximumLength: Word;
   Buffer: PWideChar;
 end;

type
 PObjectAttributes = ^TObjectAttributes;
 TObjectAttributes = record
   Length: ULONG;
   RootDirectory: THandle;
   ObjectName: PUnicodeString;
   Attributes: ULONG;
   SecurityDescriptor: PSecurityDescriptor;
   SecurityQualityOfService: PSecurityQualityOfService;
 end;

type
 TFNZwOpenSection = function(out SectionHandle: THandle;
   DesiredAccess: ACCESS_MASK; ObjectAttributes: PObjectAttributes):
NTSTATUS;
   stdcall;
 TFNRtlNtStatusToDosError = function(Status: NTSTATUS): DWORD; stdcall;

type
 PRomDumpCodeInfo = ^TRomDumpCodeInfo;
 TRomDumpCodeInfo = (rdciStart, rdciEnd, rdciSize);

const
 STATUS_SUCCESS = NTSTATUS(0);
 STATUS_INVALID_HANDLE = NTSTATUS($C0000008);
 STATUS_ACCESS_DENIED = NTSTATUS($C0000022);

 RomBiosDateOffset = Pointer($000FFFF5);
 RomBiosNameOffset = Pointer($000FE061);
 RomBiosCopyrightOffset = Pointer($000FE091);
 RomBiosIdOffset = Pointer($000FEC71);

 OBJ_INHERIT = $00000002;
 OBJ_PERMANENT = $00000010;
 OBJ_EXCLUSIVE = $00000020;
 OBJ_CASE_INSENSITIVE = $00000040;
 OBJ_OPENIF = $00000080;
 OBJ_OPENLINK = $00000100;
 OBJ_KERNEL_HANDLE = $00000200;
 OBJ_VALID_ATTRIBUTES = $000003F2;

 ObjectPhysicalMemoryDeviceName = "\Device\PhysicalMemory";
 ObjectPhysicalMemoryName: TUnicodeString = (
   Length: Length(ObjectPhysicalMemoryDeviceName) * 2;
   MaximumLength: Length(ObjectPhysicalMemoryDeviceName) * 2 + 2;
   Buffer: ObjectPhysicalMemoryDeviceName;
 );
 ObjectPhysicalMemoryAccessMask: ACCESS_MASK = SECTION_MAP_READ;
 ObjectPhysicalMemoryAttributes: TObjectAttributes =(
   Length: SizeOf(TObjectAttributes);
   RootDirectory: 0;
   ObjectName: @ObjectPhysicalMemoryName;
   Attributes: OBJ_CASE_INSENSITIVE;
   SecurityDescriptor: nil;
   SecurityQualityOfService: nil;
 );

 ntdll = "ntdll.dll";

var
 ZwOpenSection: TFNZwOpenSection;
 RtlNtStatusToDosError: TFNRtlNtStatusToDosError;

function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;
 Timeout: DWORD = INFINITE): Boolean;
function ReadRomBios9x(var Buffer: TRomBiosDump): Boolean;
function ReadRomBios16(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
function ReadRomBiosNt(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
function DirectoryExists(const Dir: string): Boolean;
function _RomDumpCodeToFile(const Filename: string): Boolean;
function _RomDumpCodeExecute(const Com, Dmp: string; Timeout: DWORD):
Boolean;
function _RomDumpCode(Info: TRomDumpCodeInfo): Pointer;
function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer):
string;


 
NightAngel ©   (2004-02-03 15:13) [7]

implementation

function ReadRomBios(var Dump: TRomBiosDump; Method: TReadRomBiosMethod;
 Timeout: DWORD = INFINITE): Boolean;
begin
 Result := False;
 case Method of
   rrbmAutomatic:
     if (Integer(GetVersion) < 0) then
     try
       Result := ReadRomBios9x(Dump);
     except
       Result := ReadRomBios16(Dump, Timeout);
     end
     else
       Result := ReadRomBiosNt(Dump, Timeout);
   rrbmGeneric:
     Result := ReadRomBios16(Dump, Timeout);
   rrbmMemory:
     Result := ReadRomBios9x(Dump);
   rrbmPhysical:
     Result := ReadRomBiosNt(Dump, Timeout);
 else
   SetLastError(ERROR_INVALID_PARAMETER);
 end;
end;

function ReadRomBios9x(var Buffer: TRomBiosDump): Boolean;
begin
 Result := False;
 try
   FillChar(Buffer, SizeOf(TRomBiosDump), 0);
   Move(Pointer(Low(TRomBiosDump))^, Buffer, SizeOf(TRomBiosDump));
   Result := True;
 except
 end
end;

function ReadRomBios16(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
const
 TempSub = "~RomDmp";
 ComName = "RomDump.com";
 DmpName = "Rom.dmp";
var
 TempPath: string;
 TempDir: string;
 TempIdx: Integer;
 TempIdxStr: string;
 ComFile: string;
 DmpFile: string;
 DmpHandle: THandle;
 Written: DWORD;
begin
 Result := False;
 SetLength(TempPath, MAX_PATH);
 SetLength(TempPath, GetTempPath(MAX_PATH, PChar(@TempPath[1])));
 if Length(TempPath) > 0 then
 begin
   if (TempPath[Length(TempPath)] <> "\") then
     TempPath := TempPath + "\";
   TempIdx := 0;
   repeat
     Inc(TempIdx);
     Str(TempIdx, TempIdxStr);
     TempDir := TempPath + TempSub + TempIdxStr;
   until not DirectoryExists(TempDir);
   if CreateDirectory(PChar(TempDir), nil) then
   try
     TempDir := TempDir + "\";
     ComFile := TempDir + ComName;
     DmpFile := TempDir + DmpName;
     if _RomDumpCodeToFile(ComFile) then
     try
       if _RomDumpCodeExecute(ComFile, DmpFile, Timeout) then
       begin
         DmpHandle := CreateFile(PChar(DmpFile), GENERIC_READ,
           FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
         if DmpHandle <> INVALID_HANDLE_VALUE then
         try
           FillChar(Buffer, SizeOf(TRomBiosDump), 0);
           Result := ReadFile(DmpHandle, Buffer, SizeOf(TRomBiosDump),
             Written, nil) and (Written = SizeOf(TRomBiosDump));
         finally
           CloseHandle(DmpHandle);
         end;
       end;
     finally
       DeleteFile(PChar(DmpFile));
       DeleteFile(PChar(ComFile));
     end;
   finally
     RemoveDirectory(PChar(TempDir));
   end;
 end;
end;

function ReadRomBiosNt(var Buffer: TRomBiosDump; Timeout: DWORD): Boolean;
var
 NtLayer: HMODULE;
 Status: NTSTATUS;
 Section: THandle;
 View: Pointer;
begin
 Result := False;
 NtLayer := GetModuleHandle(ntdll);
 if NtLayer = 0 then
   SetLastError(ERROR_CALL_NOT_IMPLEMENTED)
 else
 begin
   if not Assigned(ZwOpenSection) then
     ZwOpenSection := GetProcAddress(NtLayer, "ZwOpenSection");
   if not Assigned(RtlNtStatusToDosError) then
     RtlNtStatusToDosError := GetProcAddress(NtLayer,
"RtlNtStatusToDosError");
   if not (Assigned(ZwOpenSection) and
Assigned(RtlNtStatusToDosError)) then
     SetLastError(ERROR_CALL_NOT_IMPLEMENTED)
   else
   begin
     Status := ZwOpenSection(Section, ObjectPhysicalMemoryAccessMask,
       @ObjectPhysicalMemoryAttributes);
     case Status of
       STATUS_SUCCESS:
         try
           View := MapViewOfFile(Section,
ObjectPhysicalMemoryAccessMask, 0,
             Low(TRomBiosDump), SizeOf(TRomBiosDump));
           if Assigned(View) then
           try
             FillChar(Buffer, SizeOf(TRomBiosDump), 0);
             Move(View^, Buffer, SizeOf(TRomBiosDump));
             Result := True;
           finally
             UnmapViewOfFile(View);
           end;
         finally
           CloseHandle(Section);
         end;
       STATUS_ACCESS_DENIED:
         Result := ReadRomBios16(Buffer, Timeout);
     else
       SetLastError(RtlNtStatusToDosError(Status))
     end;
   end;
 end;
end;

function DirectoryExists(const Dir: string): Boolean;
var
 Attr: DWORD;
begin
 Attr := GetFileAttributes(PChar(Dir));
 Result := (Attr <> $FFFFFFFF) and
   (Attr and FILE_ATTRIBUTE_DIRECTORY = FILE_ATTRIBUTE_DIRECTORY);
end;

function _RomDumpCodeToFile(const Filename: string): Boolean;
var
 ComFile: THandle;
 Size: Cardinal;
begin
 Result := False;
 ComFile := CreateFile(PChar(Filename), GENERIC_WRITE,
FILE_SHARE_READ, nil,
   CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
 if ComFile <> INVALID_HANDLE_VALUE then
 try
   Result := WriteFile(ComFile, _RomDumpCode(rdciStart)^,
     Cardinal(_RomDumpCode(rdciSize)), Size, nil) and
     (Size = Cardinal(_RomDumpCode(rdciSize)));
   if not Result then
     DeleteFile(PChar(Filename));
 finally
   CloseHandle(ComFile);
 end;
end;

function _RomDumpCodeExecute(const Com, Dmp: string; Timeout: DWORD):
Boolean;
var
 ComSpec: string;
 si: TStartupInfo;
 pi: TProcessInformation;
begin
 Result := False;
 SetLength(ComSpec, MAX_PATH);
 SetLength(ComSpec,
   GetEnvironmentVariable("ComSpec", PChar(@ComSpec[1]), MAX_PATH));
 if Length(ComSpec) > 0 then
 begin
   FillChar(si, SizeOf(TStartupInfo), 0);
   si.cb := SizeOf(TStartupInfo);
   si.dwFlags := STARTF_USESHOWWINDOW;
   si.wShowWindow := SW_HIDE;
   if CreateProcess(nil, PChar(ComSpec + " /C " + Com + " > " + Dmp),
     nil, nil, False, CREATE_NEW_CONSOLE or CREATE_NEW_PROCESS_GROUP, nil,
     nil, si, pi) then
   try
     Result := WaitForSingleObject(pi.hProcess, Timeout) <> WAIT_TIMEOUT;
   finally
     CloseHandle(pi.hProcess);
     CloseHandle(pi.hThread);
   end;
 end;
end;

function _RomDumpCode(Info: TRomDumpCodeInfo): Pointer;
var
 CodeStart: Pointer;
 CodeEnd: Pointer;
begin
 asm
         JMP @@End

 @@Start:
         XOR eDX, eDX
         MOV DH, 0F0h
         MOV DS, eDX
         XOR eDX, eDX
         XOR eCX, eCX
         DEC eCX
         XOR eBX, eBX
         INC eBX
         MOV AH, 40h
         INT 21h
         JC @@Exit
         XOR eDX, eDX
         MOV DH, 0F0h
         MOV DS, eDX
         XOR eDX, eDX
         DEC eDX
         XOR eCX, eCX
         INC eCX
         MOV eBX, eCX
         MOV AH, 40
         INT 21h
         JC @@Exit
         MOV AL, 0
 @@Exit:
         MOV AH, 4Ch
         INT 21h
 @@End:

         MOV CodeStart, OFFSET @@Start
         MOV CodeEnd, OFFSET @@End
 end;
 case Info of
   rdciStart:
     Result := CodeStart;
   rdciEnd:
     Result := CodeEnd;
   rdciSize:
     Result := Pointer(Cardinal(CodeEnd) - Cardinal(CodeStart));
 else
   Result := nil;
 end;
end;

function GetRomBiosString(const Dump: TRomBiosDump; Address: Pointer):
string;
begin
 Result := "";
 if (Cardinal(Address) >= Low(TRomBiosDump)) and
   (Cardinal(Address) <= High(TRomBiosDump)) then
   Result := string(PChar(@Dump[Cardinal(Address)]));
end;

end.


 
M@Rt   (2004-02-03 18:13) [8]

NightAngel
Извини конечно, но ещё один вопрос, а как эту инфу вывести в файлик, именно нужные переменные, я пока что не понял в какой переменной окажется серийник материнки (точнее биоса)


 
DeadMeat ©   (2004-02-03 19:22) [9]

> [8] M@Rt   (03.02.04 18:13)
А может тебе ещё рано этим заниматься... Лучше возми готовые компоненты, если хочешь защитить свою прогу от копирования... Поищи на Torry, обязательно чего-нибудь наёдешь...


 
DC-AC   (2004-02-04 08:13) [10]

alexey_ar  : это т.н. BIOS Extended Info. У двух одинаковых MB (можешь мне поверить, я проверял на участке сборки компов на старой работе) эти строчки АБСОЛЮТНО одинаковы !


 
M@Rt   (2004-02-04 10:23) [11]

DeadMeat
Скорей всего что рано, просто это надо не для защиты программы а для создания уникального номера на основе данных о компьютере, может есть у кого то более удачные идеи,то подскажите в каком направлении копать.


 
Alex Konshin ©   (2004-02-04 10:32) [12]

MAC Address сетевой платы?


 
M@Rt   (2004-02-04 11:14) [13]

а если у человека нет сетевой карты?


 
Alex Konshin ©   (2004-02-04 11:25) [14]

А если нет винчестера?


 
M@Rt   (2004-02-04 14:28) [15]

Подскажите тогда хотя бы где в реестре хранится серийный номер видеокарты


 
DC-AC   (2004-02-04 15:21) [16]

Если он и где-нибудь есть (в чипе, видеобиосе, etc), то с вероятностью 99%, что его нельзя получить программно без обращения к производителю оборудования.
Название видеокарты - можно.
function GetVideoVendor: String;
var lpDisplayDevice: TDisplayDevice;
begin
lpDisplayDevice.cb := Sizeof(lpDisplayDevice);
EnumDisplayDevices(nil, 0, lpDisplayDevice , 0);
Result:=lpDisplayDevice.DeviceString;
end;
Так пойдёт ?


 
M@Rt   (2004-02-04 16:46) [17]

DC-AC
Спасибо



Страницы: 1 вся ветка

Текущий архив: 2004.04.11;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.088 c
3-1079423613
Лысый
2004-03-16 10:53
2004.04.11
SQL


8-1069869678
Михайлов Антон
2003-11-26 21:01
2004.04.11
TV Capture Card


1-1079971378
Алексейй
2004-03-22 19:02
2004.04.11
Эта загадочная клавиша "Home"


14-1079589762
able
2004-03-18 09:02
2004.04.11
LPT - порт


14-1079286422
Kamerad
2004-03-14 20:47
2004.04.11
HELP!