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 /**********************************************************************
37 LpcSendTerminationPort (IN PEPORT Port,
41 LPC_TERMINATION_MESSAGE Msg;
43 Msg.CreationTime = CreationTime;
44 Status = LpcRequestPort (Port, &Msg.Header);
49 /**********************************************************************
62 LpcSendDebugMessagePort (IN PEPORT Port,
63 IN PLPC_DBG_MESSAGE Message,
64 OUT PLPC_DBG_MESSAGE Reply)
68 PQUEUEDMESSAGE ReplyMessage;
70 Status = EiReplyOrRequestPort(Port,
74 if (!NT_SUCCESS(Status))
76 ObDereferenceObject(Port);
79 KeReleaseSemaphore(&Port->OtherPort->Semaphore, IO_NO_INCREMENT, 1, FALSE);
84 KeWaitForSingleObject(&Port->Semaphore,
93 KeAcquireSpinLock(&Port->Lock, &oldIrql);
94 ReplyMessage = EiDequeueMessagePort(Port);
95 KeReleaseSpinLock(&Port->Lock, oldIrql);
96 memcpy(Reply, &ReplyMessage->Message, ReplyMessage->Message.MessageSize);
97 ExFreePool(ReplyMessage);
99 return(STATUS_SUCCESS);
103 /**********************************************************************
115 NTSTATUS STDCALL LpcRequestPort (IN PEPORT Port,
116 IN PLPC_MESSAGE LpcMessage)
120 DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port, LpcMessage);
122 Status = EiReplyOrRequestPort(Port,
126 KeReleaseSemaphore( &Port->Semaphore, IO_NO_INCREMENT, 1, FALSE );
132 /**********************************************************************
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 /**********************************************************************
186 NtRequestWaitReplyPort (IN HANDLE PortHandle,
187 PLPC_MESSAGE UnsafeLpcRequest,
188 PLPC_MESSAGE UnsafeLpcReply)
192 PQUEUEDMESSAGE Message;
194 PLPC_MESSAGE LpcRequest;
195 USHORT LpcRequestMessageSize;
197 DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
198 "LpcReply %x)\n", PortHandle, UnsafeLpcRequest, UnsafeLpcReply);
200 Status = ObReferenceObjectByHandle(PortHandle,
206 if (!NT_SUCCESS(Status))
211 Status = MmCopyFromCaller(&LpcRequestMessageSize,
212 &UnsafeLpcRequest->MessageSize,
214 if (!NT_SUCCESS(Status))
216 ObDereferenceObject(Port);
219 if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
221 ObDereferenceObject(Port);
222 return(STATUS_PORT_MESSAGE_TOO_LONG);
224 LpcRequest = ExAllocatePool(NonPagedPool, LpcRequestMessageSize);
225 if (LpcRequest == NULL)
227 ObDereferenceObject(Port);
228 return(STATUS_NO_MEMORY);
230 Status = MmCopyFromCaller(LpcRequest, UnsafeLpcRequest,
231 LpcRequestMessageSize);
232 if (!NT_SUCCESS(Status))
234 ExFreePool(LpcRequest);
235 ObDereferenceObject(Port);
238 LpcRequestMessageSize = LpcRequest->MessageSize;
239 if (LpcRequestMessageSize > (sizeof(LPC_MESSAGE) + MAX_MESSAGE_DATA))
241 ExFreePool(LpcRequest);
242 ObDereferenceObject(Port);
243 return(STATUS_PORT_MESSAGE_TOO_LONG);
245 if (LpcRequest->DataSize != (LpcRequest->MessageSize - sizeof(LPC_MESSAGE)))
247 ExFreePool(LpcRequest);
248 ObDereferenceObject(Port);
249 return(STATUS_PORT_MESSAGE_TOO_LONG);
252 Status = EiReplyOrRequestPort(Port->OtherPort,
256 if (!NT_SUCCESS(Status))
258 DbgPrint("Enqueue failed\n");
259 ExFreePool(LpcRequest);
260 ObDereferenceObject(Port);
263 ExFreePool(LpcRequest);
264 KeReleaseSemaphore (&Port->OtherPort->Semaphore, IO_NO_INCREMENT,
270 KeWaitForSingleObject(&Port->Semaphore,
279 KeAcquireSpinLock(&Port->Lock, &oldIrql);
280 Message = EiDequeueMessagePort(Port);
281 KeReleaseSpinLock(&Port->Lock, oldIrql);
282 DPRINT("Message->Message.MessageSize %d\n",
283 Message->Message.MessageSize);
284 Status = MmCopyToCaller(UnsafeLpcReply, &Message->Message,
285 Message->Message.MessageSize);
288 ObDereferenceObject(Port);
294 /**********************************************************************
306 NTSTATUS STDCALL NtWriteRequestData (HANDLE PortHandle,
307 PLPC_MESSAGE Message,