ReactOS  0.4.14-dev-583-g2a1ba2c
send.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for send.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI LpcRequestPort (IN PVOID PortObject, IN PPORT_MESSAGE LpcMessage)
 
NTSTATUS NTAPI LpcRequestWaitReplyPort (IN PVOID PortObject, IN PPORT_MESSAGE LpcRequest, OUT PPORT_MESSAGE LpcReply)
 
NTSTATUS NTAPI NtRequestPort (IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest)
 
NTSTATUS NTAPI LpcpVerifyMessageDataInfo (_In_ PPORT_MESSAGE Message, _Out_ PULONG NumberOfDataEntries)
 
NTSTATUS NTAPI NtRequestWaitReplyPort (IN HANDLE PortHandle, IN PPORT_MESSAGE LpcRequest, IN OUT PPORT_MESSAGE LpcReply)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 12 of file send.c.

Function Documentation

◆ LpcpVerifyMessageDataInfo()

NTSTATUS NTAPI LpcpVerifyMessageDataInfo ( _In_ PPORT_MESSAGE  Message,
_Out_ PULONG  NumberOfDataEntries 
)

Definition at line 651 of file send.c.

654 {
655  PLPCP_DATA_INFO DataInfo;
656  PUCHAR EndOfEntries;
657 
658  /* Check if we have no data info at all */
659  if (Message->u2.s2.DataInfoOffset == 0)
660  {
661  *NumberOfDataEntries = 0;
662  return STATUS_SUCCESS;
663  }
664 
665  /* Make sure the data info structure is within the message */
666  if (((ULONG)Message->u1.s1.TotalLength <
667  sizeof(PORT_MESSAGE) + sizeof(LPCP_DATA_INFO)) ||
668  ((ULONG)Message->u2.s2.DataInfoOffset < sizeof(PORT_MESSAGE)) ||
669  ((ULONG)Message->u2.s2.DataInfoOffset >
670  ((ULONG)Message->u1.s1.TotalLength - sizeof(LPCP_DATA_INFO))))
671  {
673  }
674 
675  /* Get a pointer to the data info */
677 
678  /* Make sure the full data info with all entries is within the message */
679  EndOfEntries = (PUCHAR)&DataInfo->Entries[DataInfo->NumberOfEntries];
680  if ((EndOfEntries > ((PUCHAR)Message + (ULONG)Message->u1.s1.TotalLength)) ||
681  (EndOfEntries < (PUCHAR)Message))
682  {
684  }
685 
686  *NumberOfDataEntries = DataInfo->NumberOfEntries;
687  return STATUS_SUCCESS;
688 }
struct _LPCP_DATA_INFO::@1739 Entries[1]
FORCEINLINE PLPCP_DATA_INFO LpcpGetDataInfoFromMessage(PPORT_MESSAGE Message)
Definition: lpc_x.h:170
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
unsigned char * PUCHAR
Definition: retypes.h:3
if(!(yy_init))
Definition: macro.lex.yy.c:714
ULONG NumberOfEntries
Definition: lpc.h:69
CHAR Message[80]
Definition: alive.c:5
unsigned int ULONG
Definition: retypes.h:1
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by NtRequestWaitReplyPort().

◆ LpcRequestPort()

NTSTATUS NTAPI LpcRequestPort ( IN PVOID  PortObject,
IN PPORT_MESSAGE  LpcMessage 
)

Definition at line 22 of file send.c.

