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

Вниз

GetTCPTable   Найти похожие ветки 

 
Nucer   (2008-12-15 12:33) [0]

procedure GetPorts;
var
Size: Cardinal;
TCPTable: PTMibTCPTable;
I: DWORD;
n: integer;
begin
SetLength(ports,0);
GetMem(TCPTable, SizeOf(TMibTCPTable));
try
 Size:=0;
 if GetTcpTable(TCPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
finally
 FreeMem(TCPTable);
end;
GetMem(TCPTable, Size);
try
 if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
    begin
     for i:=0 to TCPTable^.dwNumEntries - 1 do
        begin
         if TCPTable^.Table[I].dwState=MIB_TCP_STATE_LISTEN then
            begin
             n:=length(ports);
             setlength(ports,n+1);
             ports[n]:=htons(TCPTable^.Table[I].dwLocalPort);
            end;
        end;
    end;
finally
 FreeMem(TCPTable);
end;
end;


При втором вызове приложение вылетает с ошибкой. Подскажите, в чем может быть ошибка?


 
Сергей М. ©   (2008-12-15 12:41) [1]


> в чем может быть ошибка?


Приведи свой прототип GetTcpTable


 
Nucer   (2008-12-15 12:46) [2]

 PTMibTCPRow = ^TMibTCPRow;
 TMibTCPRow = packed record
   dwState: DWORD;
   dwLocalAddr: DWORD;
   dwLocalPort: DWORD;
   dwRemoteAddr: DWORD;
   dwRemotePort: DWORD;
 end;

 PTMibTCPTable = ^TMibTCPTable;
 TMibTCPTable = packed record
   dwNumEntries: DWORD;
   Table: array[0..0] of TMibTCPRow;
 end;

 function GetTcpTable(pTCPTable: PTMibTCPTable; var pDWSize: DWORD;
   bOrder: BOOL): DWORD; stdcall; external "IPHLPAPI.DLL";


 
Сергей М. ©   (2008-12-15 12:57) [3]

http://lineage2c5.info/2267_get_tcp_table.html


 
Nucer   (2008-12-15 20:18) [4]

Честно говоря существенной разницы не уловил. В прототипе у них var перед первым параметром и разыменование при вызове, у меня же var нет и разыменования нет.

И мой код больше похож на пример из MSDN:
http://msdn.microsoft.com/en-us/library/aa366026(VS.85).aspx

Дело в том, что программа вылетает где-то на одном компьютере из сотни (и на XP, и на Vista). В чем дело - понять не могу. Size при первом вызове возвращается нормальный (не 0). GetMem проходит нормально, а при втором вызове ошибка.


 
Nucer   (2008-12-15 20:21) [5]

Мой код по сути взят из примера Rouse_:
http://forum.sources.ru/index.php?showtopic=81522


 
Eraser ©   (2008-12-15 21:59) [6]

у меня данный код
procedure TForm1.Button1Click(Sender: TObject);
var
 Size: Cardinal;
 TCPTable: PMibTcpTable;
 I: DWORD;
 n: integer;
 ports: array of Integer;
begin
 SetLength(ports, 0);
 GetMem(TCPTable, SizeOf(TMibTCPTable));
 try
   Size := 0;
   if GetTcpTable(TCPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then
     Exit;
 finally
   FreeMem(TCPTable);
 end;

 GetMem(TCPTable, Size);
 try
   if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
   begin
     for i := 0 to TCPTable^.dwNumEntries - 1 do
     begin
       if TCPTable^.Table[I].dwState=MIB_TCP_STATE_LISTEN then
       begin
         n := Length(ports);
         SetLength(ports, n+1);
         ports[n] := htons(TCPTable^.Table[I].dwLocalPort);
       end;
     end;
   end;
 finally
   FreeMem(TCPTable);
 end;
end;

отлично работает. протитипы взяти из JEDI API - JwaIpHlpApi, JwaIpRtrMib:
type
 PMIB_TCPTABLE = ^MIB_TCPTABLE;
 {$EXTERNALSYM PMIB_TCPTABLE}
 _MIB_TCPTABLE = record
   dwNumEntries: DWORD;
   table: array [0..ANY_SIZE - 1] of MIB_TCPROW;
 end;
 {$EXTERNALSYM _MIB_TCPTABLE}
 MIB_TCPTABLE = _MIB_TCPTABLE;
 {$EXTERNALSYM MIB_TCPTABLE}
 TMibTcpTable = MIB_TCPTABLE;
 PMibTcpTable = PMIB_TCPTABLE;

function GetTcpTable(pTcpTable: PMIB_TCPTABLE; var pdwSize: DWORD; bOrder: BOOL): DWORD; stdcall;


 
Nucer   (2008-12-15 22:03) [7]

Да у меня мой тоже работает...


> Дело в том, что программа вылетает где-то на одном компьютере
> из сотни (и на XP, и на Vista). В чем дело - понять не могу.
>
> Size при первом вызове возвращается нормальный (не 0).
> GetMem проходит нормально, а при втором вызове ошибка.


 
Eraser ©   (2008-12-15 22:08) [8]

> [4] Nucer   (15.12.08 20:18)


> Дело в том, что программа вылетает где-то на одном компьютере
> из сотни (и на XP, и на Vista). В чем дело - понять не могу.
> Size при первом вызове возвращается нормальный (не 0). GetMem
> проходит нормально, а при втором вызове ошибка.

скорее всего ошибка вообще не в этом коде. какая то часть приложения портит память. включите опциях компилятора, чтобы в runtime"e были проверки range check и overflow check.


 
Nucer   (2008-12-15 22:12) [9]

Спасибо за совет, попробую. Трудность в том, что это DLL-plugin к чужому приложению и используется Themida. Попробую еще сделать отдельную программу с таким же кодом и дать тем у кого возникает ошибка.


 
Nucer   (2008-12-16 00:55) [10]

Нет, все-таки дело именно в функции. Сделал пустой проект и вставил только кнопку с функцией. Пользователи (у которых были проблемы) получают:
Access violation at address 76D68EB1 in module "IPHLPAPI.DLL". Read of address 009F1F2C.


 
Германн ©   (2008-12-16 01:06) [11]


> Nucer   (16.12.08 00:55) [10]
>
> Нет, все-таки дело именно в функции. Сделал пустой проект
> и вставил только кнопку с функцией. Пользователи (у которых
> были проблемы) получают:
> Access violation at address 76D68EB1 in module "IPHLPAPI.
> DLL". Read of address 009F1F2C.
>

Ага. Именно в функции. :)
О сколько нам открытий чудных готовит чей-то дух! Выходит виновата функция, которая не умеет работать у "некоторых пользователей".


 
Eraser ©   (2008-12-16 01:50) [12]

> [10] Nucer   (16.12.08 00:55)

ошибка не в функции, а, к примеру, в выделении кривого участка памяти функцией GetMem, по причине того, что память где то попорчена.


 
Сергей М. ©   (2008-12-16 09:01) [13]


> Nucer

..
GetMem(TCPTable, Size);
try
  try
    if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
    begin
     ...
  finally
    FreeMem(TCPTable);
  end;
 except
   ShowMessage("Size = " + IntToStr(Size) + " BufPtr = " + IntToHex(Integer(TCPTable), 8));
 end;



Что видишь ?


 
Nucer   (2008-12-16 17:11) [14]


> ошибка не в функции, а, к примеру, в выделении кривого участка
> памяти функцией GetMem, по причине того, что память где
> то попорчена

Абсолютно новый проект (file -> new -> application). На форму кидаю TMemo и TButton. В обработчик OnClick вставляю только вызов функции GetPorts.

procedure ATL(s:string);
begin
frmMain.mLog.lines.add(s);
end;

procedure GetPorts;
var
Size: Cardinal;
TCPTable: PTMibTCPTable;
I: DWORD;
n: integer;
begin
SetLength(ports,0);
//try
 GetMem(TCPTable, SizeOf(TMibTCPTable));
 try
  Size:=0;
  if GetTcpTable(TCPTable, Size, True) <> ERROR_INSUFFICIENT_BUFFER then Exit;
 finally
  FreeMem(TCPTable);
 end;
 ATL("size: "+IntToStr(size));
 GetMem(TCPTable, Size);
 ATL("AfterGetMem");
 try                      
  ATL("BeforeFunc");
  if GetTcpTable(TCPTable, Size, True) = NO_ERROR then
     begin
      ATL("FuncDone");
      for i:=0 to TCPTable^.dwNumEntries - 1 do
         begin
          if TCPTable^.Table[I].dwState=MIB_TCP_STATE_LISTEN then
             begin
              n:=length(ports);
              setlength(ports,n+1);
              ports[n]:=htons(TCPTable^.Table[I].dwLocalPort);
             end;
         end;
      ATL("AfterFor");
     end;
  ATL("AfterBlock");
 finally
  FreeMem(TCPTable);
 end;
//except
// SetLength(ports,0);
//end;
end;


В результате:

> size: 592
> AfterGetMem
> BeforeFunc
>
> and then another window popup with message:
>
> "Access violation at address 76D68EB1 in module "IPHLPAPI.
> DLL". Read of address 009E9E7C"


Еще один отзыв:

> Access violation at address 76D58EB1 in module "IPHLPAPI.
> DLL" read of address 00A33ADC
>
> debug.exe:
> size: 772
> AfterGetMem
> BeforeFunc

---

> Сергей М.
> Что видишь ?

Сейчас добавлю try/except блок и вывод значения указателя и дам пользователям. Как ответят - скину сюда.


 
Eraser ©   (2008-12-16 19:59) [15]

а если попробовать использовать не делфевский менеджер памяти, а системный?


 
Rouse_ ©   (2008-12-17 10:33) [16]


> Сергей М. ©   (15.12.08 12:57) [3]
>
> http://lineage2c5.info/2267_get_tcp_table.html

По ссылке пример кривой, первый параметр обьявлен как указатель на указатель на буффер, второй с тем-же ляпом... Собственно у меня сей пример так и не собрался...


> Nucer   (16.12.08 17:11) [14]

Падает на финальной сортировке результатов, при считке первого параметра, он по всей видимости приходит пустым:
.text:76D58EAE                 mov     eax, [ebp+arg_4]
.text:76D58EB1                 mov     edx, [eax+4] <- вот тут падение
.text:76D58EB4                 mov     eax, [ebp+arg_0]
.text:76D58EB7                 mov     ecx, [eax+4]


Попробуй отключить сортировку (bOrder = False)


 
Сергей М. ©   (2008-12-17 11:49) [17]


> Rouse_ ©   (17.12.08 10:33) [16]


Угу, вижу


 
Nucer   (2008-12-17 20:40) [18]

Убрал сортировку:


> Access violation at address 0045113C in module "debug.exe".
>  Read of address 00958008.
>
> Content of debug.exe:
>
> size: 512
> AfterGetMem
> BeforeFuncEx
> FuncDone


 
Rouse_ ©   (2008-12-18 09:23) [19]

Ну а это уже у тебя падает (обрати внимание на адрес - 0045113C), можешь в отладчике посмотреть где именно память бьется ...


 
Сергей М. ©   (2008-12-18 09:29) [20]


> at address 0045113C


Это адрес в твоем коде, а не в коде IPHLPAPI.

Так что утверждение [10] на поверку оказывается ложным.


 
Nucer   (2008-12-18 11:44) [21]

Ошибка возникает при доступе к той памяти где должна находиться таблица. При включенной сортировке туда сначала обращается IPHLPAPI. Если сортировку отключить, то моя программа:


>       for i:=0 to TCPTable^.dwNumEntries - 1 do
>          begin
>           if TCPTable^.Table[I].dwState=MIB_TCP_STATE_LISTEN
> then
>              begin
>               n:=length(ports);
>               setlength(ports,n+1);
>               ports[n]:=htons(TCPTable^.Table[I].dwLocalPort);
>
>              end;
>          end;


Непонятно почему проблема постоянно возникает на небольшом проценте компьютеров, а у остальных никогда.


 
Nucer   (2008-12-18 11:50) [22]

Как ее можно локализовать - понятия не имею. Сложность в том, что проверить результат (работает или нет) можно только отправив программу пользователям (а они могут ответить и через сутки). Память выделяется, иначе бы процедуру GetMem вызвала исключение.


 
Сергей М. ©   (2008-12-18 11:53) [23]

см. меню Search -> Find Error ..


 
Rouse_ ©   (2008-12-18 13:19) [24]

По всей видимости на машине у проблемных пользователей может стоять некое ПО, приводящее к такому результату. Запроси у них информацию, выдаваемую утилитой MSINFO32 и посмотри что стоит на их машинах.


 
han_malign ©   (2008-12-18 14:23) [25]

TCPTable^.dwNumEntries > (Size - sizeof(TCPTable^.dwNumEntries)) div sizeof(TCPTable^.Table[I])
???


 
amarant555   (2009-01-22 18:30) [26]

http://www.delphisources.ru/pages/faq/base/get_tcp_table.html



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

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

Наверх




Память: 0.54 MB
Время: 0.054 c
2-1270195945
Lowlander
2010-04-02 12:12
2010.08.27
Маска ввода email


2-1271222434
d@nger
2010-04-14 09:20
2010.08.27
Хэндл MDI


2-1265976020
00110011
2010-02-12 15:00
2010.08.27
Дубликаты в списке


2-1274176649
Rail
2010-05-18 13:57
2010.08.27
связать бд с приложением


6-1216658120
evil_mike
2008-07-21 20:35
2010.08.27
tclientsocket без компонента на форме..