My objective is conceptually simple: I want to set a GetMessage global hook function that utilizes a shared file handle. The problem arises because to my understanding the DLL containing the hook function is loaded multiple times for each process, each with their own "address space". For this reason I'm led to believe I can't simply handle DllMain's DLL_PROCESS_ATTACH to create the desired file, as multiple files would be created with different handles.
A solution that's been brought to my attention is Named Pipes. Basically the application would act as the server end; it would create the file one time then provide the file handle to the DLL clients, therefore each global hook would be using the same file.
I can't seem to get it to work from the code I gathered. In the application, I create the file, set the global hook function, then make it go through this loop:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
while(1)
{
HANDLE hPipe = CreateNamedPipe("\\\\.\\pipe\\pipename", PIPE_ACCESS_OUTBOUND,
PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 32, 32, 5000, NULL);
if(hPipe == INVALID_HANDLE_VALUE)
return 42;
if(!ConnectNamedPipe(hPipe, NULL))
return 43;
DWORD dwWritten;
WriteFile(hPipe, logFile, sizeof(logFile), &dwWritten, NULL);
FlushFileBuffers(hPipe);
DisconnectNamedPipe(hPipe);
CloseHandle(hPipe);
}
|
Then I handle the DllMain's DLL_PROCESS_ATTACH as so:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
case DLL_PROCESS_ATTACH:
{
HANDLE hPipe;
while(1)
{
hPipe = CreateFile("\\\\.\\pipe\\pipename", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
if(hPipe != INVALID_HANDLE_VALUE)
break;
WaitNamedPipe("\\\\.\\pipe\\pipename", NMPWAIT_USE_DEFAULT_WAIT);
}
DWORD dwRead;
ReadFile(hPipe, logFile, sizeof(logFile), &dwRead, NULL);
CloseHandle(hPipe);
break;
}
|
Simply put, it does not work, and I can't seem to figure out why. Is there something I'm missing or doing wrong in my code?
Another problem that I can't figure out is that the application is stuck in an infinite loop of constantly serving. I want to set up an Event that the DLL will set under a certain circumstance and cause the main application to unhook the global hook, close the file and exit, however ConnectNamedPipe is a blocking function. What is a way to determine when all clients have been served so the serving loop can break?
Thanks for any help.