ReactOS 0.4.15-dev-7958-gcd0bb1a
lpc_x.h
Go to the documentation of this file.
1/*
2* PROJECT: ReactOS Kernel
3* LICENSE: GPL - See COPYING in the top level directory
4* FILE: ntoskrnl/include/internal/lpc_x.h
5* PURPOSE: Internal Inlined Functions for Local Procedure Call
6* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7*/
8
9//
10// Gets the message type, removing the kernel-mode flag
11//
12#define LpcpGetMessageType(x) \
13 ((x)->u2.s2.Type &~ LPC_KERNELMODE_MESSAGE)
14
15//
16// Waits on an LPC semaphore for a receive operation
17//
18#define LpcpReceiveWait(s, w) \
19{ \
20 LPCTRACE(LPC_REPLY_DEBUG, "Wait: %p\n", s); \
21 Status = KeWaitForSingleObject(s, \
22 WrLpcReceive, \
23 w, \
24 FALSE, \
25 NULL); \
26 LPCTRACE(LPC_REPLY_DEBUG, "Wait done: %lx\n", Status); \
27}
28
29//
30// Waits on an LPC semaphore for a reply operation
31//
32#define LpcpReplyWait(s, w) \
33{ \
34 LPCTRACE(LPC_SEND_DEBUG, "Wait: %p\n", s); \
35 Status = KeWaitForSingleObject(s, \
36 WrLpcReply, \
37 w, \
38 FALSE, \
39 NULL); \
40 LPCTRACE(LPC_SEND_DEBUG, "Wait done: %lx\n", Status); \
41 if (Status == STATUS_USER_APC) \
42 { \
43 /* We were preempted by an APC */ \
44 if (KeReadStateSemaphore(s)) \
45 { \
46 /* It's still signaled, so wait on it */ \
47 KeWaitForSingleObject(s, \
48 WrExecutive, \
49 KernelMode, \
50 FALSE, \
51 NULL); \
52 Status = STATUS_SUCCESS; \
53 } \
54 } \
55}
56
57//
58// Waits on an LPC semaphore for a connect operation
59//
60#define LpcpConnectWait(s, w) \
61{ \
62 LPCTRACE(LPC_CONNECT_DEBUG, "Wait: %p\n", s); \
63 Status = KeWaitForSingleObject(s, \
64 Executive, \
65 w, \
66 FALSE, \
67 NULL); \
68 LPCTRACE(LPC_CONNECT_DEBUG, "Wait done: %lx\n", Status);\
69 if (Status == STATUS_USER_APC) \
70 { \
71 /* We were preempted by an APC */ \
72 if (KeReadStateSemaphore(s)) \
73 { \
74 /* It's still signaled, so wait on it */ \
75 KeWaitForSingleObject(s, \
76 WrExecutive, \
77 KernelMode, \
78 FALSE, \
79 NULL); \
80 Status = STATUS_SUCCESS; \
81 } \
82 } \
83}
84
85//
86// Releases an LPC Semaphore to complete a wait
87//
88#define LpcpCompleteWait(s) \
89{ \
90 /* Release the semaphore */ \
91 LPCTRACE(LPC_SEND_DEBUG, "Release: %p\n", s); \
92 KeReleaseSemaphore(s, 1, 1, FALSE); \
93}
94
95//
96// Allocates a new message
97//
98static __inline
101{
103
104 /* Allocate a message from the port zone while holding the lock */
106 Message = (PLPCP_MESSAGE)ExAllocateFromPagedLookasideList(&LpcpMessagesLookaside);
107 if (!Message)
108 {
109 /* Fail, and let caller cleanup */
111 return NULL;
112 }
113
114 /* Initialize it */
116 Message->RepliedToThread = NULL;
117 Message->Request.u2.ZeroInit = 0;
118
119 /* Release the lock */
121 return Message;
122}
123
124//
125// Get the LPC Message associated to the Thread
126//
130{
131 /* Check if the port flag is set */
132 if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT)
133 {
134 /* The pointer is actually a port, not a message, so return NULL */
135 return NULL;
136 }
137
138 /* Otherwise, this is a message. Return the pointer */
139 return (PLPCP_MESSAGE)((ULONG_PTR)Thread->LpcReplyMessage & ~LPCP_THREAD_FLAGS);
140}
141
145{
146 /* Check if the port flag is set */
147 if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT)
148 {
149 /* The pointer is actually a port, return it */
150 return (PLPCP_PORT_OBJECT)((ULONG_PTR)Thread->LpcWaitingOnPort &
152 }
153
154 /* Otherwise, this is a message. There is nothing to return */
155 return NULL;
156}
157
159VOID
162{
163 /* Set the port object */
164 Thread->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)Port) |
166}
167
171{
172 return (PLPCP_DATA_INFO)((PUCHAR)Message + Message->u2.s2.DataInfoOffset);
173}
#define NULL
Definition: types.h:112
static const WCHAR Message[]
Definition: register.c:74
#define ULONG_PTR
Definition: config.h:101
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
CPPORT Port[4]
Definition: headless.c:35
#define LPCP_THREAD_FLAG_IS_PORT
Definition: lpc.h:55
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
#define LPCP_THREAD_FLAGS
Definition: lpc.h:57
PAGED_LOOKASIDE_LIST LpcpMessagesLookaside
Definition: port.c:19
FORCEINLINE PLPCP_PORT_OBJECT LpcpGetPortFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:144
FORCEINLINE VOID LpcpSetPortToThread(IN PETHREAD Thread, IN PLPCP_PORT_OBJECT Port)
Definition: lpc_x.h:160
FORCEINLINE PLPCP_MESSAGE LpcpGetMessageFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:129
FORCEINLINE PLPCP_DATA_INFO LpcpGetDataInfoFromMessage(PPORT_MESSAGE Message)
Definition: lpc_x.h:170
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
struct _LPCP_MESSAGE * PLPCP_MESSAGE
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
#define FORCEINLINE
Definition: wdftypes.h:67