2

I would like to send over a message structure from a DLL-callback function to a python application so I can log the messages.

For this I would like to use ZeroMQ. Sadly I am unable to get the messages to python using the example provided by ZeroMQ.


DLL:

// dllmain.cpp : Defines the entry point for the DLL application.
#include "pch.h"
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include <zmq.h>
HHOOK tHook;
HMODULE hinstDLL;
void* requester;
void* context;
LRESULT CALLBACK meconnect(int code, WPARAM wParam, LPARAM lParam) {
    if (code == HC_ACTION) {
        LPMSG data = (LPMSG)lParam;
        UINT message = data->message;
        switch (message)
        {
        case WM_POINTERUPDATE:
            if (!IS_POINTER_INCONTACT_WPARAM(wParam))
                break;
        case WM_POINTERDOWN:
        case WM_POINTERUP:
            POINTER_INFO pointerInfo = {};
            GetPointerInfo(GET_POINTERID_WPARAM(wParam), &pointerInfo);        
            int request_nbr;
            for (request_nbr = 0; request_nbr != 10; request_nbr++) {
                char buffer[10];
                printf("Sending Hello %d…\n", request_nbr);
                zmq_send(requester, data, 5, 0);
                zmq_recv(requester, buffer, 10, 0);
                printf("Received World %d\n", request_nbr);
            }        
        }
    }
    return(CallNextHookEx(tHook, code, wParam, lParam));
}
extern "C" __declspec(dllexport) BOOL ConnectServer() {
    printf("Connecting to hello world server…\n");
    static void* context = zmq_ctx_new();
    static void* requester = zmq_socket(context, ZMQ_REQ);
    zmq_connect(requester, "tcp://127.0.0.1:5555");
    printf("connected");
    return TRUE;
}
extern "C" __declspec(dllexport) BOOL DisconnectServer() {
    zmq_close(requester);
    zmq_ctx_destroy(context);
    return TRUE;
}
extern "C" __declspec(dllexport) BOOL SetHook()
{
    tHook = SetWindowsHookEx(WH_GETMESSAGE, meconnect, hinstDLL, 0);

    if (tHook == NULL)
        return FALSE;
    else
        return TRUE;
}
extern "C" __declspec(dllexport) BOOL UnHook()
{
    return UnhookWindowsHookEx(tHook);
}


BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        hinstDLL = hModule;
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Python:

context = zmq.Context()
socket = context.socket(zmq.REP)
socket.bind("tcp://127.0.0.1:5555")

def message_msg_loop():
    while True:
        #  Wait for next request from client
        message = socket.recv()
        print("Received request: %s" % message)

        #  Do some 'work'
        time.sleep(1)

        #  Send reply back to client
        socket.send(b"World")

def pointer_msg_loop():
    global lib
    lib = cdll.LoadLibrary(r'C:\Users\Braun\Documents\BA_Thesis\ba-oliver-braun-logging-tool-code\MessagesDll\x64\Release\HOOKDLL.dll')
    print(lib)
    res = lib.ConnectServer()
    res = lib.SetHook()
    pythoncom.PumpMessages()
    res = lib.UnHook()

Basically my plan was to detect a certain event through windows messages and pass the message structure from the DLL-callback over to the server in Python, so I can handle the data there and put them into a log file. It does not seem to work though.

user3666197
  • 1
  • 6
  • 50
  • 92

1 Answers1

2

In case one has never worked with ZeroMQ,
one may here enjoy to first look at "ZeroMQ Principles in less than Five Seconds"
before diving into further details



Simplicity helps us start,
rather than remain headbanging into Complexity First

Best avoid all the complexities :
- set .setsockopt( zmq.LINGER, 0 ) # ALWAYS, never know what version will try to join the Club
- prototype with PUSH/PULL(it a) meets the spec.+b) does not block in a mutual deadlock as all REQ/REP do ) - never share a socket ( yes, the requester ought be a private, non-shared instance )
- always read-in and assert-eval the return-codes from the ZeroMQ API calls ( detect many issues on-spot )


Can you POSACK / prove the both of the module-level declarations

...
void* requester;
void* context;
LRESULT CALLBACK meconnect(...) {...}
...

actually work as expected, or does the ConnectServer(){...}'s internal, in-scope declarations mask both of these globals ?


extern "C" __declspec(dllexport) BOOL ConnectServer() {
    printf("Connecting to hello world server…\n");
    static void* context = zmq_ctx_new();                   // shadows out void* context
    static void* requester = zmq_socket(context, ZMQ_REQ); //  shadows out void* requester
    zmq_connect(requester, "tcp://127.0.0.1:5555");
    printf("connected");
    return TRUE;
}
user3666197
  • 1
  • 6
  • 50
  • 92
  • 1
    Hey thanks for helping me out. I experimented abit and found out that pasting all the zmq related code into callback lets me receive messages in python. So the problem is definitely the globals. – Oliver Braun Feb 19 '20 at 14:57
  • Great to hear that 've solved your problem + do not forget the other things, most importantly the explicit LINGER. – user3666197 Feb 19 '20 at 14:59
  • I still sadly have no idea how to split up the code between the function so the globals are working. Also i have no idea how to set up the above LINGER and what it means. – Oliver Braun Feb 19 '20 at 15:04
  • Received request: b'\xd2\x03\x0b\x00\x00' This is what i get in my python program – Oliver Braun Feb 19 '20 at 15:10