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

Вниз

функция NetBIOS и Windows Vista   Найти похожие ветки 

 
_netbios_   (2010-03-03 16:27) [0]

Столько лет нормально работала функция NetBIOS. Получал с помощью нее MAC-адреса хостов. Очень незаменимая вещь — может вернуть MAC хоста за маршрутизатором (если протокол разрешен NETBIOS). И тут на-те! MS оказывается прекратила ее поддержку начиная с Висты!
http://msdn.microsoft.com/en-us/library/bb870903%28VS.85%29.aspx
..."[Netbios is not supported on Windows Vista, Windows Server 2008, and subsequent versions of the operating system]"...

Я потратил несколько месяцев на понимание, отчего моя прога вдруг начала непредсказуемо глючить в ходе выполнения этой функции именно в Висте и 7ке. Память сильно портилась, ломались указатели в разных местах... Как следствие — исключения, приводящие к завершению. Перепробовал кучу примеров из инета по использованию ее. Полез в оффлан-мсдн — там даже описания нет ее. И наконец полез в онлайн-мсдн, и сделал печальное открытие. Какие комментарии, товарищи разработчики? Как дальше жить без нее? Может замена какая есть, а я не знаю просто? Самое интересное, что если хост существует, то функция нормально отрабатывает и возвращает MAC. Иначе — глюки с памятью после вызова: то цикл от i=0 to 0 вдруг становится бесконечным, то объекты созданные до вызова NetBIOS перестают нормально существовать.


 
DVM ©   (2010-03-03 17:44) [1]


> Иначе — глюки с памятью после вызова: то цикл от i=0 to
> 0 вдруг становится бесконечным, то объекты созданные до
> вызова NetBIOS перестают нормально существовать.

По моему у тебя в программе ошибка.


 
_netbios_   (2010-03-03 21:04) [2]


> По моему у тебя в программе ошибка.


В 5й строке? :)


 
_netbios_   (2010-03-04 16:35) [3]

Вот, ребята с другого форума подсказали, как реализовать замену функции NetBIOS. Просто отправить нужный NBQuery по UDP хосту, MAC которого нужно узнать. Замечательно работает в случае, если хост включен и работает netbios на нем. Иначе обычный выход по таймауту при select. Никаких заморочек, как в случае с функцией NetBIOS.


const
NB_QUERY : array[0..37] of Byte = ($20,$43,$4b,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41 ,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$41,$00,$00,$21,$00,$01);

type
PMacAddress = ^TMacAddress;
TMacAddress = array[0..5] of byte;

type
PNB_HEADER = ^NB_HEADER;
NB_HEADER = packed record
 wTransId : Word;
 wFlags : Word;
 wQuestions : Word;
 wAnswerRRs : Word;
 wAuthRRs : Word;
 wAdditionalRRs : Word;
end;

type
PNB_NAME = ^NB_NAME;
NB_NAME = packed record
 Name : array[0..15] of char;
 Flags : Word;
end;

type
PNB_ANSWER = ^NB_ANSWER;
NB_ANSWER = packed record
 RRName : array[0..33] of char;
 Nbtype : Word;
 Nbclass : Word;
 dwTTL : DWord;
 wDataLen : Word;
 NumNames : Byte;
end;
   .................

function GetMACAddrUDP(hostaddr: string; var mac: string): boolean;
var
 S: TSocket;
 AddrSize, Return: Integer;
 Header: NB_HEADER;
 Target: TSockAddrIn;
 P: Pointer;
 OrigTransId: Word;
 TimeOut: TTimeVal;
 FDSet: TFDSet;
 Buffer: array[0..$800] of Byte;
 NumNames, Offset: Integer;
 MA: TMacAddress;
begin
 mac := "";
 Result := False;
 s := socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
 try
 {Keep trans ID}
   OrigTransId := LoWord(GetTickCount);
 {Prepare request}
   ZeroMemory(@Header, SizeOf(Header));
   Header.wTransId := OrigTransId;
   Header.wFlags := $1000;
   Header.wQuestions := htons(1);
 {Prepare address}
   ZeroMemory(@Target, SizeOf(Target));
   Target.sin_family := AF_INET;
   Target.sin_addr.S_addr :=  inet_addr(Pchar(hostaddr));
   Target.sin_port := htons(137);
 {Glue reuqest}
   GetMem(P, SizeOf(Header) + SizeOf(NB_QUERY));
   try
     ZeroMemory(P, SizeOf(Header) + SizeOf(NB_QUERY));
     MoveMemory(P, @Header, SizeOf(Header));
     MoveMemory(Ptr(DWORD(P) + SizeOf(Header)), @NB_QUERY, SizeOf(NB_QUERY));
     if sendto(s, P^, SizeOf(Header) + SizeOf(NB_QUERY), 0, Target, SizeOf(Target)) <> SOCKET_ERROR then
     begin
       ZeroMemory(@FDSet, SizeOf(FDSet));
       FDSet.fd_array[0] := S;
       FDSet.fd_count := 1;
       ZeroMemory(@TimeOut, SizeOf(TimeOut));
       TimeOut.tv_sec := 1;
       if select(0, @FDSet, nil, nil, @TimeOut) > 0 then
       begin
         ZeroMemory(@Buffer, SizeOf(Buffer));
         AddrSize := SizeOf(Target);
         Return := recvfrom(s, Buffer, SizeOf(Buffer), 0, Target, AddrSize);
         if Return > SizeOf(Header) then
         begin
           with PNB_HEADER(@Buffer)^ do
             if (OrigTransId = wTransId) and ((wFlags shr 12) = 0) and (htons(wAnswerRRs) = 1) then
             begin
               NumNames := PNB_ANSWER(Ptr(DWord(@Buffer) + SizeOf(NB_HEADER)))^.NumNames;
               if NumNames * SizeOf(NB_NAME) + SizeOf(TMacAddress) < (Return - SizeOf(NB_HEADER)) then
               begin
                 Offset := SizeOf(NB_HEADER) + SizeOf(NB_ANSWER) + NumNames * SizeOf(NB_NAME);
                 MA := PMacAddress(Ptr(Integer(@Buffer) + Offset))^;
                 mac := IntToHex(MA[0], 2);
                 mac := mac + "-" + IntToHex(MA[1], 2);
                 mac := mac + "-" + IntToHex(MA[2], 2);
                 mac := mac + "-" + IntToHex(MA[3], 2);
                 mac := mac + "-" + IntToHex(MA[4], 2);
                 mac := mac + "-" + IntToHex(MA[5], 2);
                 Result := True;
               end;
             end;
         end;
       end;
     end;
   finally
     FreeMem(P);
   end;
 finally
   closesocket(S);
 end;
end;



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

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

Наверх




Память: 0.49 MB
Время: 0.007 c
6-1267622827
_netbios_
2010-03-03 16:27
2013.05.12
функция NetBIOS и Windows Vista


15-1357763402
Юрий
2013-01-10 00:30
2013.05.12
С днем рождения ! 10 января 2013 четверг


15-1357835257
SaJek
2013-01-10 20:27
2013.05.12
Delphi. По вопросу графики и анимации программах. GUI.


15-1356279639
azlk52
2012-12-23 20:20
2013.05.12
слетают настройки биоса


15-1357882764
O'ShinW
2013-01-11 09:39
2013.05.12
Почему такое странное поведение/ D7