2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Callproc support
5 * FILE: win32ss/user/ntuser/callproc.c
6 * PROGRAMER: Thomas Weidenmueller <w3seek@reactos.com>
10 DBG_DEFAULT_CHANNEL(UserClass
);
12 /* CALLPROC ******************************************************************/
15 GetCallProcHandle(IN PCALLPROCDATA CallProc
)
17 /* FIXME: Check for 64 bit architectures... */
18 return (WNDPROC
)((ULONG_PTR
)UserHMGetHandle(CallProc
) | 0xFFFF0000);
22 DestroyCallProc(_Inout_ PVOID Object
)
24 UserDeleteObject(UserHMGetHandle((PCALLPROCDATA
)Object
), TYPE_CALLPROC
);
29 CreateCallProc(IN PDESKTOP Desktop
,
34 PCALLPROCDATA NewCallProc
;
37 /* We can send any thread pointer to the object manager here,
38 * What's important is the process info */
39 NewCallProc
= (PCALLPROCDATA
)UserCreateObject(gHandleTable
,
44 sizeof(CALLPROCDATA
));
45 if (NewCallProc
!= NULL
)
47 NewCallProc
->pfnClientPrevious
= WndProc
;
48 NewCallProc
->wType
|= Unicode
? UserGetCPDA2U
: UserGetCPDU2A
;
49 NewCallProc
->spcpdNext
= NULL
;
52 /* Release the extra reference (UserCreateObject added 2 references) */
53 if (NewCallProc
!= NULL
) UserDereferenceObject(NewCallProc
);
59 UserGetCallProcInfo(IN HANDLE hCallProc
,
60 OUT PWNDPROC_INFO wpInfo
)
62 PCALLPROCDATA CallProc
;
64 CallProc
= UserGetObject(gHandleTable
,
72 /* Use Handle pEntry->ppi!
73 if (CallProc->pi != GetW32ProcessInfo())
78 wpInfo
->WindowProc
= CallProc
->pfnClientPrevious
;
79 wpInfo
->IsUnicode
= !!(CallProc
->wType
& UserGetCPDA2U
);
85 Based on UserFindCallProc.
89 UserSearchForCallProc(
94 while ( pcpd
&& (pcpd
->pfnClientPrevious
!= WndProc
|| pcpd
->wType
!= Type
) )
96 pcpd
= pcpd
->spcpdNext
;
102 Get Call Proc Data handle for the window proc being requested or create a
103 new Call Proc Data handle to be return for the requested window proc.
115 PCALLPROCDATA CallProc
= NULL
;
118 pti
= PsGetCurrentThreadWin32Thread();
120 if ( Flags
& (UserGetCPDWindow
|UserGetCPDDialog
) ||
121 Flags
& UserGetCPDWndtoCls
)
129 // Search Class call proc data list.
130 if (pCls
->spcpdFirst
)
131 CallProc
= UserSearchForCallProc( pCls
->spcpdFirst
, (WNDPROC
)ProcIn
, Flags
);
133 // No luck, create a new one for the requested proc.
136 if (!pCls
->rpdeskParent
)
138 TRACE("Null DESKTOP Atom %u\n",pCls
->atomClassName
);
142 pDesk
= pCls
->rpdeskParent
;
143 CallProc
= CreateCallProc( pDesk
,
145 !!(Flags
& UserGetCPDA2U
),
149 CallProc
->spcpdNext
= pCls
->spcpdFirst
;
150 (void)InterlockedExchangePointer((PVOID
*)&pCls
->spcpdFirst
,
152 CallProc
->wType
= Flags
;
155 return (ULONG_PTR
)(CallProc
? GetCallProcHandle(CallProc
) : NULL
);
158 /* SYSCALLS *****************************************************************/
161 Retrieve the WinProcA/W or CallProcData handle for Class, Dialog or Window.
162 This Function called from user space uses Window handle for class, window
163 and dialog procs only.
166 ProcIn is the default proc from pCls/pDlg/pWnd->lpfnXxyz, caller is
167 looking for another type of proc if the original lpfnXxyz proc is preset
171 If pWnd is created from Ansi and lpfnXxyz is assumed to be Ansi, caller
172 will ask for Unicode Proc return Proc or CallProcData handle.
182 ULONG_PTR Result
= 0;
184 UserEnterExclusive();
185 if (!(Wnd
= UserGetWindowObject(hWnd
)))
190 // Processing Window only from User space.
191 if ((Flags
& ~(UserGetCPDU2A
|UserGetCPDA2U
)) != UserGetCPDClass
)
192 Result
= UserGetCPD(Wnd
, Flags
, ProcIn
);