24 {
25  PLPCP_PORT_OBJECT Port = PortObject, QueuePort, ConnectionPort = NULL;
26  ULONG MessageType;
30 
31  PAGED_CODE();
32 
33  LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", Port, LpcMessage);
34 
35  /* Check if this is a non-datagram message */
36  if (LpcMessage->u2.s2.Type)
37  {
38  /* Get the message type */
39  MessageType = LpcpGetMessageType(LpcMessage);
40 
41  /* Validate it */
42  if ((MessageType < LPC_DATAGRAM) || (MessageType > LPC_CLIENT_DIED))
43  {
44  /* Fail */
46  }
47 
48  /* Mark this as a kernel-mode message only if we really came from it */
49  if ((PreviousMode == KernelMode) &&
50  (LpcMessage->u2.s2.Type & LPC_KERNELMODE_MESSAGE))
51  {
52  /* We did, this is a kernel mode message */
53  MessageType |= LPC_KERNELMODE_MESSAGE;
54  }
55  }
56  else
57  {
58  /* This is a datagram */
59  MessageType = LPC_DATAGRAM;
60  }
61 
62  /* Can't have data information on this type of call */
63  if (LpcMessage->u2.s2.DataInfoOffset) return STATUS_INVALID_PARAMETER;
64 
65  /* Validate the message length */
66  if (((ULONG)LpcMessage->u1.s1.TotalLength > Port->MaxMessageLength) ||
67  ((ULONG)LpcMessage->u1.s1.TotalLength <= (ULONG)LpcMessage->u1.s1.DataLength))
68  {
69  /* Fail */
71  }
72 
73  /* Allocate a new message */
75  if (!Message) return STATUS_NO_MEMORY;
76 
77  /* Clear the context */
78  Message->RepliedToThread = NULL;
79  Message->PortContext = NULL;
80 
81  /* Copy the message */
82  LpcpMoveMessage(&Message->Request,
83  LpcMessage,
84  LpcMessage + 1,
85  MessageType,
86  &Thread->Cid);
87 
88  /* Acquire the LPC lock */
90 
91  /* Check if this is anything but a connection port */
93  {
94  /* The queue port is the connected port */
95  QueuePort = Port->ConnectedPort;
96  if (QueuePort)
97  {
98  /* Check if this is a client port */
100  {
101  /* Then copy the context */
102  Message->PortContext = QueuePort->PortContext;
103  ConnectionPort = QueuePort = Port->ConnectionPort;
104  if (!ConnectionPort)
105  {
106  /* Fail */
109  }
110  }
112  {
113  /* Any other kind of port, use the connection port */
114  ConnectionPort = QueuePort = Port->ConnectionPort;
115  if (!ConnectionPort)
116  {
117  /* Fail */
120  }
121  }
122 
123  /* If we have a connection port, reference it */
124  if (ConnectionPort) ObReferenceObject(ConnectionPort);
125  }
126  }
127  else
128  {
129  /* For connection ports, use the port itself */
130  QueuePort = PortObject;
131  }
132 
133  /* Make sure we have a port */
134  if (QueuePort)
135  {
136  /* Generate the Message ID and set it */
137  Message->Request.MessageId = LpcpNextMessageId++;
139  Message->Request.CallbackId = 0;
140 
141  /* No Message ID for the thread */
142  Thread->LpcReplyMessageId = 0;
143 
144  /* Insert the message in our chain */
145  InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry);
146 
147  /* Release the lock and the semaphore */
150  LpcpCompleteWait(QueuePort->MsgQueue.Semaphore);
151 
152  /* If this is a waitable port, wake it up */
153  if (QueuePort->Flags & LPCP_WAITABLE_PORT)
154  {
155  /* Wake it */
156  KeSetEvent(&QueuePort->WaitEvent, IO_NO_INCREMENT, FALSE);
157  }
158 
160 
161  /* We're done */
162  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
163  LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", QueuePort, Message);
164  return STATUS_SUCCESS;
165  }
166 
167  /* If we got here, then free the message and fail */
169  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
171 }
#define LpcpGetMessageType(x)
Definition: lpc_x.h:12
CPPORT Port[4]
Definition: headless.c:34
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
#define LPC_SEND_DEBUG
Definition: lpc.h:23
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define LpcpCompleteWait(s)
Definition: lpc_x.h:88
VOID NTAPI LpcpMoveMessage(IN PPORT_MESSAGE Destination, IN PPORT_MESSAGE Origin, IN PVOID Data, IN ULONG MessageType, IN PCLIENT_ID ClientId)
Definition: reply.c:139
#define KeGetPreviousMode()
Definition: ketypes.h:1107
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define LPCP_LOCK_RELEASE
Definition: lpc.h:64
#define LPC_KERNELMODE_MESSAGE
#define InsertTailList(ListHead, Entry)
#define LPCP_PORT_TYPE_MASK
Definition: lpctypes.h:58
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define PAGED_CODE()
Definition: video.h:57
ULONG LpcpNextMessageId
Definition: port.c:22
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
USHORT Flags
Definition: cportlib.h:31
smooth NULL
Definition: ftsmooth.c:416
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
CLIENT_ID Cid
Definition: pstypes.h:1059
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
CHAR Message[80]
Definition: alive.c:5
#define LPCP_LOCK_HELD
Definition: lpc.h:63
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
VOID NTAPI LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, IN ULONG LockFlags)
Definition: close.c:52
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define STATUS_PORT_MESSAGE_TOO_LONG
Definition: ntstatus.h:270
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ObReferenceObject
Definition: obfuncs.h:204
#define LPCP_COMMUNICATION_PORT
Definition: lpctypes.h:56
#define STATUS_PORT_DISCONNECTED
Definition: ntstatus.h:277
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49
#define LPCP_CLIENT_PORT
Definition: lpctypes.h:57

Referenced by CsrClientCallServer(), LpcpDeletePort(), and PspExitThread().

◆ LpcRequestWaitReplyPort()

NTSTATUS NTAPI LpcRequestWaitReplyPort ( IN PVOID  PortObject,
IN PPORT_MESSAGE  LpcRequest,
OUT PPORT_MESSAGE  LpcReply 
)

Definition at line 178 of file send.c.

