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

Вниз

Как узнать уникальный номер (ID) чего либо из железа на компе?   Найти похожие ветки 

 
truvor ©   (2005-10-16 02:28) [0]

Помогите пожалуйста узнать уникальный номер какого либо железа на компе, желательно такого которое 100% есть у каждого, например винта.

Убедительная просьба не задавть глупых вопросов - а зачем, а почему, и вообще лучше сделать вот так и вот так. А написать тем кто действительно может помочь.

Заранее спасибо.


 
неважно   (2005-10-16 02:39) [1]

GetVolumeInformation


 
truvor ©   (2005-10-16 02:48) [2]

Агромное спасибо-) А еще бы если б кто подсказал теперь как получить аналогичный серийник от мамки моя радость вообще не имела бы границ,
как и моя благодарность-)


 
неважно   (2005-10-16 02:56) [3]

> аналогичный серийник от мамки
Нет такого. Обсуждалось в сием форуме не раз.

З.Ы.Хотя...можно,но только нужно качнуть SDK на Вашу мать.  И,кстати,не факт,что он там обязан быть!


 
неважно   (2005-10-16 03:00) [4]

Уж лучше смотри дату установки системы.
З.Ы. У Керка на форуме есть пример получения различной информации(в т.ч. настоящего серийного номера винта. Ибо GetVolumeInformation бред.После смены ОС он будет показывать др.номер)


 
truvor ©   (2005-10-16 03:07) [5]

А от чего еще теоретически можно получить серийник из общеустановленного железа? например от видюхи. Я сейчас лажу по форуму, пока не нашел прямого ответа...

Кстати, вот если в качестве защиты программы не использовать никаких серийников - паролей к ним, а только взять какой нибудь из доступных hardware id и просто прописать сей id на сервере и чтоб программа постоянно обращалась к серваку через сокеты, на предмет наличия в базе данных такого ID а сервер в ответ присылал бы страницу билиберды, из которой я брал бы например 5, 107, 94 байты и смотря на них определял есть ли ID в базе. Насколько такая защита надежна? НУ естественно осложнить жизнь хацкерам сделать не один запрос к серверу, а допустим 5 однотипных, но разных по коду, чтобы дизасемблить и ломать сложнее было.

Кто нибудь сталкивался???


 
truvor ©   (2005-10-16 03:09) [6]


> З.Ы. У Керка на форуме есть пример получения различной информации(в
> т.ч. настоящего серийного номера винта. Ибо GetVolumeInformation
> бред.После смены ОС он будет показывать др.номер)

Так мне не жалко. Ни хай. Пусть другой показывает. Я зареганным юзерам дам возможность скажем раз в неделю менять этот самый ID на сервере автоматически без моего участия.

А адрес "У керка" не дадите, пожалуйста???


 
неважно   (2005-10-16 03:30) [7]

http://kladovka.net.ru


 
Германн ©   (2005-10-16 03:34) [8]

Всё, что можно узнать, есть у Alex Konshin.
Остальное, имхо от лукавого!


 
truvor ©   (2005-10-16 03:34) [9]

Спасибо!


 
неважно   (2005-10-16 03:44) [10]

2 truvor
Германн прав. Вот ссылка :http://home.earthlink.net/~akonshin/delphi_ru.htm. А в кладовке оказывается тоже GetVolumeInformation :(


 
truvor ©   (2005-10-16 04:00) [11]


