Author: ion
Date: Mon Oct 30 17:45:07 2006
New Revision: 24671
URL:
http://svn.reactos.org/svn/reactos?rev=24671&view=rev
Log:
- Implement NtCompleteConnectPort. SMSS can now completely accept new incoming
connections.
Modified:
trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c
Modified: trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/ntlpc/complet…
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c (original)
+++ trunk/reactos/ntoskrnl/lpc/ntlpc/complete.c Mon Oct 30 17:45:07 2006
@@ -14,6 +14,22 @@
#include <internal/debug.h>
/* PRIVATE FUNCTIONS *********************************************************/
+
+VOID
+NTAPI
+LpcpPrepareToWakeClient(IN PETHREAD Thread)
+{
+ PAGED_CODE();
+
+ /* Make sure the thread isn't dying and it has a valid chain */
+ if (!(Thread->LpcExitThreadCalled) &&
+ !(IsListEmpty(&Thread->LpcReplyChain)))
+ {
+ /* Remove it from the list and reinitialize it */
+ RemoveEntryList(&Thread->LpcReplyChain);
+ InitializeListHead(&Thread->LpcReplyChain);
+ }
+}
/* PUBLIC FUNCTIONS **********************************************************/
@@ -266,8 +282,67 @@
NTAPI
NtCompleteConnectPort(IN HANDLE PortHandle)
{
- UNIMPLEMENTED;
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PLPCP_PORT_OBJECT Port;
+ KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
+ PETHREAD Thread;
+ PAGED_CODE();
+ LPCTRACE(LPC_COMPLETE_DEBUG, "Handle: %lx\n", PortHandle);
+
+ /* Get the Port Object */
+ Status = ObReferenceObjectByHandle(PortHandle,
+ PORT_ALL_ACCESS,
+ LpcPortObjectType,
+ PreviousMode,
+ (PVOID*)&Port,
+ NULL);
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Make sure this is a connection port */
+ if ((Port->Flags & LPCP_PORT_TYPE_MASK) != LPCP_COMMUNICATION_PORT)
+ {
+ /* It isn't, fail */
+ ObDereferenceObject(Port);
+ return STATUS_INVALID_PORT_HANDLE;
+ }
+
+ /* Acquire the lock */
+ KeAcquireGuardedMutex(&LpcpLock);
+
+ /* Make sure we have a client thread */
+ if (!Port->ClientThread)
+ {
+ /* We don't, fail */
+ KeReleaseGuardedMutex(&LpcpLock);
+ ObDereferenceObject(Port);
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Get the thread */
+ Thread = Port->ClientThread;
+
+ /* Make sure it has a reply message */
+ if (!Thread->LpcReplyMessage)
+ {
+ /* It doesn't, fail */
+ KeReleaseGuardedMutex(&LpcpLock);
+ ObDereferenceObject(Port);
+ return STATUS_PORT_DISCONNECTED;
+ }
+
+ /* Clear the client thread and wake it up */
+ Port->ClientThread = NULL;
+ LpcpPrepareToWakeClient(Thread);
+
+ /* Release the lock and wait for an answer */
+ KeReleaseGuardedMutex(&LpcpLock);
+ LpcpCompleteWait(&Thread->LpcReplySemaphore);
+
+ /* Dereference the Thread and Port and return */
+ ObDereferenceObject(Port);
+ ObDereferenceObject(Thread);
+ LPCTRACE(LPC_COMPLETE_DEBUG, "Port: %p. Thread: %p\n", Port, Thread);
+ return Status;
}
/* EOF */