181 {
186  PLPCP_PORT_OBJECT QueuePort, ReplyPort, ConnectionPort = NULL;
187  USHORT MessageType;
190  PKSEMAPHORE Semaphore;
191 
192  PAGED_CODE();
193 
195  "Port: %p. Messages: %p/%p. Type: %lx\n",
196  Port,
197  LpcRequest,
198  LpcReply,
199  LpcpGetMessageType(LpcRequest));
200 
201  /* Check if the thread is dying */
203 
204  /* Check if this is an LPC Request */
205  MessageType = LpcpGetMessageType(LpcRequest);
206  switch (MessageType)
207  {
208  /* No type, assume LPC request */
209  case 0:
210  MessageType = LPC_REQUEST;
211  break;
212 
213  /* LPC request callback */
214  case LPC_REQUEST:
215  Callback = TRUE;
216  break;
217 
218  /* Anything else, nothing to do */
219  case LPC_CLIENT_DIED:
220  case LPC_PORT_CLOSED:
221  case LPC_EXCEPTION:
222  case LPC_DEBUG_EVENT:
223  case LPC_ERROR_EVENT:
224  break;
225 
226  /* Invalid message type */
227  default:
229  }
230 
231  /* Set the request type */
232  LpcRequest->u2.s2.Type = MessageType;
233 
234  /* Validate the message length */
235  if (((ULONG)LpcRequest->u1.s1.TotalLength > Port->MaxMessageLength) ||
236  ((ULONG)LpcRequest->u1.s1.TotalLength <= (ULONG)LpcRequest->u1.s1.DataLength))
237  {
238  /* Fail */
240  }
241 
242  /* Allocate a message from the port zone */
244  if (!Message)
245  {
246  /* Fail if we couldn't allocate a message */
247  return STATUS_NO_MEMORY;
248  }
249 
250  /* Check if this is a callback */
251  if (Callback)
252  {
253  /* FIXME: TODO */
254  Semaphore = NULL; // we'd use the Thread Semaphore here
255  ASSERT(FALSE);
256  return STATUS_NOT_IMPLEMENTED;
257  }
258  else
259  {
260  /* No callback, just copy the message */
261  LpcpMoveMessage(&Message->Request,
262  LpcRequest,
263  LpcRequest + 1,
264  0,
265  &Thread->Cid);
266 
267  /* Acquire the LPC lock */
269 
270  /* Right now clear the port context */
271  Message->PortContext = NULL;
272 
273  /* Check if this is a not connection port */
275  {
276  /* We want the connected port */
277  QueuePort = Port->ConnectedPort;
278  if (!QueuePort)
279  {
280  /* We have no connected port, fail */
283  }
284 
285  /* This will be the rundown port */
286  ReplyPort = QueuePort;
287 
288  /* Check if this is a communication port */
290  {
291  /* Copy the port context and use the connection port */
292  Message->PortContext = QueuePort->PortContext;
293  ConnectionPort = QueuePort = Port->ConnectionPort;
294  if (!ConnectionPort)
295  {
296  /* Fail */
299  }
300  }
301  else if ((Port->Flags & LPCP_PORT_TYPE_MASK) !=
303  {
304  /* Use the connection port for anything but communication ports */
305  ConnectionPort = QueuePort = Port->ConnectionPort;
306  if (!ConnectionPort)
307  {
308  /* Fail */
311  }
312  }
313 
314  /* Reference the connection port if it exists */
315  if (ConnectionPort) ObReferenceObject(ConnectionPort);
316  }
317  else
318  {
319  /* Otherwise, for a connection port, use the same port object */
320  QueuePort = ReplyPort = Port;
321  }
322 
323  /* No reply thread */
324  Message->RepliedToThread = NULL;
325  Message->SenderPort = Port;
326 
327  /* Generate the Message ID and set it */
328  Message->Request.MessageId = LpcpNextMessageId++;
330  Message->Request.CallbackId = 0;
331 
332  /* Set the message ID for our thread now */
333  Thread->LpcReplyMessageId = Message->Request.MessageId;
334  Thread->LpcReplyMessage = NULL;
335 
336  /* Insert the message in our chain */
337  InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry);
340 
341  /* Release the lock and get the semaphore we'll use later */
344  Semaphore = QueuePort->MsgQueue.Semaphore;
345 
346  /* If this is a waitable port, wake it up */
347  if (QueuePort->Flags & LPCP_WAITABLE_PORT)
348  {
349  /* Wake it */
350  KeSetEvent(&QueuePort->WaitEvent, IO_NO_INCREMENT, FALSE);
351  }
352  }
353 
354  /* Now release the semaphore */
355  LpcpCompleteWait(Semaphore);
357 
358  /* And let's wait for the reply */
359  LpcpReplyWait(&Thread->LpcReplySemaphore, PreviousMode);
360 
361  /* Acquire the LPC lock */
363 
364  /* Get the LPC Message and clear our thread's reply data */
366  Thread->LpcReplyMessage = NULL;
367  Thread->LpcReplyMessageId = 0;
368 
369  /* Check if we have anything on the reply chain*/
371  {
372  /* Remove this thread and reinitialize the list */
375  }
376 
377  /* Release the lock */
379 
380  /* Check if we got a reply */
381  if (Status == STATUS_SUCCESS)
382  {
383  /* Check if we have a valid message */
384  if (Message)
385  {
387  "Reply Messages: %p/%p\n",
388  &Message->Request,
389  (&Message->Request) + 1);
390 
391  /* Move the message */
392  LpcpMoveMessage(LpcReply,
393  &Message->Request,
394  (&Message->Request) + 1,
395  0,
396  NULL);
397 
398  /* Acquire the lock */
400 
401  /* Check if we replied to a thread */
402  if (Message->RepliedToThread)
403  {
404  /* Dereference */
405  ObDereferenceObject(Message->RepliedToThread);
406  Message->RepliedToThread = NULL;
407  }
408 
409  /* Free the message */
411  }
412  else
413  {
414  /* We don't have a reply */
416  }
417  }
418  else
419  {
420  /* The wait failed, free the message */
422  }
423 
424  /* All done */
426  "Port: %p. Status: %d\n",
427  Port,
428  Status);
429 
430  /* Dereference the connection port */
431  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
432  return Status;
433 }
#define LpcpGetMessageType(x)
Definition: lpc_x.h:12
KEVENT WaitEvent
Definition: lpctypes.h:231
CPPORT Port[4]
Definition: headless.c:34
#define TRUE
Definition: types.h:120
FORCEINLINE VOID LpcpSetPortToThread(IN PETHREAD Thread, IN PLPCP_PORT_OBJECT Port)
Definition: lpc_x.h:160
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
#define LPC_SEND_DEBUG
Definition: lpc.h:23
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define LpcpCompleteWait(s)
Definition: lpc_x.h:88
VOID NTAPI LpcpMoveMessage(IN PPORT_MESSAGE Destination, IN PPORT_MESSAGE Origin, IN PVOID Data, IN ULONG MessageType, IN PCLIENT_ID ClientId)
Definition: reply.c:139
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:297
LPCP_PORT_QUEUE MsgQueue
Definition: lpctypes.h:213
#define KeGetPreviousMode()
Definition: ketypes.h:1107
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY ReceiveHead
Definition: lpctypes.h:203
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define LPCP_LOCK_RELEASE
Definition: lpc.h:64
#define InsertTailList(ListHead, Entry)
struct _LPCP_PORT_OBJECT * PLPCP_PORT_OBJECT
#define LPCP_PORT_TYPE_MASK
Definition: lpctypes.h:58
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
#define PAGED_CODE()
Definition: video.h:57
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
ULONG LpcpNextMessageId
Definition: port.c:22
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
USHORT Flags
Definition: cportlib.h:31
FORCEINLINE PLPCP_MESSAGE LpcpGetMessageFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:129
unsigned char BOOLEAN
LIST_ENTRY LpcReplyChain
Definition: pstypes.h:1039
smooth NULL
Definition: ftsmooth.c:416
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define LpcpReplyWait(s, w)
Definition: lpc_x.h:32
PKSEMAPHORE Semaphore
Definition: lpctypes.h:202
CLIENT_ID Cid
Definition: pstypes.h:1059
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
CHAR Message[80]
Definition: alive.c:5
#define LPCP_LOCK_HELD
Definition: lpc.h:63
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
Status
Definition: gdiplustypes.h:24
VOID NTAPI LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, IN ULONG LockFlags)
Definition: close.c:52
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
ULONG LpcExitThreadCalled
Definition: pstypes.h:1146
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define STATUS_LPC_REPLY_LOST
Definition: ntstatus.h:707
#define STATUS_PORT_MESSAGE_TOO_LONG
Definition: ntstatus.h:270
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ObReferenceObject
Definition: obfuncs.h:204
#define LPCP_COMMUNICATION_PORT
Definition: lpctypes.h:56
#define STATUS_PORT_DISCONNECTED
Definition: ntstatus.h:277
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
LIST_ENTRY LpcReplyChainHead
Definition: lpctypes.h:221
return STATUS_SUCCESS
Definition: btrfs.c:2938
LPFNPSPCALLBACK Callback
Definition: desk.c:111
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49
#define LPCP_CLIENT_PORT
Definition: lpctypes.h:57

