Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers...
[reactos.git] / reactos / ntoskrnl / lpc / reply.c
diff --git a/reactos/ntoskrnl/lpc/reply.c b/reactos/ntoskrnl/lpc/reply.c
deleted file mode 100644 (file)
index d9fa834..0000000
+++ /dev/null
@@ -1,1004 +0,0 @@
-/*
- * PROJECT:         ReactOS Kernel
- * LICENSE:         GPL - See COPYING in the top level directory
- * FILE:            ntoskrnl/lpc/reply.c
- * PURPOSE:         Local Procedure Call: Receive (Replies)
- * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
- */
-
-/* INCLUDES ******************************************************************/
-
-#include <ntoskrnl.h>
-#define NDEBUG
-#include <debug.h>
-
-/* PRIVATE FUNCTIONS *********************************************************/
-
-VOID
-NTAPI
-LpcpFreeDataInfoMessage(IN PLPCP_PORT_OBJECT Port,
-                        IN ULONG MessageId,
-                        IN ULONG CallbackId,
-                        IN CLIENT_ID ClientId)
-{
-    PLPCP_MESSAGE Message;
-    PLIST_ENTRY ListHead, NextEntry;
-
-    /* Check if the port we want is the connection port */
-    if ((Port->Flags & LPCP_PORT_TYPE_MASK) > LPCP_UNCONNECTED_PORT)
-    {
-        /* Use it */
-        Port = Port->ConnectionPort;
-        if (!Port) return;
-    }
-
-    /* Loop the list */
-    ListHead = &Port->LpcDataInfoChainHead;
-    NextEntry = ListHead->Flink;
-    while (ListHead != NextEntry)
-    {
-        /* Get the message */
-        Message = CONTAINING_RECORD(NextEntry, LPCP_MESSAGE, Entry);
-
-        /* Make sure it matches */
-        if ((Message->Request.MessageId == MessageId) &&
-            (Message->Request.ClientId.UniqueThread == ClientId.UniqueThread) &&
-            (Message->Request.ClientId.UniqueProcess == ClientId.UniqueProcess))
-        {
-            /* Unlink and free it */
-            RemoveEntryList(&Message->Entry);
-            InitializeListHead(&Message->Entry);
-            LpcpFreeToPortZone(Message, LPCP_LOCK_HELD);
-            break;
-        }
-
-        /* Go to the next entry */
-        NextEntry = NextEntry->Flink;
-    }
-}
-
-VOID
-NTAPI
-LpcpSaveDataInfoMessage(IN PLPCP_PORT_OBJECT Port,
-                        IN PLPCP_MESSAGE Message,
-                        IN ULONG LockFlags)
-{
-    BOOLEAN LockHeld = (LockFlags & LPCP_LOCK_HELD);
-
-    PAGED_CODE();
-
-    /* Acquire the lock */
-    if (!LockHeld) KeAcquireGuardedMutex(&LpcpLock);
-
-    /* Check if the port we want is the connection port */
-    if ((Port->Flags & LPCP_PORT_TYPE_MASK) > LPCP_UNCONNECTED_PORT)
-    {
-        /* Use it */
-        Port = Port->ConnectionPort;
-        if (!Port)
-        {
-            /* Release the lock and return */
-            if (!LockHeld) KeReleaseGuardedMutex(&LpcpLock);
-            return;
-        }
-    }
-
-    /* Link the message */
-    InsertTailList(&Port->LpcDataInfoChainHead, &Message->Entry);
-
-    /* Release the lock */
-    if (!LockHeld) KeReleaseGuardedMutex(&LpcpLock);
-}
-
-PLPCP_MESSAGE
-NTAPI
-LpcpFindDataInfoMessage(
-    IN PLPCP_PORT_OBJECT Port,
-    IN ULONG MessageId,
-    IN LPC_CLIENT_ID ClientId)
-{
-    PLPCP_MESSAGE Message;
-    PLIST_ENTRY ListEntry;
-
-    PAGED_CODE();
-
-    /* Check if the port we want is the connection port */
-    if ((Port->Flags & LPCP_PORT_TYPE_MASK) > LPCP_UNCONNECTED_PORT)
-    {
-        /* Use it */
-        Port = Port->ConnectionPort;
-        if (!Port)
-        {
-            /* Return NULL */
-            return NULL;
-        }
-    }
-
-    /* Loop all entries in the list */
-    for (ListEntry = Port->LpcDataInfoChainHead.Flink;
-         ListEntry != &Port->LpcDataInfoChainHead;
-         ListEntry = ListEntry->Flink)
-    {
-        Message = CONTAINING_RECORD(ListEntry, LPCP_MESSAGE, Entry);
-
-        /* Check if this is the desired message */
-        if ((Message->Request.MessageId == MessageId) &&
-            (Message->Request.ClientId.UniqueProcess == ClientId.UniqueProcess) &&
-            (Message->Request.ClientId.UniqueThread == ClientId.UniqueThread))
-        {
-            /* It is, return it */
-            return Message;
-        }
-    }
-
-    return NULL;
-}
-
-VOID
-NTAPI
-LpcpMoveMessage(IN PPORT_MESSAGE Destination,
-                IN PPORT_MESSAGE Origin,
-                IN PVOID Data,
-                IN ULONG MessageType,
-                IN PCLIENT_ID ClientId)
-{
-    LPCTRACE((LPC_REPLY_DEBUG | LPC_SEND_DEBUG),
-             "Destination/Origin: %p/%p. Data: %p. Length: %lx\n",
-             Destination,
-             Origin,
-             Data,
-             Origin->u1.Length);
-
-    /* Set the Message size */
-    Destination->u1.Length = Origin->u1.Length;
-
-    /* Set the Message Type */
-    Destination->u2.s2.Type = !MessageType ?
-                              Origin->u2.s2.Type : MessageType & 0xFFFF;
-
-    /* Check if we have a Client ID */
-    if (ClientId)
-    {
-        /* Set the Client ID */
-        Destination->ClientId.UniqueProcess = ClientId->UniqueProcess;
-        Destination->ClientId.UniqueThread = ClientId->UniqueThread;
-    }
-    else
-    {
-        /* Otherwise, copy it */
-        Destination->ClientId.UniqueProcess = Origin->ClientId.UniqueProcess;
-        Destination->ClientId.UniqueThread = Origin->ClientId.UniqueThread;
-    }
-
-    /* Copy the MessageId and ClientViewSize */
-    Destination->MessageId = Origin->MessageId;
-    Destination->ClientViewSize = Origin->ClientViewSize;
-
-    /* Copy the Message Data */
-    RtlCopyMemory(Destination + 1,
-                  Data,
-                  ALIGN_UP_BY(Destination->u1.s1.DataLength, sizeof(ULONG)));
-}
-
-/* PUBLIC FUNCTIONS **********************************************************/
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-NtReplyPort(IN HANDLE PortHandle,
-            IN PPORT_MESSAGE ReplyMessage)
-{
-    NTSTATUS Status;
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    PORT_MESSAGE CapturedReplyMessage;
-    PLPCP_PORT_OBJECT Port;
-    PLPCP_MESSAGE Message;
-    PETHREAD Thread = PsGetCurrentThread(), WakeupThread;
-
-    PAGED_CODE();
-    LPCTRACE(LPC_REPLY_DEBUG,
-             "Handle: %p. Message: %p.\n",
-             PortHandle,
-             ReplyMessage);
-
-    /* Check if the call comes from user mode */
-    if (PreviousMode != KernelMode)
-    {
-        _SEH2_TRY
-        {
-            ProbeForRead(ReplyMessage, sizeof(*ReplyMessage), sizeof(ULONG));
-            CapturedReplyMessage = *(volatile PORT_MESSAGE*)ReplyMessage;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        CapturedReplyMessage = *ReplyMessage;
-    }
-
-    /* Validate its length */
-    if (((ULONG)CapturedReplyMessage.u1.s1.DataLength + sizeof(PORT_MESSAGE)) >
-         (ULONG)CapturedReplyMessage.u1.s1.TotalLength)
-    {
-        /* Fail */
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Make sure it has a valid ID */
-    if (!CapturedReplyMessage.MessageId) return STATUS_INVALID_PARAMETER;
-
-    /* Get the Port object */
-    Status = ObReferenceObjectByHandle(PortHandle,
-                                       0,
-                                       LpcPortObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&Port,
-                                       NULL);
-    if (!NT_SUCCESS(Status)) return Status;
-
-    /* Validate its length in respect to the port object */
-    if (((ULONG)CapturedReplyMessage.u1.s1.TotalLength > Port->MaxMessageLength) ||
-        ((ULONG)CapturedReplyMessage.u1.s1.TotalLength <=
-         (ULONG)CapturedReplyMessage.u1.s1.DataLength))
-    {
-        /* Too large, fail */
-        ObDereferenceObject(Port);
-        return STATUS_PORT_MESSAGE_TOO_LONG;
-    }
-
-    /* Get the ETHREAD corresponding to it */
-    Status = PsLookupProcessThreadByCid(&CapturedReplyMessage.ClientId,
-                                        NULL,
-                                        &WakeupThread);
-    if (!NT_SUCCESS(Status))
-    {
-        /* No thread found, fail */
-        ObDereferenceObject(Port);
-        return Status;
-    }
-
-    /* Allocate a message from the port zone */
-    Message = LpcpAllocateFromPortZone();
-    if (!Message)
-    {
-        /* Fail if we couldn't allocate a message */
-        ObDereferenceObject(WakeupThread);
-        ObDereferenceObject(Port);
-        return STATUS_NO_MEMORY;
-    }
-
-    /* Keep the lock acquired */
-    KeAcquireGuardedMutex(&LpcpLock);
-
-    /* Make sure this is the reply the thread is waiting for */
-    if ((WakeupThread->LpcReplyMessageId != CapturedReplyMessage.MessageId) ||
-        ((LpcpGetMessageFromThread(WakeupThread)) &&
-        (LpcpGetMessageType(&LpcpGetMessageFromThread(WakeupThread)-> Request)
-            != LPC_REQUEST)))
-    {
-        /* It isn't, fail */
-        LpcpFreeToPortZone(Message, LPCP_LOCK_HELD | LPCP_LOCK_RELEASE);
-        ObDereferenceObject(WakeupThread);
-        ObDereferenceObject(Port);
-        return STATUS_REPLY_MESSAGE_MISMATCH;
-    }
-
-    /* Copy the message */
-    _SEH2_TRY
-    {
-        LpcpMoveMessage(&Message->Request,
-                        &CapturedReplyMessage,
-                        ReplyMessage + 1,
-                        LPC_REPLY,
-                        NULL);
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        /* Cleanup and return the exception code */
-        LpcpFreeToPortZone(Message, LPCP_LOCK_HELD | LPCP_LOCK_RELEASE);
-        ObDereferenceObject(WakeupThread);
-        ObDereferenceObject(Port);
-        _SEH2_YIELD(return _SEH2_GetExceptionCode());
-    }
-    _SEH2_END;
-
-    /* Reference the thread while we use it */
-    ObReferenceObject(WakeupThread);
-    Message->RepliedToThread = WakeupThread;
-
-    /* Set this as the reply message */
-    WakeupThread->LpcReplyMessageId = 0;
-    WakeupThread->LpcReplyMessage = (PVOID)Message;
-
-    /* Check if we have messages on the reply chain */
-    if (!(WakeupThread->LpcExitThreadCalled) &&
-        !(IsListEmpty(&WakeupThread->LpcReplyChain)))
-    {
-        /* Remove us from it and reinitialize it */
-        RemoveEntryList(&WakeupThread->LpcReplyChain);
-        InitializeListHead(&WakeupThread->LpcReplyChain);
-    }
-
-    /* Check if this is the message the thread had received */
-    if ((Thread->LpcReceivedMsgIdValid) &&
-        (Thread->LpcReceivedMessageId == CapturedReplyMessage.MessageId))
-    {
-        /* Clear this data */
-        Thread->LpcReceivedMessageId = 0;
-        Thread->LpcReceivedMsgIdValid = FALSE;
-    }
-
-    /* Free any data information */
-    LpcpFreeDataInfoMessage(Port,
-                            CapturedReplyMessage.MessageId,
-                            CapturedReplyMessage.CallbackId,
-                            CapturedReplyMessage.ClientId);
-
-    /* Release the lock and release the LPC semaphore to wake up waiters */
-    KeReleaseGuardedMutex(&LpcpLock);
-    LpcpCompleteWait(&WakeupThread->LpcReplySemaphore);
-
-    /* Now we can let go of the thread */
-    ObDereferenceObject(WakeupThread);
-
-    /* Dereference port object */
-    ObDereferenceObject(Port);
-    return Status;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-NtReplyWaitReceivePortEx(IN HANDLE PortHandle,
-                         OUT PVOID *PortContext OPTIONAL,
-                         IN PPORT_MESSAGE ReplyMessage OPTIONAL,
-                         OUT PPORT_MESSAGE ReceiveMessage,
-                         IN PLARGE_INTEGER Timeout OPTIONAL)
-{
-    NTSTATUS Status;
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(), WaitMode = PreviousMode;
-    PORT_MESSAGE CapturedReplyMessage;
-    LARGE_INTEGER CapturedTimeout;
-    PLPCP_PORT_OBJECT Port, ReceivePort, ConnectionPort = NULL;
-    PLPCP_MESSAGE Message;
-    PETHREAD Thread = PsGetCurrentThread(), WakeupThread;
-    PLPCP_CONNECTION_MESSAGE ConnectMessage;
-    ULONG ConnectionInfoLength;
-
-    PAGED_CODE();
-    LPCTRACE(LPC_REPLY_DEBUG,
-             "Handle: %p. Messages: %p/%p. Context: %p\n",
-             PortHandle,
-             ReplyMessage,
-             ReceiveMessage,
-             PortContext);
-
-    /* Check if the call comes from user mode */
-    if (PreviousMode != KernelMode)
-    {
-        _SEH2_TRY
-        {
-            if (PortContext != NULL)
-                ProbeForWritePointer(PortContext);
-
-            if (ReplyMessage != NULL)
-            {
-                ProbeForRead(ReplyMessage, sizeof(*ReplyMessage), sizeof(ULONG));
-                CapturedReplyMessage = *(volatile PORT_MESSAGE*)ReplyMessage;
-            }
-
-            if (Timeout != NULL)
-            {
-                ProbeForReadLargeInteger(Timeout);
-                CapturedTimeout = *(volatile LARGE_INTEGER*)Timeout;
-                Timeout = &CapturedTimeout;
-            }
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        /* If this is a system thread, then let it page out its stack */
-        if (Thread->SystemThread) WaitMode = UserMode;
-
-        if (ReplyMessage != NULL)
-            CapturedReplyMessage = *ReplyMessage;
-    }
-
-    /* Check if caller has a reply message */
-    if (ReplyMessage)
-    {
-        /* Validate its length */
-        if (((ULONG)CapturedReplyMessage.u1.s1.DataLength + sizeof(PORT_MESSAGE)) >
-             (ULONG)CapturedReplyMessage.u1.s1.TotalLength)
-        {
-            /* Fail */
-            return STATUS_INVALID_PARAMETER;
-        }
-
-        /* Make sure it has a valid ID */
-        if (!CapturedReplyMessage.MessageId) return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Get the Port object */
-    Status = ObReferenceObjectByHandle(PortHandle,
-                                       0,
-                                       LpcPortObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&Port,
-                                       NULL);
-    if (!NT_SUCCESS(Status)) return Status;
-
-    /* Check if the caller has a reply message */
-    if (ReplyMessage)
-    {
-        /* Validate its length in respect to the port object */
-        if (((ULONG)CapturedReplyMessage.u1.s1.TotalLength > Port->MaxMessageLength) ||
-            ((ULONG)CapturedReplyMessage.u1.s1.TotalLength <=
-             (ULONG)CapturedReplyMessage.u1.s1.DataLength))
-        {
-            /* Too large, fail */
-            ObDereferenceObject(Port);
-            return STATUS_PORT_MESSAGE_TOO_LONG;
-        }
-    }
-
-    /* Check if this is anything but a client port */
-    if ((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_CLIENT_PORT)
-    {
-        /* Check if this is the connection port */
-        if (Port->ConnectionPort == Port)
-        {
-            /* Use this port */
-            ConnectionPort = ReceivePort = Port;
-            ObReferenceObject(ConnectionPort);
-        }
-        else
-        {
-            /* Acquire the lock */
-            KeAcquireGuardedMutex(&LpcpLock);
-
-            /* Get the port */
-            ConnectionPort = ReceivePort = Port->ConnectionPort;
-            if (!ConnectionPort)
-            {
-                /* Fail */
-                KeReleaseGuardedMutex(&LpcpLock);
-                ObDereferenceObject(Port);
-                return STATUS_PORT_DISCONNECTED;
-            }
-
-            /* Release lock and reference */
-            ObReferenceObject(ConnectionPort);
-            KeReleaseGuardedMutex(&LpcpLock);
-        }
-    }
-    else
-    {
-        /* Otherwise, use the port itself */
-        ReceivePort = Port;
-    }
-
-    /* Check if the caller gave a reply message */
-    if (ReplyMessage)
-    {
-        /* Get the ETHREAD corresponding to it */
-        Status = PsLookupProcessThreadByCid(&CapturedReplyMessage.ClientId,
-                                            NULL,
-                                            &WakeupThread);
-        if (!NT_SUCCESS(Status))
-        {
-            /* No thread found, fail */
-            ObDereferenceObject(Port);
-            if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-            return Status;
-        }
-
-        /* Allocate a message from the port zone */
-        Message = LpcpAllocateFromPortZone();
-        if (!Message)
-        {
-            /* Fail if we couldn't allocate a message */
-            if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-            ObDereferenceObject(WakeupThread);
-            ObDereferenceObject(Port);
-            return STATUS_NO_MEMORY;
-        }
-
-        /* Keep the lock acquired */
-        KeAcquireGuardedMutex(&LpcpLock);
-
-        /* Make sure this is the reply the thread is waiting for */
-        if ((WakeupThread->LpcReplyMessageId != CapturedReplyMessage.MessageId) ||
-            ((LpcpGetMessageFromThread(WakeupThread)) &&
-             (LpcpGetMessageType(&LpcpGetMessageFromThread(WakeupThread)->Request)
-                != LPC_REQUEST)))
-        {
-            /* It isn't, fail */
-            LpcpFreeToPortZone(Message, LPCP_LOCK_HELD | LPCP_LOCK_RELEASE);
-            if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-            ObDereferenceObject(WakeupThread);
-            ObDereferenceObject(Port);
-            return STATUS_REPLY_MESSAGE_MISMATCH;
-        }
-
-        /* Copy the message */
-        _SEH2_TRY
-        {
-            LpcpMoveMessage(&Message->Request,
-                            &CapturedReplyMessage,
-                            ReplyMessage + 1,
-                            LPC_REPLY,
-                            NULL);
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Cleanup and return the exception code */
-            LpcpFreeToPortZone(Message, LPCP_LOCK_HELD | LPCP_LOCK_RELEASE);
-            if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-            ObDereferenceObject(WakeupThread);
-            ObDereferenceObject(Port);
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-
-        /* Reference the thread while we use it */
-        ObReferenceObject(WakeupThread);
-        Message->RepliedToThread = WakeupThread;
-
-        /* Set this as the reply message */
-        WakeupThread->LpcReplyMessageId = 0;
-        WakeupThread->LpcReplyMessage = (PVOID)Message;
-
-        /* Check if we have messages on the reply chain */
-        if (!(WakeupThread->LpcExitThreadCalled) &&
-            !(IsListEmpty(&WakeupThread->LpcReplyChain)))
-        {
-            /* Remove us from it and reinitialize it */
-            RemoveEntryList(&WakeupThread->LpcReplyChain);
-            InitializeListHead(&WakeupThread->LpcReplyChain);
-        }
-
-        /* Check if this is the message the thread had received */
-        if ((Thread->LpcReceivedMsgIdValid) &&
-            (Thread->LpcReceivedMessageId == CapturedReplyMessage.MessageId))
-        {
-            /* Clear this data */
-            Thread->LpcReceivedMessageId = 0;
-            Thread->LpcReceivedMsgIdValid = FALSE;
-        }
-
-        /* Free any data information */
-        LpcpFreeDataInfoMessage(Port,
-                                CapturedReplyMessage.MessageId,
-                                CapturedReplyMessage.CallbackId,
-                                CapturedReplyMessage.ClientId);
-
-        /* Release the lock and release the LPC semaphore to wake up waiters */
-        KeReleaseGuardedMutex(&LpcpLock);
-        LpcpCompleteWait(&WakeupThread->LpcReplySemaphore);
-
-        /* Now we can let go of the thread */
-        ObDereferenceObject(WakeupThread);
-    }
-
-    /* Now wait for someone to reply to us */
-    LpcpReceiveWait(ReceivePort->MsgQueue.Semaphore, WaitMode);
-    if (Status != STATUS_SUCCESS) goto Cleanup;
-
-    /* Wait done, get the LPC lock */
-    KeAcquireGuardedMutex(&LpcpLock);
-
-    /* Check if we've received nothing */
-    if (IsListEmpty(&ReceivePort->MsgQueue.ReceiveHead))
-    {
-        /* Check if this was a waitable port and wake it */
-        if (ReceivePort->Flags & LPCP_WAITABLE_PORT)
-        {
-            /* Reset its event */
-            KeResetEvent(&ReceivePort->WaitEvent);
-        }
-
-        /* Release the lock and fail */
-        KeReleaseGuardedMutex(&LpcpLock);
-        if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-        ObDereferenceObject(Port);
-        return STATUS_UNSUCCESSFUL;
-    }
-
-    /* Get the message on the queue */
-    Message = CONTAINING_RECORD(RemoveHeadList(&ReceivePort->MsgQueue.ReceiveHead),
-                                LPCP_MESSAGE,
-                                Entry);
-
-    /* Check if the queue is empty now */
-    if (IsListEmpty(&ReceivePort->MsgQueue.ReceiveHead))
-    {
-        /* Check if this was a waitable port */
-        if (ReceivePort->Flags & LPCP_WAITABLE_PORT)
-        {
-            /* Reset its event */
-            KeResetEvent(&ReceivePort->WaitEvent);
-        }
-    }
-
-    /* Re-initialize the message's list entry */
-    InitializeListHead(&Message->Entry);
-
-    /* Set this as the received message */
-    Thread->LpcReceivedMessageId = Message->Request.MessageId;
-    Thread->LpcReceivedMsgIdValid = TRUE;
-
-    _SEH2_TRY
-    {
-        /* Check if this was a connection request */
-        if (LpcpGetMessageType(&Message->Request) == LPC_CONNECTION_REQUEST)
-        {
-            /* Get the connection message */
-            ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);
-            LPCTRACE(LPC_REPLY_DEBUG,
-                     "Request Messages: %p/%p\n",
-                     Message,
-                     ConnectMessage);
-
-            /* Get its length */
-            ConnectionInfoLength = Message->Request.u1.s1.DataLength -
-                                   sizeof(LPCP_CONNECTION_MESSAGE);
-
-            /* Return it as the receive message */
-            *ReceiveMessage = Message->Request;
-
-            /* Clear our stack variable so the message doesn't get freed */
-            Message = NULL;
-
-            /* Setup the receive message */
-            ReceiveMessage->u1.s1.TotalLength = (CSHORT)(sizeof(LPCP_MESSAGE) +
-                                                         ConnectionInfoLength);
-            ReceiveMessage->u1.s1.DataLength = (CSHORT)ConnectionInfoLength;
-            RtlCopyMemory(ReceiveMessage + 1,
-                          ConnectMessage + 1,
-                          ConnectionInfoLength);
-
-            /* Clear the port context if the caller requested one */
-            if (PortContext) *PortContext = NULL;
-        }
-        else if (LpcpGetMessageType(&Message->Request) != LPC_REPLY)
-        {
-            /* Otherwise, this is a new message or event */
-            LPCTRACE(LPC_REPLY_DEBUG,
-                     "Non-Reply Messages: %p/%p\n",
-                     &Message->Request,
-                     (&Message->Request) + 1);
-
-            /* Copy it */
-            LpcpMoveMessage(ReceiveMessage,
-                            &Message->Request,
-                            (&Message->Request) + 1,
-                            0,
-                            NULL);
-
-            /* Return its context */
-            if (PortContext) *PortContext = Message->PortContext;
-
-            /* And check if it has data information */
-            if (Message->Request.u2.s2.DataInfoOffset)
-            {
-                /* It does, save it, and don't free the message below */
-                LpcpSaveDataInfoMessage(Port, Message, LPCP_LOCK_HELD);
-                Message = NULL;
-            }
-        }
-        else
-        {
-            /* This is a reply message, should never happen! */
-            ASSERT(FALSE);
-        }
-    }
-    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-    {
-        Status = _SEH2_GetExceptionCode();
-    }
-    _SEH2_END;
-
-    /* Check if we have a message pointer here */
-    if (Message)
-    {
-        /* Free it and release the lock */
-        LpcpFreeToPortZone(Message, LPCP_LOCK_HELD | LPCP_LOCK_RELEASE);
-    }
-    else
-    {
-        /* Just release the lock */
-        KeReleaseGuardedMutex(&LpcpLock);
-    }
-
-Cleanup:
-    /* All done, dereference the port and return the status */
-    LPCTRACE(LPC_REPLY_DEBUG,
-             "Port: %p. Status: %d\n",
-             Port,
-             Status);
-    if (ConnectionPort) ObDereferenceObject(ConnectionPort);
-    ObDereferenceObject(Port);
-    return Status;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-NtReplyWaitReceivePort(IN HANDLE PortHandle,
-                       OUT PVOID *PortContext OPTIONAL,
-                       IN PPORT_MESSAGE ReplyMessage OPTIONAL,
-                       OUT PPORT_MESSAGE ReceiveMessage)
-{
-    /* Call the newer API */
-    return NtReplyWaitReceivePortEx(PortHandle,
-                                    PortContext,
-                                    ReplyMessage,
-                                    ReceiveMessage,
-                                    NULL);
-}
-
-/*
- * @unimplemented
- */
-NTSTATUS
-NTAPI
-NtReplyWaitReplyPort(IN HANDLE PortHandle,
-                     IN PPORT_MESSAGE ReplyMessage)
-{
-    UNIMPLEMENTED;
-    return STATUS_NOT_IMPLEMENTED;
-}
-
-NTSTATUS
-NTAPI
-LpcpCopyRequestData(
-    IN BOOLEAN Write,
-    IN HANDLE PortHandle,
-    IN PPORT_MESSAGE Message,
-    IN ULONG Index,
-    IN PVOID Buffer,
-    IN ULONG BufferLength,
-    OUT PULONG ReturnLength)
-{
-    NTSTATUS Status;
-    KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
-    PORT_MESSAGE CapturedMessage;
-    PLPCP_PORT_OBJECT Port = NULL;
-    PETHREAD ClientThread = NULL;
-    SIZE_T LocalReturnLength;
-    PLPCP_MESSAGE InfoMessage;
-    PLPCP_DATA_INFO DataInfo;
-    PVOID DataInfoBaseAddress;
-
-    PAGED_CODE();
-
-    /* Check if the call comes from user mode */
-    if (PreviousMode != KernelMode)
-    {
-        _SEH2_TRY
-        {
-            ProbeForRead(Message, sizeof(*Message), sizeof(PVOID));
-            CapturedMessage = *(volatile PORT_MESSAGE*)Message;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            _SEH2_YIELD(return _SEH2_GetExceptionCode());
-        }
-        _SEH2_END;
-    }
-    else
-    {
-        CapturedMessage = *Message;
-    }
-
-    /* Make sure there is any data to copy */
-    if (CapturedMessage.u2.s2.DataInfoOffset == 0)
-    {
-        return STATUS_INVALID_PARAMETER;
-    }
-
-    /* Reference the port handle */
-    Status = ObReferenceObjectByHandle(PortHandle,
-                                       PORT_ALL_ACCESS,
-                                       LpcPortObjectType,
-                                       PreviousMode,
-                                       (PVOID*)&Port,
-                                       NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Failed to reference port handle: 0x%ls\n", Status);
-        return Status;
-    }
-
-    /* Look up the client thread */
-    Status = PsLookupProcessThreadByCid(&CapturedMessage.ClientId,
-                                        NULL,
-                                        &ClientThread);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Failed to lookup client thread for [0x%lx:0x%lx]: 0x%ls\n",
-                CapturedMessage.ClientId.UniqueProcess,
-                CapturedMessage.ClientId.UniqueThread, Status);
-        goto Cleanup;
-    }
-
-    /* Acquire the global LPC lock */
-    KeAcquireGuardedMutex(&LpcpLock);
-
-    /* Check for message id mismatch */
-    if ((ClientThread->LpcReplyMessageId != CapturedMessage.MessageId) ||
-        (CapturedMessage.MessageId == 0))
-    {
-        DPRINT1("LpcReplyMessageId mismatch: 0x%lx/0x%lx.\n",
-                ClientThread->LpcReplyMessageId, CapturedMessage.MessageId);
-        Status = STATUS_REPLY_MESSAGE_MISMATCH;
-        goto CleanupWithLock;
-    }
-
-    /* Validate the port */
-    if (!LpcpValidateClientPort(ClientThread, Port))
-    {
-        DPRINT1("LpcpValidateClientPort failed\n");
-        Status = STATUS_REPLY_MESSAGE_MISMATCH;
-        goto CleanupWithLock;
-    }
-
-    /* Find the message with the data */
-    InfoMessage = LpcpFindDataInfoMessage(Port,
-                                          CapturedMessage.MessageId,
-                                          CapturedMessage.ClientId);
-    if (InfoMessage == NULL)
-    {
-        DPRINT1("LpcpFindDataInfoMessage failed\n");
-        Status = STATUS_INVALID_PARAMETER;
-        goto CleanupWithLock;
-    }
-
-    /* Get the data info */
-    DataInfo = LpcpGetDataInfoFromMessage(&InfoMessage->Request);
-
-    /* Check if the index is within bounds */
-    if (Index >= DataInfo->NumberOfEntries)
-    {
-        DPRINT1("Message data index %lu out of bounds (%lu in msg)\n",
-                Index, DataInfo->NumberOfEntries);
-        Status = STATUS_INVALID_PARAMETER;
-        goto CleanupWithLock;
-    }
-
-    /* Check if the caller wants to read/write more data than expected */
-    if (BufferLength > DataInfo->Entries[Index].DataLength)
-    {
-        DPRINT1("Trying to read more data (%lu) than available (%lu)\n",
-                BufferLength, DataInfo->Entries[Index].DataLength);
-        Status = STATUS_INVALID_PARAMETER;
-        goto CleanupWithLock;
-    }
-
-    /* Get the data pointer */
-    DataInfoBaseAddress = DataInfo->Entries[Index].BaseAddress;
-
-    /* Release the lock */
-    KeReleaseGuardedMutex(&LpcpLock);
-
-    if (Write)
-    {
-        /* Copy data from the caller to the message sender */
-        Status = MmCopyVirtualMemory(PsGetCurrentProcess(),
-                                     Buffer,
-                                     ClientThread->ThreadsProcess,
-                                     DataInfoBaseAddress,
-                                     BufferLength,
-                                     PreviousMode,
-                                     &LocalReturnLength);
-    }
-    else
-    {
-        /* Copy data from the message sender to the caller */
-        Status = MmCopyVirtualMemory(ClientThread->ThreadsProcess,
-                                     DataInfoBaseAddress,
-                                     PsGetCurrentProcess(),
-                                     Buffer,
-                                     BufferLength,
-                                     PreviousMode,
-                                     &LocalReturnLength);
-    }
-
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("MmCopyVirtualMemory failed: 0x%ls\n", Status);
-        goto Cleanup;
-    }
-
-    /* Check if the caller asked to return the copied length */
-    if (ReturnLength != NULL)
-    {
-        _SEH2_TRY
-        {
-            *ReturnLength = LocalReturnLength;
-        }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
-        {
-            /* Ignore */
-            DPRINT1("Exception writing ReturnLength, ignoring\n");
-        }
-        _SEH2_END;
-    }
-
-Cleanup:
-
-    if (ClientThread != NULL)
-        ObDereferenceObject(ClientThread);
-
-    ObDereferenceObject(Port);
-
-    return Status;
-
-CleanupWithLock:
-
-    /* Release the lock */
-    KeReleaseGuardedMutex(&LpcpLock);
-    goto Cleanup;
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-NtReadRequestData(IN HANDLE PortHandle,
-                  IN PPORT_MESSAGE Message,
-                  IN ULONG Index,
-                  IN PVOID Buffer,
-                  IN ULONG BufferLength,
-                  OUT PULONG ReturnLength)
-{
-    /* Call the internal function */
-    return LpcpCopyRequestData(FALSE,
-                               PortHandle,
-                               Message,
-                               Index,
-                               Buffer,
-                               BufferLength,
-                               ReturnLength);
-}
-
-/*
- * @implemented
- */
-NTSTATUS
-NTAPI
-NtWriteRequestData(IN HANDLE PortHandle,
-                   IN PPORT_MESSAGE Message,
-                   IN ULONG Index,
-                   IN PVOID Buffer,
-                   IN ULONG BufferLength,
-                   OUT PULONG ReturnLength)
-{
-    /* Call the internal function */
-    return LpcpCopyRequestData(TRUE,
-                               PortHandle,
-                               Message,
-                               Index,
-                               Buffer,
-                               BufferLength,
-                               ReturnLength);
-}
-
-/* EOF */