C++ JournalPlayback and Bluescreen 0x0000008E (hooks)

1

I have problem with my problem. Program using WH_JOURNALRECORD and WH_JOURNALPLAYBACK in c++, everything looking not bad but.. program in few seconds shut down my computer to bluescreen with error 0x0000008E it is my code(dll):

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <iostream>

using namespace std;

BOOL APIENTRY DllMain (HMODULE hModule     /* Library instance handle. */ ,
                       DWORD reason        /* Reason this function is being called. */ ,
                       LPVOID reserved     /* Not used. */ )
{
    g_hInst = hModule;

    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }

    /* Returns TRUE on success, FALSE on failure */
    return TRUE;
}

LRESULT CALLBACK RecordProc (int code, WPARAM wParam, LPARAM lParam)      //lparam to informacje wejscia a wparam wyjscia
{
          if( code < 0 ) return CallNextHookEx( 0, code, wParam, lParam );

          if( code == HC_ACTION )
          {
              EVENTMSG * msg =( EVENTMSG * ) lParam;
              msg->time -= g_StartTime;
              g_Events.push_back(* msg);
              return 0;
          }
          return CallNextHookEx (0, code, wParam, lParam);
}

LRESULT CALLBACK PlaybackProc(int code, WPARAM wParam, LPARAM lParam)
{
      if(code < 0) return CallNextHookEx(0, code, wParam, lParam);

      if(code == HC_GETNEXT)
      {
              EVENTMSG * msg = (EVENTMSG *) lParam;
        msg->hwnd = g_Events[ g_CurrentEvent ].hwnd;         
        msg->message = g_Events[ g_CurrentEvent ].message;       
        msg->paramH = g_Events[ g_CurrentEvent ].paramH;      
        msg->paramL = g_Events[ g_CurrentEvent ].paramL;       
        msg->time = g_StartTime + g_Events[ g_CurrentEvent ].time;  

              DWORD delta = msg->time - GetTickCount();

              if(delta > 0)     return delta;
              else
                       return 0;
      }
      else if(code == HC_SKIP)
      {
           if(!g_PlaybackStopped)
                 g_CurrentEvent++;

           if(g_CurrentEvent >= g_Events.size() )
           {
               g_CurrentEvent = 0;
                g_StartTime = GetTickCount();
                g_PlaybackStopped = false;
                return 0;
                }
       }
       return 0;
}


DLLIMPORT void StartRecording( void )
{
          g_StartTime = GetTickCount();
          if(g_RecordHook==NULL)
    g_RecordHook = SetWindowsHookEx( WH_JOURNALRECORD, RecordProc, g_hInst, 0 );
    else UnhookWindowsHookEx(g_RecordHook);
}


DLLIMPORT void StartPlayback( void )
{
          g_CurrentEvent = 0;
          g_StartTime = GetTickCount();
          UnhookWindowsHookEx(g_RecordHook);
          g_PlaybackStopped = false;
          Sleep(1000);
          g_PlaybackHook = SetWindowsHookEx( WH_JOURNALPLAYBACK, PlaybackProc, g_hInst, 0 );
}
c++
hook
asked on Stack Overflow Apr 21, 2017 by Kurogami12 • edited Apr 21, 2017 by Remy Lebeau

1 Answer

0

You are not allowed to modify the EVENTMSG structs. The documentation says so. You should not be manipulating the time field at all.

Try something more like this:

/* Replace "dll.h" with the name of your header */
#include "dll.h"
#include <windows.h>
#include <list>

HHOOK g_RecordHook = NULL;
HHOOK g_PlaybackHook = NULL;

bool g_PauseRecording = false;
bool g_PausePlayback = false;

std::list<EVENTMSG> g_Events;
std::list<EVENTMSG>::iterator g_CurrentEvent;

DWORD g_CurrentTime = 0;
DWORD g_PrevTime = 0;

BOOL APIENTRY DllMain(HMODULE hModule, DWORD reason, LPVOID reserved)
{
    g_hInst = hModule;
    return TRUE;
}

LRESULT CALLBACK RecordProc(int code, WPARAM wParam, LPARAM lParam)
{
    switch (code)
    {
        case HC_ACTION:
        {
            if (!g_PauseRecording)
            {
                EVENTMSG * msg = (EVENTMSG *) lParam;
                g_Events.push_back(*msg);
            }

            break;
        }

        case HC_SYSMODALOFF:
            g_PauseRecording = false;
            break;

        case HC_SYSMODALON:
            g_PauseRecording = true;
            break;
    }

    return CallNextHookEx(g_RecordHook, code, wParam, lParam);
}

LRESULT CALLBACK PlaybackProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code < 0)
        return CallNextHookEx(g_PlaybackHook, code, wParam, lParam);

    switch (code)
    {
        case HC_GETNEXT:
        {
            EVENTMSG * msg = (EVENTMSG *) lParam;
            *msg = *g_CurrentEvent;

            DWORD delay;
            if (g_CurrentTime != g_PreviousTime)
            {
                delay = (g_CurrentTime > g_PreviousTime) ?
                    (g_CurrentTime - g_PreviousTime) :
                    ((MAXDWORD - g_PreviousTime) + g_CurrentTime);
                g_PreviousTime = g_CurrentTime;
            }
            else
                delay = 0;

            return delay;
        }

        case HC_SKIP:
        {
            if (!g_PausePlayback)
            {
                ++g_CurrentEvent;
                if (g_CurrentEvent == g_Events.end())
                    g_CurrentEvent = g_Events.begin();

                g_PreviousTime = g_CurrentTime;
                g_CurrentTime = g_CurrentEvent->time;
            }

            break;
        }

        case HC_SYSMODALOFF:
            g_PausePlayback = false;
            break;

        case HC_SYSMODALON:
            g_PausePlayback = true;
            break;
    }

    return 0;
}

DLLIMPORT void StartRecording(void)
{
    if (g_PlaybackHook)
    {
        UnhookWindowsHookEx(g_PlaybackHook);
        g_PlaybackHook = NULL;
    }

    if (g_RecordHook)
    {
        UnhookWindowsHookEx(g_RecordHook);
        g_RecordHook = NULL;
    }

    g_Events.clear();
    g_PauseRecording = false;

    g_RecordHook = SetWindowsHookEx(WH_JOURNALRECORD, RecordProc, g_hInst, 0);
}

DLLIMPORT void StartPlayback(void)
{
    if (g_RecordHook)
    {
        UnhookWindowsHookEx(g_RecordHook);
        g_RecordHook = NULL;
    }

    if (g_PlaybackHook)
    {
        UnhookWindowsHookEx(g_PlaybackHook);
        g_PlaybackHook = NULL;
    }

    if (!g_Events.empty())
    {
        g_CurrentEvent = g_Events.begin();

        g_PreviousTime = g_CurrentTime = g_CurrentEvent->time;
        g_PausePlayback = false;

        g_PlaybackHook = SetWindowsHookEx(WH_JOURNALPLAYBACK, PlaybackProc, g_hInst, 0);
    }
}
answered on Stack Overflow Apr 21, 2017 by Remy Lebeau • edited Apr 21, 2017 by Remy Lebeau

User contributions licensed under CC BY-SA 3.0