> Германн прав. Вот ссылка :http://home.earthlink.net/~akonshin/delphi_ru.
> htm. А в кладовке оказывается тоже GetVolumeInformation
> :(

Ага я там тоже только GetVolumeInformation нашел.

Вторую ссылку тоже нашел уже. Только там получение информации
об ide только а если scsi, а не scsi-2 у юзера будет? А даже если и scsi-2 все равно там только для 2000 и NT... Так что это не катит... Ладно, бог с ним, воспользуюсь  GetVolumeInformation... Но если кто нибудь предложит более универсальный метод буду очень признателен.

Спасибо всем за советы!!!


 
Alex Konshin ©   (2005-10-16 09:34) [12]

SCSI-2 это стандарт и я очень сильно соневаюсь, что у пользователя будет что-то другое.
Да, код для SCSI приведен только для NT/2K/XP, потому как под Windows 95 нет SPTI, но есть ASPI и при желании можно найти примеры и для него. На самом деле с SCSI есть более важная проблема: этот код не будет работать не под администратором, если не делать специальных действий. Что касается ASPI, то там есть еще и сложность в том, что этот API не поддерживается Microsoft.

Для IDE этих проблем нет. Хотя могут быть заморочки с SMART API под Windows 95/98/ME, если винчестер не мастер на первом контроллере. Это можно обойти через другой драйвер, есть у меня и такой вариант. Хотя я не напрягался этими проблемами на Windows 9x, потому что меня лично это не интересует.


 
isasa ©   (2005-10-16 10:03) [13]

уникальный номер какого либо железа на компе,
У машин в сети - ты его не видишь, а он есть.
MAC-адрес, но не 100% у всех :)


 
Anatoly Podgoretsky ©   (2005-10-16 12:09) [14]

truvor ©   (16.10.05 02:28)  
Напримере "винта" есть не у всех


 
Anatoly Podgoretsky ©   (2005-10-16 12:10) [15]

truvor ©   (16.10.05 02:48) [2]
Нужно большое везение (точнее нужны деньги) чтобы заиметь тоже самое у "мамки"


 
Anatoly Podgoretsky ©   (2005-10-16 12:14) [16]

Судя по обсуждению программа какая то гиганстукая с таким же ареалом распространения и при этом жалко 100 долларов на профессиональную защиту.


 
qwerty2k3   (2005-10-16 15:16) [17]


> Anatoly Podgoretsky ©   (16.10.05 12:14) [16]
> жалко 100 долларов  на профессиональную защиту.


А можно ссылку на пример проф.защиты за $100?


 
Anatoly Podgoretsky ©   (2005-10-16 15:18) [18]

ASPROTECT


 
qwerty2k3   (2005-10-16 15:35) [19]


> Anatoly Podgoretsky ©   (16.10.05 15:18) [18]


Запустил поиск по ASPROTECT и >50% ссылок ведут на подробные рассказы как и при помощи чего снимается эта защита.


 
truvor ©   (2005-10-16 16:28) [20]

Не, ну вот странные люди...

Всем кто помог советом спасибо, а всем
кто сказал что нет денег - даже не знаю чего.

С чего вы взяли что денег нету??? Деньги есть. И чем любая другая система профессиональнее моей будет? Тем что ее 20 человек писало?
Так они и писали ее для всех... И все давно поломано...

Но мне нужна собственная система защиты, в силу многих обстоятельств.
Ждать пока кто то напишет нет времени. Использовать уже готовые - все поломаны, а это уже есть методология полная защиты разработанная,
все написано, осталось только взять любой уникальный номер.

Даже готова версия которая работает с сетевой картой, т.к. у них у всех реально уникальные ID. Только вот маленький трабл - не у всех она есть 100% а это не устраивает.


 
GanibalLector ©   (2005-10-17 00:15) [21]

2 truvor ©   (16.10.05 16:28) [20]
Посмотрите еще раз [4]. Уж это на 100%. Я про дату ;)


 
Alex Konshin ©   (2005-10-17 02:01) [22]

Дата установки системы и VolumeID отлично копируются при клонировании дисков, что в больших конторах делается, я бы сказал, уже как правило, т.е. на партию компьюторов с одинаковой конфигурацией система вместе с приложениями устанавливается уже простым клонированием диска.
Можно доставать SID компьютера, он должен быть уникальным в локальной сети и вроде как системы клонирования должны каждый раз генерировать новый SID. По крайней мере эта проблема обсуждается где-то на http://www.sysinternals.com/
Кстати, там же есть программка для смены VolumeID - это к сведению тем, кто любит привязываться к нему.


 
Gydvin ©   (2005-10-17 06:51) [23]

