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/ntu... ============================================================================== --- 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();