그런데 잘 동작하다가 인터넷익스플로러가 종종 잘못된 연산으로 종료되더군요.
지금까지 써왔던 api hook 코드가 잘못되었나 싶어 어셈코드부터 다 뜯어보았습니다.
그래도 원인을 알 수 없더군요.
할 수 없이 기존의 쓰던 훅코드를 지우고 Microsoft Research 에서 배포하는 Detours 를 통해 훅을 해서 테스트 하였습니다. 그랬더니 역시나 익스플로러가 종료되더군요.
사실 어셈이나 인젝션한 DLL 에서 잘못되었다면 익셉션 직전의 콜스택이 저렇게 되면 안되는 것인데..
머.. 어쨋든 Detours에서도 같은 증상을 나타내니 코드를 하니씩 제거해 나가면서 테스트를 해보았습니다.
그래서 결국 찾은 것이 아래와 같은 코드더군요.
362 EmptyClipboard();
363 size_t nSize = strlen(szTemp)+1;
364 BYTE* hData = (BYTE*)GlobalAlloc(GMEM_FIXED, nSize);
365 memcpy(hData, szTemp, nSize);
366 //HANDLE hCp = GetClipboardData(CF_TEXT);
367 SetClipboardData(CF_TEXT, hData);
368 CloseClipboard();
369 GlobalFree(hData);
370 sndPlaySoundA(lpWaveRes, SND_MEMORY|SND_ASYNC);
그래서 아래와 같이 바꿔보았습니다.
68 EmptyClipboard();
69 size_t nSize = strlen(szTemp);
70 HGLOBAL hMem = GlobalAlloc(GMEM_MOVEABLE, nSize);
71 BYTE* hData = (BYTE*)GlobalLock(hMem);
72 memcpy(hData, szTemp, nSize);
73 SetClipboardData(CF_TEXT, hData);
74 CloseClipboard();
75 GlobalUnlock(hMem);
76 GlobalFree(hData);
77 sndPlaySoundA(lpWaveRes, SND_MEMORY|SND_ASYNC);
이렇게 하니 인터넷익스플로러가 종료하지 않더군요.
아직도 정확히 무엇때문에 종료가 된 건지는 정확히 규명이 되지 않았지만, 쓰레드가 많이 동작하는 경우 GlobalAlloc 에 GMEM_FIXED 를 사용하는 것을 자제해야겠습니다. ^^;