Author: jimtabor
Date: Wed Aug 12 09:35:15 2009
New Revision: 42632
URL:
http://svn.reactos.org/svn/reactos?rev=42632&view=rev
Log:
Rewrite NtUserGetCPD to correctly return the callproc handle pointer.
Modified:
trunk/reactos/subsystems/win32/win32k/ntuser/callproc.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/callproc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/nt…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/ntuser/callproc.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/win32k/ntuser/callproc.c [iso-8859-1] Wed Aug 12
09:35:15 2009
@@ -111,6 +111,72 @@
return TRUE;
}
+/*
+ Based on UserFindCallProc.
+ */
+PCALLPROCDATA
+FASTCALL
+UserSearchForCallProc(
+ PCALLPROCDATA pcpd,
+ WNDPROC WndProc,
+ GETCPD Type)
+{
+ while ( pcpd && (pcpd->pfnClientPrevious != WndProc || pcpd->wType !=
Type) )
+ {
+ pcpd = pcpd->spcpdNext;
+ }
+ return pcpd;
+}
+
+/*
+ Get Call Proc Data handle for the window proc being requested or create a
+ new Call Proc Data handle to be return for the requested window proc.
+ */
+ULONG_PTR
+FASTCALL
+UserGetCPD(
+ PVOID pvClsWnd,
+ GETCPD Flags,
+ ULONG_PTR ProcIn)
+{
+ PCLS pCls;
+ PWND pWnd;
+ PCALLPROCDATA CallProc = NULL;
+ PTHREADINFO pti;
+
+ pti = PsGetCurrentThreadWin32Thread();
+
+ if ( Flags & (UserGetCPDWindow|UserGetCPDDialog) ||
+ Flags & UserGetCPDWndtoCls)
+ {
+ pWnd = pvClsWnd;
+ pCls = pWnd->pcls;
+ }
+ else
+ pCls = pvClsWnd;
+
+ // Search Class call proc data list.
+ if (pCls->spcpdFirst)
+ CallProc = UserSearchForCallProc( pCls->spcpdFirst, (WNDPROC)ProcIn, Flags);
+
+ // No luck, create a new one for the requested proc.
+ if (!CallProc)
+ {
+ CallProc = CreateCallProc( NULL,
+ (WNDPROC)ProcIn,
+ (Flags & UserGetCPDU2A),
+ pti->ppi);
+ if (CallProc)
+ {
+ CallProc->spcpdNext = pCls->spcpdFirst;
+ (void)InterlockedExchangePointer((PVOID*)&pCls->spcpdFirst,
+ CallProc);
+ CallProc->wType = Flags;
+ }
+ }
+ return (ULONG_PTR)(CallProc ? GetCallProcHandle(CallProc) : NULL);
+}
+
/* SYSCALLS *****************************************************************/
/*
@@ -138,9 +204,7 @@
{
PWINDOW_OBJECT Window;
PWND Wnd;
- PCLS Class;
ULONG_PTR Result = 0;
- BOOL Ansi;
UserEnterExclusive();
if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd)
@@ -148,18 +212,10 @@
goto Cleanup;
}
Wnd = Window->Wnd;
- Class = Wnd->pcls;
- /* Ex: Retrieve the Unicode Proc since the default is Ansi. */
- Ansi = (Flags & UserGetCPDA2U); // Ansi to Unicode request from user.
-
- if ( Flags & (UserGetCPDWindow|UserGetCPDDialog))
- {
- Result = UserGetWindowLong( hWnd, GWL_WNDPROC, Ansi);
- }
- else if (Flags & (UserGetCPDClass|UserGetCPDWndtoCls))
- {
- Result = UserGetClassLongPtr( Class, GCLP_WNDPROC, Ansi);
- }
+
+ // Processing Window only from User space.
+ if ((Flags & ~(UserGetCPDU2A|UserGetCPDA2U)) != UserGetCPDClass)
+ Result = UserGetCPD(Wnd, Flags, ProcIn);
Cleanup:
UserLeave();