GetVolumeInformation
Бред сивой кобылы.

Вот есть два метода но я их точно непроверял насколько они рабочие

Вот здесь обещают, что получишь серийный номер процесора!!!

unit Main;

interface

uses
 Windows,
 Messages,
 SysUtils,
 Classes,
 Graphics,
 Controls,
 Forms,
 Dialogs,
 ExtCtrls,
 StdCtrls,
 Buttons;

type
 TDemoForm = class(TForm)
   Label1: TLabel;
   Label2: TLabel;
   Label3: TLabel;
   Label4: TLabel;
   GetButton: TBitBtn;
   CloseButton: TBitBtn;
   Bevel1: TBevel;
   Label5: TLabel;
   FLabel: TLabel;
   MLabel: TLabel;
   PLabel: TLabel;
   SLabel: TLabel;
   PValue: TLabel;
   FValue: TLabel;
   MValue: TLabel;
   SValue: TLabel;
   procedure GetButtonClick(Sender: TObject);
 end;
var
 DemoForm: TDemoForm;

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; register;
asm
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     AL,True   {Result=True}
@exit:
end;

function GetCPUID : TCPUID; assembler; register;
asm
 PUSH    EBX         {Save affected register}
 PUSH    EDI
 MOV     EDI,EAX     {@Resukt}
 MOV     EAX,1
 DW      $A20F       {CPUID Command}
 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; assembler; register;