Referenced by CsrClientCallServer(), DbgkpSendApiMessageLpc(), and ExpRaiseHardError().

◆ NtRequestPort()

NTSTATUS NTAPI NtRequestPort ( IN HANDLE  PortHandle,
IN PPORT_MESSAGE  LpcRequest 
)

Definition at line 440 of file send.c.

442 {
446  PORT_MESSAGE CapturedLpcRequest;
447  PLPCP_PORT_OBJECT Port, QueuePort, ConnectionPort = NULL;
448  ULONG MessageType;
450 
451  PAGED_CODE();
453  "Handle: %p. Message: %p. Type: %lx\n",
454  PortHandle,
455  LpcRequest,
456  LpcpGetMessageType(LpcRequest));
457 
458  /* Check if the call comes from user mode */
459  if (PreviousMode != KernelMode)
460  {
461  _SEH2_TRY
462  {
463  /* Probe and capture the LpcRequest */
464  ProbeForRead(LpcRequest, sizeof(*LpcRequest), sizeof(ULONG));
465  CapturedLpcRequest = *(volatile PORT_MESSAGE*)LpcRequest;
466  }
468  {
470  }
471  _SEH2_END;
472  }
473  else
474  {
475  /* Access the LpcRequest directly */
476  CapturedLpcRequest = *LpcRequest;
477  }
478 
479  /* Get the message type */
480  MessageType = CapturedLpcRequest.u2.s2.Type | LPC_DATAGRAM;
481 
482  /* Can't have data information on this type of call */
483  if (CapturedLpcRequest.u2.s2.DataInfoOffset) return STATUS_INVALID_PARAMETER;
484 
485  /* Validate the length */
486  if (((ULONG)CapturedLpcRequest.u1.s1.DataLength + sizeof(PORT_MESSAGE)) >
487  (ULONG)CapturedLpcRequest.u1.s1.TotalLength)
488  {
489  /* Fail */
491  }
492 
493  /* Reference the object */
494  Status = ObReferenceObjectByHandle(PortHandle,
495  0,
497  PreviousMode,
498  (PVOID*)&Port,
499  NULL);
500  if (!NT_SUCCESS(Status)) return Status;
501 
502  /* Validate the message length */
503  if (((ULONG)CapturedLpcRequest.u1.s1.TotalLength > Port->MaxMessageLength) ||
504  ((ULONG)CapturedLpcRequest.u1.s1.TotalLength <= (ULONG)CapturedLpcRequest.u1.s1.DataLength))
505  {
506  /* Fail */
509  }
510 
511  /* Allocate a message from the port zone */
513  if (!Message)
514  {
515  /* Fail if we couldn't allocate a message */
517  return STATUS_NO_MEMORY;
518  }
519 
520  /* No callback, just copy the message */
521  _SEH2_TRY
522  {
523  /* Copy it */
524  LpcpMoveMessage(&Message->Request,
525  &CapturedLpcRequest,
526  LpcRequest + 1,
527  MessageType,
528  &Thread->Cid);
529  }
531  {
532  /* Cleanup and return the exception code */
536  }
537  _SEH2_END;
538 
539  /* Acquire the LPC lock */
541 
542  /* Right now clear the port context */
543  Message->PortContext = NULL;
544 
545  /* Check if this is a not connection port */
547  {
548  /* We want the connected port */
549  QueuePort = Port->ConnectedPort;
550  if (!QueuePort)
551  {
552  /* We have no connected port, fail */
556  }
557 
558  /* Check if this is a communication port */
560  {
561  /* Copy the port context and use the connection port */
562  Message->PortContext = QueuePort->PortContext;
563  ConnectionPort = QueuePort = Port->ConnectionPort;
564  if (!ConnectionPort)
565  {
566  /* Fail */
570  }
571  }
573  {
574  /* Use the connection port for anything but communication ports */
575  ConnectionPort = QueuePort = Port->ConnectionPort;
576  if (!ConnectionPort)
577  {
578  /* Fail */
582  }
583  }
584 
585  /* Reference the connection port if it exists */
586  if (ConnectionPort) ObReferenceObject(ConnectionPort);
587  }
588  else
589  {
590  /* Otherwise, for a connection port, use the same port object */
591  QueuePort = Port;
592  }
593 
594  /* Reference QueuePort if we have it */
595  if (QueuePort && ObReferenceObjectSafe(QueuePort))
596  {
597  /* Set sender's port */
598  Message->SenderPort = Port;
599 
600  /* Generate the Message ID and set it */
601  Message->Request.MessageId = LpcpNextMessageId++;
603  Message->Request.CallbackId = 0;
604 
605  /* No Message ID for the thread */
606  Thread->LpcReplyMessageId = 0;
607 
608  /* Insert the message in our chain */
609  InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry);
610 
611  /* Release the lock and the semaphore */
614  LpcpCompleteWait(QueuePort->MsgQueue.Semaphore);
615 
616  /* If this is a waitable port, wake it up */
617  if (QueuePort->Flags & LPCP_WAITABLE_PORT)
618  {
619  /* Wake it */
620  KeSetEvent(&QueuePort->WaitEvent, IO_NO_INCREMENT, FALSE);
621  }
622 
624 
625  /* Dereference objects */
626  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
627  ObDereferenceObject(QueuePort);
629  LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", QueuePort, Message);
630  return STATUS_SUCCESS;
631  }
632 
634 
635  /* All done with a failure*/
637  "Port: %p. Status: %d\n",
638  Port,
639  Status);
640 
641  /* The wait failed, free the message */
643 
645  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
646  return Status;
647 }
#define LpcpGetMessageType(x)
Definition: lpc_x.h:12
KEVENT WaitEvent
Definition: lpctypes.h:231
CPPORT Port[4]
Definition: headless.c:34
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
#define LPC_SEND_DEBUG
Definition: lpc.h:23
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define LpcpCompleteWait(s)
Definition: lpc_x.h:88
VOID NTAPI LpcpMoveMessage(IN PPORT_MESSAGE Destination, IN PPORT_MESSAGE Origin, IN PVOID Data, IN ULONG MessageType, IN PCLIENT_ID ClientId)
Definition: reply.c:139
LPCP_PORT_QUEUE MsgQueue
Definition: lpctypes.h:213
#define KeGetPreviousMode()
Definition: ketypes.h:1107
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY ReceiveHead
Definition: lpctypes.h:203
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define LPCP_LOCK_RELEASE
Definition: lpc.h:64
#define InsertTailList(ListHead, Entry)
#define LPCP_PORT_TYPE_MASK
Definition: lpctypes.h:58
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
BOOLEAN FASTCALL ObReferenceObjectSafe(IN PVOID Object)
Definition: obref.c:24
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
ULONG LpcpNextMessageId
Definition: port.c:22
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
USHORT Flags
Definition: cportlib.h:31
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
smooth NULL
Definition: ftsmooth.c:416
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PKSEMAPHORE Semaphore
Definition: lpctypes.h:202
CLIENT_ID Cid
Definition: pstypes.h:1059
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
CHAR Message[80]
Definition: alive.c:5
#define LPCP_LOCK_HELD
Definition: lpc.h:63
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
Status
Definition: gdiplustypes.h:24
VOID NTAPI LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, IN ULONG LockFlags)
Definition: close.c:52
_SEH2_END
Definition: create.c:4424
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define STATUS_PORT_MESSAGE_TOO_LONG
Definition: ntstatus.h:270
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define ObReferenceObject
Definition: obfuncs.h:204
#define LPCP_COMMUNICATION_PORT
Definition: lpctypes.h:56
#define STATUS_PORT_DISCONNECTED
Definition: ntstatus.h:277
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49
#define LPCP_CLIENT_PORT
Definition: lpctypes.h:57

