Difference between revisions of "Techwiki:RegisterUserApiHook"

From ReactOS Wiki
Jump to: navigation, search
 
(19 intermediate revisions by 3 users not shown)
Line 1: Line 1:
RegisterUserApiHook seems to be implemlemented in user32 to be used exclusively by uxtheme. Actually it abstracts the functionality need to apply themes in uxtheme. The problem with this function is that it is changed it through Windows releases so it is more difficult to test it.
+
RegisterUserApiHook is a function that is called once per session and makes user32 load the specified module for each process and call the specified callback function. It is implemented in user32 to be used exclusively by uxtheme as it abstracts the functionality needed to apply themes in all windows.
RegisterUserApiHook works in the same way a global hook works. The only difference is that right after user32 loads the specified library into every application, it calls the (specified) callback to give the ability to the loaded library to override some functionality that exists in use32.  
 
  
 +
This is the prototype in Windows XP:
  
This is the prototype in windows xp:
+
  BOOL WINAPI RegisterUserApiHook(HINSTANCE hInstance, FARPROC CallbackFunc);
 
 
 
 
  BOOL WINAPI RegisterUserApiHook(HINSTANCE hInstance, PVOID Callback);
 
 
 
 
 
 
 
And this is the prototype in win2k3:
 
  
 +
And this is the prototype in Windows 2003:
  
 
  typedef struct _USERAPIHOOKINFO
 
  typedef struct _USERAPIHOOKINFO
 
  {
 
  {
DWORD m_size;
+
  DWORD m_size;
LPCWSTR m_dllname1;
+
  LPCWSTR m_dllname1;
LPCWSTR m_funname1;
+
  LPCWSTR m_funname1;
LPCWSTR m_dllname2;
+
  LPCWSTR m_dllname2;
LPCWSTR m_funname2;
+
  LPCWSTR m_funname2;
 
  }USERAPIHOOKINFO,*PUSERAPIHOOKINFO;
 
  }USERAPIHOOKINFO,*PUSERAPIHOOKINFO;
 +
 
  BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO ApiHookInfo);
 
  BOOL WINAPI RegisterUserApiHook(PUSERAPIHOOKINFO ApiHookInfo);
 +
 +
In both cases we give to RegisterUserApiHook the dll that is going to be loaded and the callback function.
  
  
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:  
 
This is the prototype of the callback function:  
  
 
+
typedef LRESULT(CALLBACK *WNDPROC_OWP)(HWND,UINT,WPARAM,LPARAM,ULONG_PTR,PDWORD);
  typedef struct
+
 +
  typedef struct _UAHOWP
 +
{
 +
  BYTE*  MsgBitArray;
 +
  DWORD  Size;
 +
} UAHOWP, *PUAHOWP;
 +
 +
typedef struct tagUSERAPIHOOK
 +
{
 +
  DWORD  size;
 +
  WNDPROC DefWindowProcA;
 +
  WNDPROC DefWindowProcW;
 +
  UAHOWP  DefWndProcArray;
 +
  FARPROC GetScrollInfo;
 +
  FARPROC SetScrollInfo;
 +
  FARPROC EnableScrollBar;
 +
  FARPROC AdjustWindowRectEx;
 +
  FARPROC SetWindowRgn;
 +
  WNDPROC_OWP PreWndProc;
 +
  WNDPROC_OWP PostWndProc;
 +
  UAHOWP  WndProcArray;
 +
  WNDPROC_OWP PreDefDlgProc;
 +
  WNDPROC_OWP PostDefDlgProc;
 +
  UAHOWP  DlgProcArray;
 +
  FARPROC GetSystemMetrics;
 +
  FARPROC SystemParametersInfoA;
 +
  FARPROC SystemParametersInfoW;
 +
  FARPROC ForceResetUserApiHook;
 +
  FARPROC DrawFrameControl;
 +
  FARPROC DrawCaption;
 +
  FARPROC MDIRedrawFrame;
 +
  FARPROC GetRealWindowOwner;
 +
} USERAPIHOOK, *PUSERAPIHOOK;
 +
 +
