There are many disputes for how to use and create hooks, this article tries to clarify these issues.
Note: If you just use the hook within your own process, there will be no one below, which occurs when you use the system hook.
The key issue is that any objects (including variables) created by the code in the address space and the DLL function are hit by its threads or processes. When the process is loaded into the DLL, the operating system automatically maps the DLL address to the private space of the process, that is, the virtual address space of the process, and copying a copy of the global data of the DLL to the process space. That is to say, the same DLL of each process, is a private, DLL to become part of the process, executed by this process, using this process stack. This means that the data will be reinitialized. Typically, they will be zero.
Some people suggested that the data is stored on the DLL. This is impossible. Is anyone opposed? Well, this is not impossible, but this is impossible to use it. Make you created a shared memory variable visible to all instances of the DLL, this variable is only actually meaningful in the process of storing it. For all other processes, this is just a string bit, and if you try to use it as an address, this address is completely useless or even cause the program to crash.
This separate address space concept is an unhappy concept. Let me use the picture to explain it.
We have three processes here.
Your process is displayed on the left.
DLL
There is code, there is data, and has a shared data segment.
Now as a hook
DLL
Implement a procedure
A
Event interception
,
System automatically
DLL
The address mapped to the private space of the process, that is, the virtual address space of the process, and also copy it.
DLL
A copy of the global data to the process space.
Coincidentally, they will be moved to the process
A
The same virtual address.
process
A
Have its own private copy
Data segment, then process
A
in
Either I saw in "Data"
Private
, Or I can't affect other processes
(
Or affected by other processes
!).
What is troublesome here is
shared
Data segment
(Showing red.) In your processes and processes
A
The same memory page is indicated.
Note, coincidentally, these memory pages appear on the same virtual address.
If you have your progress and processes
A simultaneous debugging
And pay attention to see in a common data segment
& Something
And look at the process
A
In the same
& Something
You will see the same data, even they are in the same address.
If you use the debugger to change, you will see the program change
& Something
Value
You can go to another process, check it, see the new value that appears there.
Let's take a look at what happens in the process B. The DLL is mapped when the event is hooked in the process B. The code is moved to another address in the process in the process. If you debug in the process B, pay attention to & Something in a shared area, you will find that the address of & Something is different, but & Something content will be the same; in your process or the contents of & Something content in your process or process A Changing immediately can see in process B, even if the process B is seen in another address (virtual address). (This is in the same physical memory location). When I mentioned coincidence, "coincidence" refers to being planned; Windows always tries to map the DLL map into the same virtual address, it tries to do so, but it is very successful.
This means that if you store a pointer to the callback function in the DLL, it may point to other addresses when you actually run the process a or process B. This also means that you will not be able to use MFC in the DLL - it cannot be an extended MFC DLL or MFC DLL because these DLLs (Dynamic Link Libraries) call MFC functions.
So where is the MFC function? They are in your address space, not the address space of the process A or process B! Because they may be written in Visual.basic, Java or other languages, you must write Straight-C DLL, and I suggest that you ignore the entire C Runtime Library., Just use the API. Use lstrcpy instead of strcpy or tcscpy, instead of strCMP or TCSCMP with lstrcmp, and so on.
How to make your DLL communicate with your Controlling Server?
A solution will use: postMessage or :: SendMessage function. (I mentioned here is the original API call, not MFC call!) Whenever possible: PostMessage, use it as much as possible to use: SendMessage. Otherwise, if your process is unfortunate, everyone is blocked in a never return :: SendMessage, other processes will stop, then the entire system stops.
You can also consider using the information queue in shared memory area, but that topic is outside this article.
In: Z: SendMessage or :: PostMessage, you can't pass back a pointer (we will ignore the issue of passing a relative pointer to the shared memory area; that is also outside this article). This is because you can use Any address indicated by any pointer is either in the DLL or in the process of hook. (Process A or Process B) So in your process, this pointer is completely useless. You can only return the address space by the information in WPARAM or LPARAM.
I I strongly recommend using registered window messages to this. You can send a message to the Message_Map window and use the ON_REGISTERED_MESSAGE macro here.
Now the key is to get the HWND (handle) of that window. Fortunately, this is easy.