Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» IcmpSendEcho и Windows 7 x64

Автор: AlexMoralez
Дата сообщения: 23.07.2010 21:48
Столкнулся с проблемой вызова сабжевой функции в 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.
Автор: AlexAlf
Дата сообщения: 13.09.2010 00:46

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

Pointer.
Автор: AlexMoralez
Дата сообщения: 13.09.2010 10:01
Дело в не в нем оказалось - уже решил вопрос сам. У меня с выделяемой памятью проблемы были. Собсно, раньше тоже сомнений не было, что POINTER_32 это есть pointer в pascal. Но потом возникли... Как оказалось - зря Не там искал. А насколько я понял, что для POINTER_64 аналога в pascal пока нет. Embarcadero еще пока только анонсирует Delphi x64.
Автор: AnViSe
Дата сообщения: 10.02.2016 16:06
Функция IcmpSendEcho в x64 проекте возвращает всегда ошибку 11050, хотя тот же проект но в х32 исполнении работает без проблем.
В чем трабла? В различии используемых структур
icmp_echo_reply и icmp_echo_reply32
ip_option_information и ip_option_information32?
Автор: ne_viens
Дата сообщения: 10.02.2016 16:41
У меня и на х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;
}
Автор: NeoAnomaly
Дата сообщения: 10.02.2016 16:48
AnViSe, а код вызова покажите, в частности вот эти 2 параметра как задаёте:

Код:
_In_ LPVOID RequestData,
_In_ WORD RequestSize,
Автор: AnViSe
Дата сообщения: 11.02.2016 07:40
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';

Страницы: 1

Предыдущая тема: liberty basic


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.