}
}
+
+//
+// Pass the Current Window handle and pointer to the Client Callback.
+// This will help user space programs speed up read access with the window object.
+//
+static VOID
+IntSetTebWndCallback (HWND * hWnd, PVOID * pWnd)
+{
+ HWND hWndS = *hWnd;
+ PWINDOW_OBJECT Window = UserGetWindowObject(*hWnd);
+ PTEB Teb = NtCurrentTeb();
+
+ *hWnd = Teb->Win32ClientInfo.hWND;
+ *pWnd = Teb->Win32ClientInfo.pvWND;
+
+ Teb->Win32ClientInfo.hWND = hWndS;
+ Teb->Win32ClientInfo.pvWND = (PVOID) Window;
+}
+
+static VOID
+IntRestoreTebWndCallback (HWND hWnd, PVOID pWnd)
+{
+ PTEB Teb = NtCurrentTeb();
+
+ Teb->Win32ClientInfo.hWND = hWnd;
+ Teb->Win32ClientInfo.pvWND = pWnd;
+}
+
/* FUNCTIONS *****************************************************************/
VOID STDCALL
LRESULT Result)
{
SENDASYNCPROC_CALLBACK_ARGUMENTS Arguments;
- PVOID ResultPointer;
+ PVOID ResultPointer, pWnd;
ULONG ResultLength;
NTSTATUS Status;
Arguments.Context = CompletionCallbackContext;
Arguments.Result = Result;
+ IntSetTebWndCallback (&hWnd, &pWnd);
+
UserLeaveCo();
Status = KeUserModeCallback(USER32_CALLBACK_SENDASYNCPROC,
UserEnterCo();
+ IntRestoreTebWndCallback (hWnd, pWnd);
+
if (!NT_SUCCESS(Status))
{
return;
WINDOWPROC_CALLBACK_ARGUMENTS StackArguments;
PWINDOWPROC_CALLBACK_ARGUMENTS Arguments;
NTSTATUS Status;
- PVOID ResultPointer;
+ PVOID ResultPointer, pWnd;
ULONG ResultLength;
ULONG ArgumentLength;
LRESULT Result;
ResultPointer = NULL;
ResultLength = ArgumentLength;
+ IntSetTebWndCallback (&Wnd, &pWnd);
+
UserLeaveCo();
Status = KeUserModeCallback(USER32_CALLBACK_WINDOWPROC,
UserEnterCo();
+ IntRestoreTebWndCallback (Wnd, pWnd);
+
if (!NT_SUCCESS(Status))
{
if (0 < lParamBufferSize)