0

Here is testing code, I'm trying to understand callbacks with IcmpSendEcho2; my callback does not fire. I tried to move icmp functions to other thread (link), but got no result. I tried to use XP callback style (here I'm not surprised to get nothing on win7)

#include <WinSock2.h>  //includes Windows.h
#include <Ws2tcpip.h>

/**
    struct from WinDDK Wdm.h (include Wdm.h, Ntddk.h, or Ntifs.h)
*/
typedef struct _IO_STATUS_BLOCK {
  union {
    NTSTATUS Status;
    PVOID    Pointer;
  };
  ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

/**
    typedef for PIO_APC_ROUTINE from MSDN
*/
typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
    IN PVOID ApcContext,
    IN PIO_STATUS_BLOCK IoStatusBlock,
    IN ULONG Reserved
    );
//defined
#define PIO_APC_ROUTINE_DEFINED

#include <iphlpapi.h>
#include <icmpapi.h>
#include <stdio.h>

#include <string>
using namespace std;

#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib, "iphlpapi.lib")

bool    icmpLoop = false;

VOID NTAPI callbackVistaPlus(PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,ULONG Reserved)
{
    MessageBoxA(0,"wow!","msg",MB_OK);
}

DWORD WINAPI IcmpThread(PVOID Parameter)
{
    unsigned long _serverAddr = inet_addr("192.168.1.2"); //my linux machine
    HANDLE _hIcmp = IcmpCreateFile();
    bool init = true;
    if (_hIcmp == INVALID_HANDLE_VALUE)
    {
        printf("cant icmpcreatefile\n");
        return 0;
    }
    //for test i create large buffer. it's testing code, not real
    char * _replysBuffer = (char*)malloc(sizeof(ICMP_ECHO_REPLY)*1000+8); 
    if (!_replysBuffer)
    {
        printf("cant buffer\n");
        return 0;
    }
    char * data = "hi all"; //my testing data to see with tcpdump at linux machine
//  bool loop = true;
    DWORD ret = IcmpSendEcho2(
            _hIcmp,
            0,
            callbackVistaPlus,
            0,
            _serverAddr,
            data,
            strlen(data),
            NULL,
            _replysBuffer,
            sizeof(ICMP_ECHO_REPLY)*1000+8,
            1000);
    /**/
    printf("ping sended\n");
    getchar();
//  while (icmpLoop){Sleep(100);}
    printf("exit\n");
    IcmpCloseHandle(_hIcmp);
}

int main(int argc, char* argv[])
{
    icmpLoop = true;
//  HANDLE hThread = CreateThread(NULL,0,IcmpThread,NULL,0,NULL);
    IcmpThread(0);
//  getchar();
//  icmpLoop = false;
    getchar();
    return 0;
}

I'm totally sure about correct existing of replyBuffer, and that IcmpCloseHandle doesn't close before I get reply (loop for thread-style, getchar() "pause" for non-thread)

I check tcpdump at linux machine (which I use to send echo) and I see incoming and outgoing ICMP packets with my data - it's working! I debug the compiled code, and see replyBuffer changes with my data after IcmpSendEcho2 .. So.. ICMP does work, but not the callback.

I don't want to move to Event-style, because it will create problems to my code

Also I'm surprised about the next situation: MSDN:

When called asynchronously, the IcmpSendEcho2 function 
returns ERROR_IO_PENDING to indicate the operation is in progress. 

but IcmpSendEcho2 returns 0, and GetLastError() returns ERROR_IO_PENDING is it ok?

so, if anyone could help me - it would be awesome.

Community
  • 1
  • 1
abrakadobr
  • 11
  • 6

1 Answers1

0

The callback is only called when the calling thread is in an "alertable state". Basically, you need to call one of the extended waiting functions with the alertable flag=true, for example WaitForSingleObjectEx.

Gajib
  • 46
  • 2