Difference between revisions of "Techwiki:RegisterUserApiHook"

From ReactOS Wiki
Jump to: navigation, search
Line 1: Line 1:
RegisterUserApiHook is a function that is called once for the entire system and then user32 loads the specified module for each process and calls the specified fnUserApiHook function for that process. It seems to be implemented in user32 to be used exclusively by uxtheme as it abstracts the functionality needed to apply themes in uxtheme.
+
RegisterUserApiHook is a function that is called once for the current user and then user32 loads the specified module for each process and calls the specified fnUserApiHook function for that process. It seems to be implemented in user32 to be used exclusively by uxtheme as it abstracts the functionality needed to apply themes in uxtheme.
  
 
This is the prototype in Windows XP:
 
This is the prototype in Windows XP:

Revision as of 08:07, 20 June 2009

RegisterUserApiHook is a function that is called once for the current user and then user32 loads the specified module for each process and calls the specified fnUserApiHook function for that process. It seems to be implemented in user32 to be used exclusively by uxtheme as it abstracts the functionality needed to apply themes in uxtheme.

This is the prototype in Windows XP:

BOOL WINAPI RegisterUserApiHook(HINSTANCE hInstance, PVOID CallbackFunc);

And this is the prototype in win2k3:

typedef struct _USERAPIHOOKINFO
{
DWORD m_size;
LPCWSTR m_dllname1;
LPCWSTR m_funname1;
LPCWSTR m_dllname2;
LPCWSTR m_funname2;
}USERAPIHOOKINFO,*PUSERAPIHOOKINFO;

BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO ApiHookInfo);

In both cases we give to RegisterUserApiHook the dll that is going to be loaded and the callback function. This is the prototype of the callback function:

typedef struct
{
DWORD size;
WNDPROC DefWindowProcA;
WNDPROC DefWindowProcW;
DWORD* DefWndProcArray;
DWORD DefWndProcArraySize;
FARPROC GetScrollInfo;
FARPROC SetScrollInfo;
FARPROC EnableScrollBar;
FARPROC AdjustWindowRectEx;
FARPROC SetWindowRng;
WNDPROC PreWndProc;
WNDPROC PostWndProc;
DWORD* WndProcArray;
DWORD WndProcArraySize;
WNDPROC PreDefDlgProc;
WNDPROC PostDefDlgProc;
DWORD* DlgProcArray;
DWORD DlgProcArraySize;
FARPROC GetSystemMetrics;
FARPROC SystemParametersInfoA;
FARPROC SystemParametersInfoW;
FARPROC ForceResetUserApiHook;
FARPROC DrawFrameControl;
FARPROC DrawCaption;
FARPROC MDIRedrawFrame;
} APIHOOKINFO, *PAPIHOOKINFO;

typedef DWORD (CALLBACK * USERAPIHOOKPROC)(DWORD State, PAPIHOOKINFO ApiHookInfo);


User32 gives to the callback function an APIHOOKINFO struct filled with the original implementation of the functions that the library can use from user32. Then the callback replaces the functions from user32 with its own functions. So for example if a program calls DefWindowProc, user32 instead of calling its implementation it calls the function that the loaded libriary provided.


If an application has installed the api hook, any call to RegisterUserApiHook will fail. Api hook is uninstalled if the process that called RegisterUserApiHook calls UnregisterUserApiHook, or if it is terminated.


In Windows XP the callback function is internal in uxtheme.dll and isn’t exported. However in Windows 2003 this function must be exported because RegisterUserApiHook must be given its name and not a pointer to it. It is exported from uxtheme.dll with the name ThemeInitApiHook.


The weirdest things in the APIHOOKINFO struct are the DefWndProcArray, WndProcArray and DlgProcArray fields. These seem to control when the overridden DefWindowProc, Pre/PostWndProc and PreDefDlgProc will be called. If they are set to NULL, the new functions never get called. By testing ThemeInitApiHook, I could dump the contents of these arrays. If I use these, the overridden functions are called correctly in both Windows XP and 2003 :

DWORD DefWindowProcMagic[25]= {0x1000, 0x0, 0x80, 0x28000000, 0x75, 0xc003, 0x0, 0x0,
             0x40000,0x01240000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x4,0x0,0x0,0x9800000};
DWORD PrePostWindowProcMagic[25]= {0x4000002,0x1800,0xc0,0x30000000,0x26,0x0,0x0,0x0,0x0,0x1,
                    0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10000,0x0,0x0,0x0,0x0,0x0,0x0,0xc000000};



References

http://www.winehq.org/pipermail/wine-devel/2005-March/035286.html

http://www.winehq.org/pipermail/wine-devel/2005-March/035245.html

http://www.arabteam2000-forum.com/lofiversion/index.php/t139449.html