2017-04-21 7 views
1

문제점이 있습니다. ++ WH_JOURNALRECORD 및 C WH_JOURNALPLAYBACK를 사용하는 프로그램은 모든 나쁜 찾고 있지만 .. 오류 0x0000008E 와 함께 블루 스크린 내 컴퓨터를 종료 몇 초에서 프로그램은 내 코드 (DLL)입니다 : 당신은 수정할 수 없습니다C++ JournalPlayback 및 Bluescreen 0x0000008E (후크)

/* 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); 
} 

답변

0

EVENTMSG 구조체. 문서에 그렇게 나와 있습니다. time 필드를 전혀 조작해서는 안됩니다.

더 이런 식으로 뭔가를 시도 : 답변

/* 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); 
    } 
} 
+0

감사합니다! : P 나는 2 초 3 초가 지난 후 재생할 때 몇 초보다 오래 녹음을한다면 블루 스크린을 얻었지만 훔쳤다. 녹음 시간이 짧으면 (1 초) 효과가 더 좋고 블루 스크린이 없습니다. 어쩌면이 문제는 내 PC와 관련이 있습니까? 어쨌든 내 문제에 관심을 갖고 도움을 주심에 감사드립니다. – Kurogami12