asm
 PUSH    EBX     {Save affected register}
 PUSH    EDI
 MOV     EDI,EAX   {@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 TDemoForm.GetButtonClick(Sender: TObject);
var
 CPUID : TCPUID;
 I     : Integer;
 S   : TVendor;
begin
for I := Low(CPUID) to High(CPUID)  do CPUID[I] := -1;
 if IsCPUID_Available then begin
  CPUID := GetCPUID;
  Label1.Caption := "CPUID[1] = " + IntToHex(CPUID[1],8);
  Label2.Caption := "CPUID[2] = " + IntToHex(CPUID[2],8);
  Label3.Caption := "CPUID[3] = " + IntToHex(CPUID[3],8);
  Label4.Caption := "CPUID[4] = " + IntToHex(CPUID[4],8);
  PValue.Caption := IntToStr(CPUID[1] shr 12 and 3);
  FValue.Caption := IntToStr(CPUID[1] shr 8 and $f);
  MValue.Caption := IntToStr(CPUID[1] shr 4 and $f);
  SValue.Caption := IntToStr(CPUID[1] and $f);
  S := GetCPUVendor;
  Label5.Caption := "Vendor: " + S; end
 else begin
  Label5.Caption := "CPUID not available";
 end;
end;

end.


 
Gydvin ©   (2005-10-17 06:52) [24]

А здесь харда.

{ **** UBPFD *********** by delphibase.endimus.com ****
>> Поличение серийного номера IDE диска.

Функция получает серийный номер первого физического диска IDE (не серийный номер тома!).
Используется S.M.A.R.T. API, а под Windows NT/2K/XP запрос производится не напрямую к диску,
а через miniport драйвер контроллера, что позволяет читать серийный номер не имея прав администратора.
Функция может не работать, если первый контролер в системе не ATA или если первое устройство
не является винчестером, который поддерживает SMART (современные винчестеры поддерживают).
Если Вы хотите получить другие параметры диска/других дисков, то смотрите пример IdeInfo2 с моего сайта.
На Windows 9x требует наличия драйвера smartvsd.vxd (должен быть в стандартной поставке),
просто скопируйте его в windowssystemiosubsys и перезагрузите компьютер.

Зависимости: Windows, SysUtils
Автор:       Alex Konshin, akonshin@earthlink.net, Boston, USA
Copyright:   http://home.earthlink.net/~akonshin/index.htm
Дата:        30 декабря 2002 г.
***************************************************** }

function GetIdeDiskSerialNumber: string;
type
 TSrbIoControl = packed record
   HeaderLength: ULONG;
   Signature: array[0..7] of Char;
   Timeout: ULONG;
   ControlCode: ULONG;
   ReturnCode: ULONG;
   Length: ULONG;
 end;
 SRB_IO_CONTROL = TSrbIoControl;
 PSrbIoControl = ^TSrbIoControl;

 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;
 IDEREGS = TIDERegs;
 PIDERegs = ^TIDERegs;

 TSendCmdInParams = packed record
   cBufferSize: DWORD; // Buffer size in bytes
   irDriveRegs: TIDERegs; // Structure with drive register values.
   bDriveNumber: Byte; // Physical drive number to send command to (0,1,2,3).
   bReserved: array[0..2] of Byte; // Reserved for future expansion.
   dwReserved: array[0..3] of DWORD; // For future use.
   bBuffer: array[0..0] of Byte; // Input buffer.
 end;
 SENDCMDINPARAMS = TSendCmdInParams;
 PSendCmdInParams = ^TSendCmdInParams;

 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: ULONG;
   wMultSectorStuff: Word;
   ulTotalAddressableSectors: ULONG;
   wSingleWordDMA: Word;
   wMultiWordDMA: Word;
   bReserved: array[0..127] of Byte;
 end;
 PIdSector = ^TIdSector;

const
 IDE_ID_FUNCTION = $EC;
 IDENTIFY_BUFFER_SIZE = 512;
 DFP_RECEIVE_DRIVE_DATA = $0007C088;
 IOCTL_SCSI_MINIPORT = $0004D008;
 IOCTL_SCSI_MINIPORT_IDENTIFY = $001B0501;
 DataSize = sizeof(TSendCmdInParams) - 1 + IDENTIFY_BUFFER_SIZE;
 BufferSize = SizeOf(SRB_IO_CONTROL) + DataSize;
 W9xBufferSize = IDENTIFY_BUFFER_SIZE + 16;
var
 hDevice: THandle;
 cbBytesReturned: DWORD;
 pInData: PSendCmdInParams;
 pOutData: Pointer; // PSendCmdInParams;
 Buffer: array[0..BufferSize - 1] of Byte;
 srbControl: TSrbIoControl absolute Buffer;

 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 := "";
 FillChar(Buffer, BufferSize, #0);
 if Win32Platform = VER_PLATFORM_WIN32_NT then
 begin // Windows NT, Windows 2000
   // Get SCSI port handle
   hDevice := CreateFile("\.Scsi0:", GENERIC_READ or GENERIC_WRITE,
     FILE_SHARE_READ or FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
   if hDevice = INVALID_HANDLE_VALUE then
     Exit;
   try
     srbControl.HeaderLength := SizeOf(SRB_IO_CONTROL);
     System.Move("SCSIDISK", srbControl.Signature, 8);
     srbControl.Timeout := 2;
     srbControl.Length := DataSize;
     srbControl.ControlCode := IOCTL_SCSI_MINIPORT_IDENTIFY;
     pInData := PSendCmdInParams(PChar(@Buffer) + SizeOf(SRB_IO_CONTROL));
     pOutData := pInData;
     with pInData^ do
     begin
       cBufferSize := IDENTIFY_BUFFER_SIZE;
       bDriveNumber := 0;
       with irDriveRegs do
       begin
         bFeaturesReg := 0;
         bSectorCountReg := 1;
         bSectorNumberReg := 1;
         bCylLowReg := 0;
         bCylHighReg := 0;
         bDriveHeadReg := $A0;
         bCommandReg := IDE_ID_FUNCTION;
       end;
     end;
     if not DeviceIoControl(hDevice, IOCTL_SCSI_MINIPORT, @Buffer,
       BufferSize, @Buffer, BufferSize, cbBytesReturned, nil) then
       Exit;
   finally
     CloseHandle(hDevice);
   end;
 end
 else
 begin // Windows 95 OSR2, Windows 98
   hDevice := CreateFile("\.SMARTVSD", 0, 0, nil, CREATE_NEW, 0, 0);
   if hDevice = INVALID_HANDLE_VALUE then
     Exit;
   try
     pInData := PSendCmdInParams(@Buffer);
     pOutData := PChar(@pInData^.bBuffer);
     with pInData^ do
     begin
       cBufferSize := IDENTIFY_BUFFER_SIZE;
       bDriveNumber := 0;
       with irDriveRegs do
       begin
         bFeaturesReg := 0;
         bSectorCountReg := 1;
         bSectorNumberReg := 1;
         bCylLowReg := 0;
         bCylHighReg := 0;
         bDriveHeadReg := $A0;
         bCommandReg := IDE_ID_FUNCTION;
       end;
     end;
     if not DeviceIoControl(hDevice, DFP_RECEIVE_DRIVE_DATA, pInData,
       SizeOf(TSendCmdInParams) - 1, pOutData, W9xBufferSize,
       cbBytesReturned, nil) then
       Exit;
   finally
     CloseHandle(hDevice);
   end;
 end;
 with PIdSector(PChar(pOutData) + 16)^ do
 begin
   ChangeByteOrder(sSerialNumber, SizeOf(sSerialNumber));
   SetString(Result, sSerialNumber, SizeOf(sSerialNumber));
 end;
end;
Пример использования:

var
 s: string;
 rc: DWORD;
begin
 s := GetIdeDiskSerialNumber;
 if s = "" then
 begin
   rc := GetLastError;
   if rc = 0 then
     WriteLn("IDE drive is not support SMART feature")
   else
     WriteLn(SysErrorMessage(rc));
 end
 else
   WriteLn("Disk serial number: """, s, """");
end.


 
Alex Konshin ©   (2005-10-17 09:04) [25]

> Gydvin ©   (17.10.05 06:52) [24]
Я бы настоятельно рекомендовал брать сей код с моего сайта. Все-таки он иногда меняется.


 
Gydvin ©   (2005-10-17 09:26) [26]

Alex Konshin ©   (17.10.05 09:04) [25]
Ну я ж говорил, несмотрел я их. И что нерабочий?
Был на странице скачал новый пример, спасибо.

Дома обязательно гляну.


 
REA   (2005-10-17 10:47) [27]

Ссылка битая на сайт вначале. Впрочем нашел через копирайт.

Можно достать MAC адрес сетевой карты, но он подделывается при желании.
Находил в свое время драйвера для NT/XP для доставания ID винта и CPU. Хотя может и без этого можно...


 
Ботвин Дмитрий   (2005-10-17 11:04) [28]

truvor ©   (16.10.05 02:28)  

Практически всю инфу по железу можно получить через WMI. Это, ИМХО, самый верный способ. Правда работает тока начиная c w2k, но вроде как и
для 9x есть драйверы WMI на микрософте.


 
Gydvin ©   (2005-10-17 12:09) [29]

Ботвин Дмитрий   (17.10.05 11:04) [28]
Практически всю инфу по железу можно получить через WMI


Это, что за зверь?


 
Ботвин Дмитрий   (2005-10-17 12:29) [30]

Gydvin ©   (17.10.05 12:09) [29]

Это Windows Menegment Instruments - читай MSDN, кроме того есть куча статей по работе с WMI в делфи. Вещь очень и очень полезная :-)))


 
Konrads   (2005-10-17 14:03) [31]

Очень удобен на мой взгляд MAC адрес сетевой карты

Создай форму на ней Button1 (TButton) и Memo1 (TMemo) и вот весь текст

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;

const
IPHelper = "iphlpapi.dll";
MAX_ADAPTER_NAME_LENGTH        = 256;
MAX_ADAPTER_DESCRIPTION_LENGTH = 128;
MAX_ADAPTER_ADDRESS_LENGTH     = 8;

type
 time_t = Longint;
 StrAddr = Array[1..3] of string;

PIP_MASK_STRING = ^IP_MASK_STRING;
IP_ADDRESS_STRING = record
 S: array [0..15] of Char;
end;
IP_MASK_STRING = IP_ADDRESS_STRING;

PIP_ADDR_STRING = ^IP_ADDR_STRING;
IP_ADDR_STRING = record
 Next: PIP_ADDR_STRING;
 IpAddress: IP_ADDRESS_STRING;
 IpMask: IP_MASK_STRING;
 Context: DWORD;
end;

PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
IP_ADAPTER_INFO = record
 Next: PIP_ADAPTER_INFO;
 ComboIndex: DWORD;
 AdapterName: array [0..MAX_ADAPTER_NAME_LENGTH + 3] of Char;
 Description: array [0..MAX_ADAPTER_DESCRIPTION_LENGTH + 3] of Char;
 AddressLength: UINT;
 Address: array [0..MAX_ADAPTER_ADDRESS_LENGTH - 1] of BYTE;
 Index: DWORD;
 Type_: UINT;
 DhcpEnabled: UINT;
 CurrentIpAddress: PIP_ADDR_STRING;
 IpAddressList: IP_ADDR_STRING;
 GatewayList: IP_ADDR_STRING;
 DhcpServer: IP_ADDR_STRING;
 HaveWins: BOOL;
 PrimaryWinsServer: IP_ADDR_STRING;
 SecondaryWinsServer: IP_ADDR_STRING;
 LeaseObtained: time_t;
 LeaseExpires: time_t;
end;

 TForm1 = class(TForm)
   Button1: TButton;
   Memo1: TMemo;
   function Dim2Hex(what:array of byte;len:integer):string;
   procedure Button1Click(Sender: TObject);

 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;
 InterfaceInfo, TmpPointer: PIP_ADAPTER_INFO;
 IP: PIP_ADDR_STRING;
 Len: ULONG;

implementation

{$R *.dfm}
function GetAdaptersInfo(pAdapterInfo: PIP_ADAPTER_INFO; var pOutBufLen: ULONG): DWORD; stdcall; external IPHelper;

function TForm1.Dim2Hex(what:array of byte;len:integer):string;
var i : integer;
  b : byte;
begin
   Result:="";
   for i:=0 to len-1 do begin
     b:=what[i];
     Result := Result+inttohex(b,2)+".";
   end;
   Delete(Result,Length(Result),1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if GetAdaptersInfo(nil, Len) = ERROR_BUFFER_OVERFLOW then
begin
 GetMem(InterfaceInfo, Len);
 try
   if GetAdaptersInfo(InterfaceInfo, Len) = ERROR_SUCCESS then
   begin
     TmpPointer := InterfaceInfo;
     repeat
       IP := @TmpPointer.IpAddressList;
       repeat
         Memo1.Lines.Append("IP Addr = " + IP.IpAddress.S + "      MAC Addr = " + Dim2Hex(TmpPointer.Address,TmpPointer.AddressLength) + "     NET Card = " + TmpPointer.Description);
//          Writeln(Format("%s - %s - %s",
//            [IP.IpAddress.S, Dim2Hex(TmpPointer.Address,TmpPointer.AddressLength),TmpPointer.Description]));
         IP := IP.Next;
       until IP = nil;
       TmpPointer := TmpPointer.Next;
     until TmpPointer = nil;
   end;
 finally
   FreeMem(InterfaceInfo);
 end;
end;
end;

end.

Зделай двойной клик по Button1 и запускай программу, дальше разберёшся



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

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

Наверх




Память: 0.59 MB
Время: 0.087 c
6-1125862548
Alpine
2005-09-04 23:35
2005.12.18
Как сохранить страницу загруженную в WebBrowser ?


14-1133123063
Gero
2005-11-27 23:24
2005.12.18
Минестерство Российской Федерации


1-1131899674
Toxa_ua
2005-11-13 19:34
2005.12.18
Как в компонент ListBox вставить в фон картинку jpeg?


2-1133512097
MakNik
2005-12-02 11:28
2005.12.18
MessageBox


2-1133441340
Mamed
2005-12-01 15:49
2005.12.18
Byte Array to WideString