Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » IcmpSendEcho и Windows 7 x64

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки

Открыть новую тему     Написать ответ в эту тему

AlexMoralez



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Столкнулся с проблемой вызова сабжевой функции в Windows 7 x64. При увеличении размера пакета запроса до 250 и выше байт возвращает ошибку 998 — неверная работа с памятью. Полез в МСДН онлайновый — там следующее:
 

Код:
 
RequestOptions [in]
 
A pointer to the IP header options for the request, in the form of an IP_OPTION_INFORMATION structure. On a 64-bit platform, this parameter is in the form for an IP_OPTION_INFORMATION32 structure.
 
This parameter may be NULL if no IP header options need to be specified.
 
ReplyBuffer [in, out]
 
A buffer to hold any replies to the echo request. Upon return, the buffer contains an array of ICMP_ECHO_REPLY structures followed by the options and data for the replies. The buffer should be large enough to hold at least one ICMP_ECHO_REPLY structure plus RequestSize bytes of data.
 
On a 64-bit platform, upon return the buffer contains an array of ICMP_ECHO_REPLY32 structures followed by the options and data for the replies.
ReplySize [in]
 
The allocated size, in bytes, of the reply buffer. The buffer should be large enough to hold at least one ICMP_ECHO_REPLY structure plus RequestSize bytes of data. On a 64-bit platform, The buffer should be large enough to hold at least one ICMP_ECHO_REPLY32 structure plus RequestSize bytes of data.

 
Т.е., для 64-битных платформ надо юзать другие структуры. ОК — идем, смотрим:
 

Код:
 
The ICMP_ECHO_REPLY32 structure describes the data returned in response to an IPv4 echo request on a 64-bit platform.
Syntax
Copy
 
typedef struct icmp_echo_reply32 {
IPAddr Address;
ULONG Status;
ULONG RoundTripTime;
USHORT DataSize;
USHORT Reserved;
VOID * POINTER_32 Data;
struct ip_option_information32 Options;
} ICMP_ECHO_REPLY32, *PICMP_ECHO_REPLY32;
 

 
Все отличие от старой —
VOID * POINTER_32 Data;
struct ip_option_information32 Options;
 
Вопрос: Как портировать в паскаль тип VOID * POINTER_32? Что является ему аналогом?
 
Аналогичный тип присутствует в структуре struct ip_option_information32.
 
Кто сталкивался?

Всего записей: 86 | Зарегистр. 05-06-2008 | Отправлено: 22:48 23-07-2010
AlexAlf



Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору

Цитата:
Вопрос: Как портировать в паскаль тип VOID * POINTER_32? Что является ему аналогом?

Pointer.

Всего записей: 269 | Зарегистр. 17-07-2006 | Отправлено: 01:46 13-09-2010
AlexMoralez



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Дело в не в нем оказалось - уже решил вопрос сам. У меня с выделяемой памятью проблемы были. Собсно, раньше тоже сомнений не было, что POINTER_32 это есть pointer в pascal. Но потом возникли... Как оказалось - зря Не там искал. А насколько я понял, что для POINTER_64 аналога в pascal пока нет. Embarcadero еще пока только анонсирует Delphi x64.

Всего записей: 86 | Зарегистр. 05-06-2008 | Отправлено: 11:01 13-09-2010
AnViSe



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Функция IcmpSendEcho в x64 проекте возвращает всегда ошибку 11050, хотя тот же проект но в х32 исполнении работает без проблем.
В чем трабла? В различии используемых структур
icmp_echo_reply и  icmp_echo_reply32
ip_option_information и ip_option_information32?

Всего записей: 123 | Зарегистр. 10-11-2008 | Отправлено: 17:06 10-02-2016
ne_viens

Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
У меня и на х86 и на х64 работает такой:

Код:
#include <windows.h>
#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "ws2_32.lib")
 
int doFlag;
////////////////////////////////////////////////////////////////////////////////////////
int __stdcall handler(type)
{
    puts("Ctrl-C pressed..\n");
    doFlag = 0;
    Sleep(4000);
    return 0;
}
 