Referenced by ClientThread(), and main().

◆ NtRequestWaitReplyPort()

NTSTATUS NTAPI NtRequestWaitReplyPort ( IN HANDLE  PortHandle,
IN PPORT_MESSAGE  LpcRequest,
IN OUT PPORT_MESSAGE  LpcReply 
)

Definition at line 695 of file send.c.

698 {
700  PORT_MESSAGE CapturedLpcRequest;
701  ULONG NumberOfDataEntries;
702  PLPCP_PORT_OBJECT Port, QueuePort, ReplyPort, ConnectionPort = NULL;
707  PKSEMAPHORE Semaphore;
708  ULONG MessageType;
709  PLPCP_DATA_INFO DataInfo;
710 
711  PAGED_CODE();
713  "Handle: %p. Messages: %p/%p. Type: %lx\n",
714  PortHandle,
715  LpcRequest,
716  LpcReply,
717  LpcpGetMessageType(LpcRequest));
718 
719  /* Check if the thread is dying */
721 
722  /* Check for user mode access */
723  if (PreviousMode != KernelMode)
724  {
725  _SEH2_TRY
726  {
727  /* Probe and capture the LpcRequest */
728  ProbeForRead(LpcRequest, sizeof(*LpcRequest), sizeof(ULONG));
729  CapturedLpcRequest = *(volatile PORT_MESSAGE*)LpcRequest;
730 
731  /* Probe the reply message for write */
732  ProbeForWrite(LpcReply, sizeof(*LpcReply), sizeof(ULONG));
733 
734  /* Make sure the data entries in the request message are valid */
735  Status = LpcpVerifyMessageDataInfo(LpcRequest, &NumberOfDataEntries);
736  if (!NT_SUCCESS(Status))
737  {
738  DPRINT1("LpcpVerifyMessageDataInfo failed\n");
739  _SEH2_YIELD(return Status);
740  }
741  }
743  {
744  DPRINT1("Got exception\n");
746  }
747  _SEH2_END;
748  }
749  else
750  {
751  CapturedLpcRequest = *LpcRequest;
752  Status = LpcpVerifyMessageDataInfo(LpcRequest, &NumberOfDataEntries);
753  if (!NT_SUCCESS(Status))
754  {
755  DPRINT1("LpcpVerifyMessageDataInfo failed\n");
756  return Status;
757  }
758  }
759 
760  /* This flag is undocumented. Remove it before continuing */
761  CapturedLpcRequest.u2.s2.Type &= ~0x4000;
762 
763  /* Check if this is an LPC Request */
764  if (LpcpGetMessageType(&CapturedLpcRequest) == LPC_REQUEST)
765  {
766  /* Then it's a callback */
767  Callback = TRUE;
768  }
769  else if (LpcpGetMessageType(&CapturedLpcRequest))
770  {
771  /* This is a not kernel-mode message */
772  DPRINT1("Not a kernel-mode message!\n");
774  }
775  else
776  {
777  /* This is a kernel-mode message without a callback */
778  CapturedLpcRequest.u2.s2.Type |= LPC_REQUEST;
779  Callback = FALSE;
780  }
781 
782  /* Get the message type */
783  MessageType = CapturedLpcRequest.u2.s2.Type;
784 
785  /* Due to the above probe, we know that TotalLength is positive */
786  ASSERT(CapturedLpcRequest.u1.s1.TotalLength >= 0);
787 
788  /* Validate the length */
789  if ((((ULONG)(USHORT)CapturedLpcRequest.u1.s1.DataLength + sizeof(PORT_MESSAGE)) >
790  (ULONG)CapturedLpcRequest.u1.s1.TotalLength))
791  {
792  /* Fail */
793  DPRINT1("Invalid message length: %u, %u\n",
794  CapturedLpcRequest.u1.s1.DataLength,
795  CapturedLpcRequest.u1.s1.TotalLength);
797  }
798 
799  /* Reference the object */
800  Status = ObReferenceObjectByHandle(PortHandle,
801  0,
803  PreviousMode,
804  (PVOID*)&Port,
805  NULL);
806  if (!NT_SUCCESS(Status)) return Status;
807 
808  /* Validate the message length */
809  if (((ULONG)CapturedLpcRequest.u1.s1.TotalLength > Port->MaxMessageLength) ||
810  ((ULONG)CapturedLpcRequest.u1.s1.TotalLength <= (ULONG)CapturedLpcRequest.u1.s1.DataLength))
811  {
812  /* Fail */
813  DPRINT1("Invalid message length: %u, %u\n",
814  CapturedLpcRequest.u1.s1.DataLength,
815  CapturedLpcRequest.u1.s1.TotalLength);
818  }
819 
820  /* Allocate a message from the port zone */
822  if (!Message)
823  {
824  /* Fail if we couldn't allocate a message */
825  DPRINT1("Failed to allocate a message!\n");
827  return STATUS_NO_MEMORY;
828  }
829 
830  /* Check if this is a callback */
831  if (Callback)
832  {
833  /* FIXME: TODO */
834  Semaphore = NULL; // we'd use the Thread Semaphore here
835  ASSERT(FALSE);
836  }
837  else
838  {
839  /* No callback, just copy the message */
840  _SEH2_TRY
841  {
842  /* Check if we have data info entries */
843  if (LpcRequest->u2.s2.DataInfoOffset != 0)
844  {
845  /* Get the data info and check if the number of entries matches
846  what we expect */
847  DataInfo = LpcpGetDataInfoFromMessage(LpcRequest);
848  if (DataInfo->NumberOfEntries != NumberOfDataEntries)
849  {
852  DPRINT1("NumberOfEntries has changed: %u, %u\n",
853  DataInfo->NumberOfEntries, NumberOfDataEntries);
855  }
856  }
857 
858  /* Copy it */
859  LpcpMoveMessage(&Message->Request,
860  &CapturedLpcRequest,
861  LpcRequest + 1,
862  MessageType,
863  &Thread->Cid);
864  }
866  {
867  /* Cleanup and return the exception code */
868  DPRINT1("Got exception!\n");
872  }
873  _SEH2_END;
874 
875  /* Acquire the LPC lock */
877 
878  /* Right now clear the port context */
879  Message->PortContext = NULL;
880 
881  /* Check if this is a not connection port */
883  {
884  /* We want the connected port */
885  QueuePort = Port->ConnectedPort;
886  if (!QueuePort)
887  {
888  /* We have no connected port, fail */
889  DPRINT1("No connected port\n");
893  }
894 
895  /* This will be the rundown port */
896  ReplyPort = QueuePort;
897 
898  /* Check if this is a client port */
900  {
901  /* Copy the port context */
902  Message->PortContext = QueuePort->PortContext;
903  }
904 
906  {
907  /* Use the connection port for anything but communication ports */
908  ConnectionPort = QueuePort = Port->ConnectionPort;
909  if (!ConnectionPort)
910  {
911  /* Fail */
912  DPRINT1("No connection port\n");
916  }
917  }
918 
919  /* Reference the connection port if it exists */
920  if (ConnectionPort) ObReferenceObject(ConnectionPort);
921  }
922  else
923  {
924  /* Otherwise, for a connection port, use the same port object */
925  QueuePort = ReplyPort = Port;
926  }
927 
928  /* No reply thread */
929  Message->RepliedToThread = NULL;
930  Message->SenderPort = Port;
931 
932  /* Generate the Message ID and set it */
933  Message->Request.MessageId = LpcpNextMessageId++;
935  Message->Request.CallbackId = 0;
936 
937  /* Set the message ID for our thread now */
938  Thread->LpcReplyMessageId = Message->Request.MessageId;
939  Thread->LpcReplyMessage = NULL;
940 
941  /* Insert the message in our chain */
942  InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry);
945 
946  /* Release the lock and get the semaphore we'll use later */
949  Semaphore = QueuePort->MsgQueue.Semaphore;
950 
951  /* If this is a waitable port, wake it up */
952  if (QueuePort->Flags & LPCP_WAITABLE_PORT)
953  {
954  /* Wake it */
955  KeSetEvent(&QueuePort->WaitEvent, IO_NO_INCREMENT, FALSE);
956  }
957  }
958 
959  /* Now release the semaphore */
960  LpcpCompleteWait(Semaphore);
962 
963  /* And let's wait for the reply */
964  LpcpReplyWait(&Thread->LpcReplySemaphore, PreviousMode);
965 
966  /* Acquire the LPC lock */
968 
969  /* Get the LPC Message and clear our thread's reply data */
971  Thread->LpcReplyMessage = NULL;
972  Thread->LpcReplyMessageId = 0;
973 
974  /* Check if we have anything on the reply chain*/
976  {
977  /* Remove this thread and reinitialize the list */
980  }
981 
982  /* Release the lock */
984 
985  /* Check if we got a reply */
986  if (Status == STATUS_SUCCESS)
987  {
988  /* Check if we have a valid message */
989  if (Message)
990  {
992  "Reply Messages: %p/%p\n",
993  &Message->Request,
994  (&Message->Request) + 1);
995 
996  /* Move the message */
997  _SEH2_TRY
998  {
999  LpcpMoveMessage(LpcReply,
1000  &Message->Request,
1001  (&Message->Request) + 1,
1002  0,
1003  NULL);
1004  }
1006  {
1007  DPRINT1("Got exception!\n");
1009  }
1010  _SEH2_END;
1011 
1012  /* Check if this is an LPC request with data information */
1013  if ((LpcpGetMessageType(&Message->Request) == LPC_REQUEST) &&
1014  (Message->Request.u2.s2.DataInfoOffset))
1015  {
1016  /* Save the data information */
1018  }
1019  else
1020  {
1021  /* Otherwise, just free it */
1023  }
1024  }
1025  else
1026  {
1027  /* We don't have a reply */
1029  }
1030  }
1031  else
1032  {
1033  /* The wait failed, free the message */
1035  }
1036 
1037  /* All done */
1039  "Port: %p. Status: %d\n",
1040  Port,
1041  Status);
1043  if (ConnectionPort) ObDereferenceObject(ConnectionPort);
1044  return Status;
1045 }
#define LpcpGetMessageType(x)
Definition: lpc_x.h:12
KEVENT WaitEvent
Definition: lpctypes.h:231
CPPORT Port[4]
Definition: headless.c:34
FORCEINLINE PLPCP_DATA_INFO LpcpGetDataInfoFromMessage(PPORT_MESSAGE Message)
Definition: lpc_x.h:170
#define TRUE
Definition: types.h:120
FORCEINLINE VOID LpcpSetPortToThread(IN PETHREAD Thread, IN PLPCP_PORT_OBJECT Port)
Definition: lpc_x.h:160
KGUARDED_MUTEX LpcpLock
Definition: port.c:20
#define LPC_SEND_DEBUG
Definition: lpc.h:23
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define LpcpCompleteWait(s)
Definition: lpc_x.h:88
VOID NTAPI LpcpMoveMessage(IN PPORT_MESSAGE Destination, IN PPORT_MESSAGE Origin, IN PVOID Data, IN ULONG MessageType, IN PCLIENT_ID ClientId)
Definition: reply.c:139
#define STATUS_THREAD_IS_TERMINATING
Definition: ntstatus.h:297
LPCP_PORT_QUEUE MsgQueue
Definition: lpctypes.h:213
#define KeGetPreviousMode()
Definition: ketypes.h:1107
LONG NTSTATUS
Definition: precomp.h:26
LIST_ENTRY ReceiveHead
Definition: lpctypes.h:203
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
#define LPCP_LOCK_RELEASE
Definition: lpc.h:64
#define InsertTailList(ListHead, Entry)
#define LPCP_PORT_TYPE_MASK
Definition: lpctypes.h:58
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define PAGED_CODE()
Definition: video.h:57
_SEH2_TRY
Definition: create.c:4250
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:496
ULONG LpcpNextMessageId
Definition: port.c:22
#define LPCP_CONNECTION_PORT
Definition: lpctypes.h:54
USHORT Flags
Definition: cportlib.h:31
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
FORCEINLINE PLPCP_MESSAGE LpcpGetMessageFromThread(IN PETHREAD Thread)
Definition: lpc_x.h:129
unsigned char BOOLEAN
LIST_ENTRY LpcReplyChain
Definition: pstypes.h:1039
NTSTATUS NTAPI LpcpVerifyMessageDataInfo(_In_ PPORT_MESSAGE Message, _Out_ PULONG NumberOfDataEntries)
Definition: send.c:651
smooth NULL
Definition: ftsmooth.c:416
static __inline PLPCP_MESSAGE LpcpAllocateFromPortZone(VOID)
Definition: lpc_x.h:100
POBJECT_TYPE LpcPortObjectType
Definition: port.c:17
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103
#define LpcpReplyWait(s, w)
Definition: lpc_x.h:32
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PKSEMAPHORE Semaphore
Definition: lpctypes.h:202
CLIENT_ID Cid
Definition: pstypes.h:1059
ULONG NumberOfEntries
Definition: lpc.h:69
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
CHAR Message[80]
Definition: alive.c:5
#define LPCP_LOCK_HELD
Definition: lpc.h:63
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define LPCP_WAITABLE_PORT
Definition: lpctypes.h:60
Status
Definition: gdiplustypes.h:24
VOID NTAPI LpcpFreeToPortZone(IN PLPCP_MESSAGE Message, IN ULONG LockFlags)
Definition: close.c:52
_SEH2_END
Definition: create.c:4424
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
ULONG LpcExitThreadCalled
Definition: pstypes.h:1146
unsigned short USHORT
Definition: pedump.c:61
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define STATUS_LPC_REPLY_LOST
Definition: ntstatus.h:707
#define STATUS_PORT_MESSAGE_TOO_LONG
Definition: ntstatus.h:270
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
#define ObReferenceObject
Definition: obfuncs.h:204
#define LPCP_COMMUNICATION_PORT
Definition: lpctypes.h:56
#define STATUS_PORT_DISCONNECTED
Definition: ntstatus.h:277
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:566
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
LIST_ENTRY LpcReplyChainHead
Definition: lpctypes.h:221
return STATUS_SUCCESS
Definition: btrfs.c:2938
VOID NTAPI LpcpSaveDataInfoMessage(IN PLPCP_PORT_OBJECT Port, IN PLPCP_MESSAGE Message, IN ULONG LockFlags)
Definition: reply.c:62
LPFNPSPCALLBACK Callback
Definition: desk.c:111
#define LPCTRACE(x, fmt,...)
Definition: lpc.h:49
#define LPCP_CLIENT_PORT
Definition: lpctypes.h:57

Referenced by CsrClientCallServer(), LsaEnumerateLogonSessions(), LsaGetLogonSessionData(), LsapRmCreateLogonSession(), LsapRmDeleteLogonSession(), LsaRegisterPolicyChangeNotification(), LsaUnregisterPolicyChangeNotification(), SmCompleteSession(), SmExecPgm(), SmExecuteProgram(), SmpCallCsrCreateProcess(), SmpLoadSubSystem(), SmpSbCreateSession(), SmQueryInformation(), and SmSessionComplete().