typedef enum _UAPIHK
 
  {
 
  {
DWORD size;
+
  uahLoadInit,
WNDPROC DefWindowProcA;
+
  uahStop,
WNDPROC DefWindowProcW;
+
  uahShutdown
  DWORD* DefWndProcArray;
+
  } UAPIHK, *PUAPIHK;
DWORD DefWndProcArraySize;
+
   
FARPROC GetScrollInfo;
+
   
FARPROC SetScrollInfo;
+
  DWORD CALLBACK
FARPROC EnableScrollBar;
+
  UserApiHookProc(UAPIHK State, PUSERAPIHOOK Info);
  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 function replaces the functions from user32 with its own functions.
 
The most strange thing in APIHOOKINFO struct are the  DefWndProcArray, WndProcArray and DlgProcArray fields.
 
These fields seem to control when overridden DefWindowProc, Pre/PostWndProc and PreDefDlgProc will be called. If they are set to NULL, the overridden functions never get called.
 
 
 
  
However, when testing in win2k3, I called ThemeInitApiHook and dumped the contents of these arrays. If I use these, the overridden functions are called correctly (in both xp and win2k3) :
 
  
 +
User32 gives to the callback function an USERAPIHOOK 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 specified by the UserApiHook callback.
  
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};
 
  
 +
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.
  
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};
 
  
  
 +
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.
  
  
Line 82: Line 84:
  
 
http://www.winehq.org/pipermail/wine-devel/2005-March/035245.html
 
http://www.winehq.org/pipermail/wine-devel/2005-March/035245.html
 +
 +
http://www.arabteam2000-forum.com/lofiversion/index.php/t139449.html

Latest revision as of 14:51, 2 May 2011

RegisterUserApiHook is a function that is called once per session and makes user32 load the specified module for each process and call the specified callback function. It is implemented in user32 to be used exclusively by uxtheme as it abstracts the functionality needed to apply themes in all windows.

This is the prototype in Windows XP:

BOOL WINAPI RegisterUserApiHook(HINSTANCE hInstance, FARPROC CallbackFunc);

And this is the prototype in Windows 2003:

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 LRESULT(CALLBACK *WNDPROC_OWP)(HWND,UINT,WPARAM,LPARAM,ULONG_PTR,PDWORD);

typedef struct _UAHOWP
{
  BYTE*  MsgBitArray;
  DWORD  Size;
} UAHOWP, *PUAHOWP;

typedef struct tagUSERAPIHOOK
{
  DWORD   size;
  WNDPROC DefWindowProcA;
  WNDPROC DefWindowProcW;
  UAHOWP  DefWndProcArray;
  FARPROC GetScrollInfo;
  FARPROC SetScrollInfo;
  FARPROC EnableScrollBar;
  FARPROC AdjustWindowRectEx;
  FARPROC SetWindowRgn;
  WNDPROC_OWP PreWndProc;
  WNDPROC_OWP PostWndProc;
  UAHOWP  WndProcArray;
  WNDPROC_OWP PreDefDlgProc;
  WNDPROC_OWP PostDefDlgProc;
  UAHOWP  DlgProcArray;
  FARPROC GetSystemMetrics;
  FARPROC SystemParametersInfoA;
  FARPROC SystemParametersInfoW;
  FARPROC ForceResetUserApiHook;
  FARPROC DrawFrameControl;
  FARPROC DrawCaption;
  FARPROC MDIRedrawFrame;
  FARPROC GetRealWindowOwner;
} USERAPIHOOK, *PUSERAPIHOOK;

typedef enum _UAPIHK
{
  uahLoadInit,
  uahStop,
  uahShutdown
} UAPIHK, *PUAPIHK;


DWORD CALLBACK 
UserApiHookProc(UAPIHK State, PUSERAPIHOOK Info);


User32 gives to the callback function an USERAPIHOOK 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 specified by the UserApiHook callback.


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.


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