2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Callproc support
5 * FILE: subsystems/win32/win32k/ntuser/callproc.c
6 * PROGRAMER: Thomas Weidenmueller <w3seek@reactos.com>
11 /* CALLPROC ******************************************************************/
14 GetCallProcHandle(IN PCALLPROCDATA CallProc
)
16 /* FIXME: Check for 64 bit architectures... */
17 return (WNDPROC
)((ULONG_PTR
)UserHMGetHandle(CallProc
) | 0xFFFF0000);
21 DestroyCallProc(_Inout_ PVOID Object
)
23 UserDeleteObject(UserHMGetHandle((PCALLPROCDATA
)Object
), TYPE_CALLPROC
);
28 CreateCallProc(IN PDESKTOP Desktop
,
33 PCALLPROCDATA NewCallProc
;
36 /* We can send any thread pointer to the object manager here,
37 * What's important is the process info */
38 NewCallProc
= (PCALLPROCDATA
)UserCreateObject(gHandleTable
,
43 sizeof(CALLPROCDATA
));
44 if (NewCallProc
!= NULL
)
46 NewCallProc
->pfnClientPrevious
= WndProc
;
47 NewCallProc
->wType
|= Unicode
? UserGetCPDA2U
: UserGetCPDU2A
;
48 NewCallProc
->spcpdNext
= NULL
;
51 /* Release the extra reference (UserCreateObject added 2 references) */
52 UserDereferenceObject(NewCallProc
);
58 UserGetCallProcInfo(IN HANDLE hCallProc
,
59 OUT PWNDPROC_INFO wpInfo
)
61 PCALLPROCDATA CallProc
;
63 CallProc
= UserGetObject(gHandleTable
,
71 /* Use Handle pEntry->ppi!
72 if (CallProc->pi != GetW32ProcessInfo())
77 wpInfo
->WindowProc
= CallProc
->pfnClientPrevious
;
78 wpInfo
->IsUnicode
= !!(CallProc
->wType
& UserGetCPDA2U
);
84 Based on UserFindCallProc.
88 UserSearchForCallProc(
93 while ( pcpd
&& (pcpd
->pfnClientPrevious
!= WndProc
|| pcpd
->wType
!= Type
) )
95 pcpd
= pcpd
->spcpdNext
;
101 Get Call Proc Data handle for the window proc being requested or create a
102 new Call Proc Data handle to be return for the requested window proc.
113 PCALLPROCDATA CallProc
= NULL
;
116 pti
= PsGetCurrentThreadWin32Thread();
118 if ( Flags
& (UserGetCPDWindow
|UserGetCPDDialog
) ||
119 Flags
& UserGetCPDWndtoCls
)
127 // Search Class call proc data list.
128 if (pCls
->spcpdFirst
)
129 CallProc
= UserSearchForCallProc( pCls
->spcpdFirst
, (WNDPROC
)ProcIn
, Flags
);
131 // No luck, create a new one for the requested proc.
134 CallProc
= CreateCallProc( pCls
->rpdeskParent
,
136 !!(Flags
& UserGetCPDA2U
),
140 CallProc
->spcpdNext
= pCls
->spcpdFirst
;
141 (void)InterlockedExchangePointer((PVOID
*)&pCls
->spcpdFirst
,
143 CallProc
->wType
= Flags
;
146 return (ULONG_PTR
)(CallProc
? GetCallProcHandle(CallProc
) : NULL
);
149 /* SYSCALLS *****************************************************************/
152 Retrieve the WinProcA/W or CallProcData handle for Class, Dialog or Window.
153 This Function called from user space uses Window handle for class, window
154 and dialog procs only.
157 ProcIn is the default proc from pCls/pDlg/pWnd->lpfnXxyz, caller is
158 looking for another type of proc if the original lpfnXxyz proc is preset
162 If pWnd is created from Ansi and lpfnXxyz is assumed to be Ansi, caller
163 will ask for Unicode Proc return Proc or CallProcData handle.
173 ULONG_PTR Result
= 0;
175 UserEnterExclusive();
176 if (!(Wnd
= UserGetWindowObject(hWnd
)))
181 // Processing Window only from User space.
182 if ((Flags
& ~(UserGetCPDU2A
|UserGetCPDA2U
)) != UserGetCPDClass
)
183 Result
= UserGetCPD(Wnd
, Flags
, ProcIn
);