////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char** argv)
{
    unsigned int err, ipaddr, i, j, min, max, sum;
    HANDLE hIcmp;
    char* lpMsgBuf;
    PICMP_ECHO_REPLY pRepl;
    SYSTEMTIME st;
    struct in_addr raddr;
    char snd[32] = "PINGPINGPINGPINGPINGPINGPINGPIN";
    char repl[sizeof(ICMP_ECHO_REPLY) + sizeof(snd)] = {0};
 
//    printf("%08X", _rdrand32_step(111));
    if(2 != argc)
    {
        printf("Usage: %s IPAddress\n", argv[0]);
        return -1;
    }
    
    ipaddr = inet_addr(argv[1]);
    hIcmp = IcmpCreateFile();
    
    if(INVALID_HANDLE_VALUE == hIcmp)
    {
        printf("IcmpCreateFile() error..\n");
        return -1;
    }
 
    doFlag = 1;
    SetConsoleCtrlHandler((PHANDLER_ROUTINE)handler, TRUE);
    
    for(min = 0xffffffff, max = sum = j = i = 0; doFlag; ++i)
    {
        GetLocalTime(&st);
        printf("%04d.%02d.%02d %02d:%02d:%02d ", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
        if(IcmpSendEcho(hIcmp, ipaddr, snd, sizeof(snd), NULL, repl, sizeof(repl), 1000))
        {
            ++j;
            pRepl = (PICMP_ECHO_REPLY)repl;
            raddr.S_un.S_addr = pRepl->Address;
            if(!pRepl->RoundTripTime)
            {
//                pRepl->RoundTripTime = 1;
                printf("time<1ms %s\n", inet_ntoa(raddr));
            }
            else
                printf("time=%ldms %s\n", pRepl->RoundTripTime, inet_ntoa(raddr));
            sum += pRepl->RoundTripTime;
            if(pRepl->RoundTripTime < min)
                min = pRepl->RoundTripTime;
            if(pRepl->RoundTripTime > max)
                max = pRepl->RoundTripTime;
        }
        else
        {
            err = GetLastError();
//            printf("ICMP error 0x%08x ", err);
            FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err,
                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR)&lpMsgBuf, 0, NULL);
            printf("Err: 0x%08x, %s", err, lpMsgBuf);
            LocalFree(lpMsgBuf);
        }
        Sleep(1000);
    }
    
    IcmpCloseHandle(hIcmp);
    printf("Packets: Sent = %d, Received = %d, Lost = %d, <%.0f%% loss>\n",
                        i, j, i - j, ((float)i - (float)j) / (float)i * 100);
//    if(!min)
//        ++min;
    printf("Round trip times: Min = %dms, Max = %dms, Average = %.0fms\n", min, max, (float)sum / j);
    return 0;
}

Всего записей: 1530 | Зарегистр. 01-11-2004 | Отправлено: 17:41 10-02-2016
NeoAnomaly

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
AnViSe, а код вызова покажите, в частности вот эти 2 параметра как задаёте:

Код:
 
_In_     LPVOID                 RequestData,
  _In_     WORD                   RequestSize,

Всего записей: 418 | Зарегистр. 23-03-2010 | Отправлено: 17:48 10-02-2016
AnViSe



Junior Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
NeoAnomaly
Вот описание:

Код:
 
type
  ip_option_information = packed record
      Ttl : byte;
      Tos : byte;
      Flags : byte;
      OptionsSize : byte;
      OptionsData : Pointer;
  end;
 
 icmp_echo_reply = packed record
      Address : u_long;
      Status : u_long;
      RTTime : u_long;
      DataSize : u_short;
      Reserved : u_short;
      Data : Pointer;
      Options : ip_option_information;
  end;
 
  PIPINFO = ^ip_option_information;
  PVOID = Pointer;
 
  function IcmpSendEcho(
                  IcmpHandle : THandle;
                  DestAddress : u_long;
                  RequestData : PVOID;
                  RequestSize : Word;
                  RequestOptns : PIPINFO;
                  ReplyBuffer : PVOID;
                  ReplySize : DWORD;
                  Timeout : DWORD) : DWORD; stdcall; external 'ICMP.DLL' name 'IcmpSendEcho';
 

Вот вызов:

Код:
function CheckPing(Host: String): boolean;
var
  hIP: THandle;
  pingBuffer: array [0..31] of Char;
  pIpe: ^icmp_echo_reply;
  wVersionRequested: WORD;
  lwsaData: WSAData;
  Error: WORD;
  cIP : Cardinal;
begin
 Result := True;
 hIP := IcmpCreateFile();
 GetMem(pIpe, sizeof(icmp_echo_reply) + sizeof(pingBuffer));
 pIpe.Data := @pingBuffer;
 pIpe.DataSize := sizeof(pingBuffer);
 wVersionRequested := MakeWord(1, 1);
 Error := WSAStartup(wVersionRequested, lwsaData);
 if (Error <> 0) then
  begin
   Result := False;
  end
 else
  begin
   cIP := inet_addr(PAnsiChar(AnsiString(Host)));
   IcmpSendEcho(hIP, cIP, @pingBuffer, SizeOf(pingBuffer), nil, pIpe, SizeOf(icmp_echo_reply) + SizeOf(pingBuffer), 1000);
   Error := GetLastError();
   if (Error <> 0) then
    begin
     Result := False;
    end;
  end;
 IcmpCloseHandle(hIP);
 WSACleanup();
 FreeMem(pIpe);
end;
 

Всего записей: 123 | Зарегистр. 10-11-2008 | Отправлено: 08:40 11-02-2016 | Исправлено: AnViSe, 08:47 11-02-2016
Открыть новую тему     Написать ответ в эту тему

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » IcmpSendEcho и Windows 7 x64


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru