1 /* $Id: send.c,v 1.12 2003/08/18 11:48:19 hbirr Exp $
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/lpc/send.c
6 * PURPOSE: Communication mechanism
7 * PROGRAMMER: David Welch (welch@cwcom.net)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/port.h>
17 #include <internal/dbg.h>
18 #include <internal/safe.h>
21 #include <internal/debug.h>
24 /**********************************************************************
36 LpcSendTerminationPort (IN PEPORT Port
,
40 LPC_TERMINATION_MESSAGE Msg
;
42 Msg
.CreationTime
= CreationTime
;
43 Status
= LpcRequestPort (Port
, &Msg
.Header
);
48 /**********************************************************************
60 LpcSendDebugMessagePort (IN PEPORT Port
,
61 IN PLPC_DBG_MESSAGE Message
,
62 OUT PLPC_DBG_MESSAGE Reply
)
66 PQUEUEDMESSAGE ReplyMessage
;
68 Status
= EiReplyOrRequestPort(Port
,
72 if (!NT_SUCCESS(Status
))
74 ObDereferenceObject(Port
);
77 KeReleaseSemaphore(&Port
->OtherPort
->Semaphore
, IO_NO_INCREMENT
, 1, FALSE
);
82 KeWaitForSingleObject(&Port
->Semaphore
,
91 KeAcquireSpinLock(&Port
->Lock
, &oldIrql
);
92 ReplyMessage
= EiDequeueMessagePort(Port
);
93 KeReleaseSpinLock(&Port
->Lock
, oldIrql
);
94 memcpy(Reply
, &ReplyMessage
->Message
, ReplyMessage
->Message
.MessageSize
);
95 ExFreePool(ReplyMessage
);
97 return(STATUS_SUCCESS
);
101 /**********************************************************************
114 NTSTATUS STDCALL
LpcRequestPort (IN PEPORT Port
,
115 IN PLPC_MESSAGE LpcMessage
)
119 DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port
, LpcMessage
);
121 Status
= EiReplyOrRequestPort(Port
,
125 KeReleaseSemaphore( &Port
->Semaphore
, IO_NO_INCREMENT
, 1, FALSE
);
131 /**********************************************************************
144 NTSTATUS STDCALL
NtRequestPort (IN HANDLE PortHandle
,
145 IN PLPC_MESSAGE LpcMessage
)
150 DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle
,
153 Status
= ObReferenceObjectByHandle(PortHandle
,
159 if (!NT_SUCCESS(Status
))
161 DPRINT("NtRequestPort() = %x\n", Status
);
165 Status
= LpcRequestPort(Port
->OtherPort
,
168 ObDereferenceObject(Port
);
173 /**********************************************************************
187 NtRequestWaitReplyPort (IN HANDLE PortHandle
,
188 PLPC_MESSAGE UnsafeLpcRequest
,
189 PLPC_MESSAGE UnsafeLpcReply
)
193 PQUEUEDMESSAGE Message
;
195 PLPC_MESSAGE LpcRequest
;
196 USHORT LpcRequestMessageSize
;
198 DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
199 "LpcReply %x)\n", PortHandle
, UnsafeLpcRequest
, UnsafeLpcReply
);
201 Status
= ObReferenceObjectByHandle(PortHandle
,
207 if (!NT_SUCCESS(Status
))
212 Status
= MmCopyFromCaller(&LpcRequestMessageSize
,
213 &UnsafeLpcRequest
->MessageSize
,
215 if (!NT_SUCCESS(Status
))
217 ObDereferenceObject(Port
);
220 if (LpcRequestMessageSize
> (sizeof(LPC_MESSAGE
) + MAX_MESSAGE_DATA
))
222 ObDereferenceObject(Port
);
223 return(STATUS_PORT_MESSAGE_TOO_LONG
);
225 LpcRequest
= ExAllocatePool(NonPagedPool
, LpcRequestMessageSize
);
226 if (LpcRequest
== NULL
)
228 ObDereferenceObject(Port
);
229 return(STATUS_NO_MEMORY
);
231 Status
= MmCopyFromCaller(LpcRequest
, UnsafeLpcRequest
,
232 LpcRequestMessageSize
);
233 if (!NT_SUCCESS(Status
))
235 ExFreePool(LpcRequest
);
236 ObDereferenceObject(Port
);
239 LpcRequestMessageSize
= LpcRequest
->MessageSize
;
240 if (LpcRequestMessageSize
> (sizeof(LPC_MESSAGE
) + MAX_MESSAGE_DATA
))
242 ExFreePool(LpcRequest
);
243 ObDereferenceObject(Port
);
244 return(STATUS_PORT_MESSAGE_TOO_LONG
);
246 if (LpcRequest
->DataSize
!= (LpcRequest
->MessageSize
- sizeof(LPC_MESSAGE
)))
248 ExFreePool(LpcRequest
);
249 ObDereferenceObject(Port
);
250 return(STATUS_PORT_MESSAGE_TOO_LONG
);
253 Status
= EiReplyOrRequestPort(Port
->OtherPort
,
257 if (!NT_SUCCESS(Status
))
259 DbgPrint("Enqueue failed\n");
260 ExFreePool(LpcRequest
);
261 ObDereferenceObject(Port
);
264 ExFreePool(LpcRequest
);
265 KeReleaseSemaphore (&Port
->OtherPort
->Semaphore
, IO_NO_INCREMENT
,
271 Status
= KeWaitForSingleObject(&Port
->Semaphore
,
276 if (Status
== STATUS_SUCCESS
)
282 KeAcquireSpinLock(&Port
->Lock
, &oldIrql
);
283 Message
= EiDequeueMessagePort(Port
);
284 KeReleaseSpinLock(&Port
->Lock
, oldIrql
);
287 DPRINT("Message->Message.MessageSize %d\n",
288 Message
->Message
.MessageSize
);
289 Status
= MmCopyToCaller(UnsafeLpcReply
, &Message
->Message
,
290 Message
->Message
.MessageSize
);
294 Status
= STATUS_UNSUCCESSFUL
;
298 if (NT_SUCCESS(Status
))
300 Status
= STATUS_UNSUCCESSFUL
;
303 ObDereferenceObject(Port
);
309 /**********************************************************************
320 NTSTATUS STDCALL
NtWriteRequestData (HANDLE PortHandle
,
321 PLPC_MESSAGE Message
,