ReactOS  0.4.14-dev-41-g31d7680
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 //
98 static __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 */
115  InitializeListHead(&Message->Entry);
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 
159 VOID
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 }
CPPORT Port[4]
Definition: headless.c:34
#define IN
Definition: typedefs.h:38
FORCEINLINE PLPCP_DATA_INFO LpcpGetDataInfoFromMessage(PPORT_MESSAGE Message)
Definition: lpc_x.h:170
FORCEINLINE VOID LpcpSetPortToThread(IN PETHREAD Thread, IN PLPCP_PORT_OBJECT Port)
Definition: lpc_x.h:160
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
PAGED_LOOKASIDE_LIST LpcpMessagesLookaside
Definition: port.c:19
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
unsigned char * PUCHAR
Definition: retypes.h:3
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE PLPCP_MESSAGE LpcpGetMessageFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:129
smooth NULL
Definition: ftsmooth.c:416
#define FORCEINLINE
Definition: ntbasedef.h:221
void * PVOID
Definition: retypes.h:9
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
FORCEINLINE PLPCP_PORT_OBJECT LpcpGetPortFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:144
#define LPCP_THREAD_FLAG_IS_PORT
Definition: lpc.h:55
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CHAR Message[80]
Definition: alive.c:5
struct _LPCP_MESSAGE * PLPCP_MESSAGE
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ULONG_PTR
Definition: config.h:101
#define LPCP_THREAD_FLAGS
Definition: lpc.h:57