--- /dev/null
+/* $Id: close.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/close.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+VOID
+NiClosePort (
+ PVOID ObjectBody,
+ ULONG HandleCount
+ )
+{
+ PEPORT Port = (PEPORT) ObjectBody;
+ LPC_MESSAGE Message;
+
+// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n",
+// ObjectBody, HandleCount, ObGetReferenceCount(Port));
+
+ if ( (HandleCount == 0)
+ && (Port->State == EPORT_CONNECTED_CLIENT)
+ && (ObGetReferenceCount(Port) == 2)
+ )
+ {
+// DPRINT1("All handles closed to client port\n");
+
+ Message.MessageSize = sizeof(LPC_MESSAGE);
+ Message.DataSize = 0;
+
+ EiReplyOrRequestPort (
+ Port->OtherPort,
+ & Message,
+ LPC_PORT_CLOSED,
+ Port
+ );
+ KeSetEvent (
+ & Port->OtherPort->Event,
+ IO_NO_INCREMENT,
+ FALSE
+ );
+
+ Port->OtherPort->OtherPort = NULL;
+ Port->OtherPort->State = EPORT_DISCONNECTED;
+ ObDereferenceObject (Port);
+ }
+ if ( (HandleCount == 0)
+ && (Port->State == EPORT_CONNECTED_SERVER)
+ && (ObGetReferenceCount(Port) == 2)
+ )
+ {
+// DPRINT("All handles closed to server\n");
+
+ Port->OtherPort->OtherPort = NULL;
+ Port->OtherPort->State = EPORT_DISCONNECTED;
+ ObDereferenceObject(Port->OtherPort);
+ }
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+VOID
+NiDeletePort (
+ PVOID ObjectBody
+ )
+{
+// PEPORT Port = (PEPORT)ObjectBody;
+
+// DPRINT1("Deleting port %x\n", Port);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: complete.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/complete.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/***********************************************************************
+ * NAME EXPORTED
+ * NtCompleteConnectPort@4
+ *
+ *
+ */
+EXPORTED
+NTSTATUS
+STDCALL
+NtCompleteConnectPort (HANDLE PortHandle)
+{
+ NTSTATUS Status;
+ PEPORT OurPort;
+
+ DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle);
+
+ Status = ObReferenceObjectByHandle (
+ PortHandle,
+ PORT_ALL_ACCESS,
+ ExPortType,
+ UserMode,
+ (PVOID *) & OurPort,
+ NULL
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ return (Status);
+ }
+
+ KeSetEvent (
+ & OurPort->OtherPort->Event,
+ IO_NO_INCREMENT,
+ FALSE
+ );
+
+ OurPort->State = EPORT_CONNECTED_SERVER;
+
+ ObDereferenceObject (OurPort);
+
+ return (STATUS_SUCCESS);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: connect.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/connect.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * NtConnectPort@32
+ *
+ * DESCRIPTION
+ * Connect to a named port and wait for the other side to
+ * accept the connection.
+ *
+ * ARGUMENTS
+ * ConnectedPort
+ * PortName
+ * Qos
+ * WriteMap
+ * ReadMap
+ * MaxMessageSize
+ * ConnectInfo
+ * UserConnectInfoLength
+ *
+ * RETURN VALUE
+ *
+ */
+NTSTATUS
+STDCALL
+NtConnectPort (
+ PHANDLE ConnectedPort,
+ PUNICODE_STRING PortName,
+ PSECURITY_QUALITY_OF_SERVICE Qos,
+ PLPC_SECTION_WRITE WriteMap,
+ PLPC_SECTION_READ ReadMap,
+ PULONG MaxMessageSize,
+ PVOID ConnectInfo,
+ PULONG UserConnectInfoLength
+ )
+{
+ NTSTATUS Status;
+ PEPORT NamedPort;
+ PEPORT OurPort;
+ HANDLE OurPortHandle;
+ PLPC_MESSAGE Request;
+ PQUEUEDMESSAGE Reply;
+ ULONG ConnectInfoLength;
+ KIRQL oldIrql;
+
+ DPRINT("PortName %x\n", PortName);
+ DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
+
+ /*
+ * Copy in user parameters
+ */
+ memcpy (
+ & ConnectInfoLength,
+ UserConnectInfoLength,
+ sizeof (*UserConnectInfoLength)
+ );
+ /*
+ * Get access to the port
+ */
+ Status = ObReferenceObjectByName (
+ PortName,
+ 0,
+ NULL,
+ PORT_ALL_ACCESS, /* DesiredAccess */
+ ExPortType,
+ UserMode,
+ NULL,
+ (PVOID *) & NamedPort
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("Failed to reference named port (status %x)\n", Status);
+ return (Status);
+ }
+ /*
+ * Create a port to represent our side of the connection
+ */
+ OurPort = ObCreateObject (
+ & OurPortHandle,
+ PORT_ALL_ACCESS,
+ NULL,
+ ExPortType
+ );
+ NiInitializePort(OurPort);
+ /*
+ * Create a request message
+ */
+ DPRINT("Creating request message\n");
+
+ Request = ExAllocatePool (
+ NonPagedPool,
+ (sizeof (LPC_MESSAGE) + ConnectInfoLength)
+ );
+
+ Request->DataSize = ConnectInfoLength;
+ Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
+ Request->SharedSectionSize = 0;
+ if ( (ConnectInfo != NULL)
+ && (ConnectInfoLength > 0)
+ )
+ {
+ memcpy (
+ (PVOID) (Request + 1),
+ ConnectInfo,
+ ConnectInfoLength
+ );
+ }
+ /*
+ * Queue the message to the named port
+ */
+ DPRINT("Queuing message\n");
+
+ EiReplyOrRequestPort (
+ NamedPort,
+ Request,
+ LPC_CONNECTION_REQUEST,
+ OurPort
+ );
+ KeSetEvent (
+ & NamedPort->Event,
+ IO_NO_INCREMENT,
+ FALSE
+ );
+
+ DPRINT("Waiting for connection completion\n");
+
+ /*
+ * Wait for them to accept our connection
+ */
+ KeWaitForSingleObject (
+ & OurPort->Event,
+ UserRequest,
+ UserMode,
+ FALSE,
+ NULL
+ );
+
+ DPRINT("Received connection completion\n");
+ KeAcquireSpinLock (
+ & OurPort->Lock,
+ & oldIrql
+ );
+ Reply = EiDequeueMessagePort (OurPort);
+ KeReleaseSpinLock (
+ & OurPort->Lock,
+ oldIrql
+ );
+ memcpy (
+ ConnectInfo,
+ Reply->MessageData,
+ Reply->Message.DataSize
+ );
+ *UserConnectInfoLength = Reply->Message.DataSize;
+
+ if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
+ {
+ ObDereferenceObject (NamedPort);
+ ObDereferenceObject (OurPort);
+ ZwClose (OurPortHandle);
+ ExFreePool (Request);
+ ExFreePool (Reply);
+ return (STATUS_UNSUCCESSFUL);
+ }
+
+ OurPort->State = EPORT_CONNECTED_CLIENT;
+ *ConnectedPort = OurPortHandle;
+ ExFreePool (Reply);
+ ExFreePool (Request);
+
+ DPRINT("Exited successfully\n");
+
+ return (STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * NtAcceptConnectPort@24
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * ServerPortHandle
+ * NamedPortHandle
+ * LpcMessage
+ * AcceptIt
+ * WriteMap
+ * ReadMap
+ *
+ * RETURN VALUE
+ *
+ */
+EXPORTED
+NTSTATUS
+STDCALL
+NtAcceptConnectPort (
+ PHANDLE ServerPortHandle,
+ HANDLE NamedPortHandle,
+ PLPC_MESSAGE LpcMessage,
+ BOOLEAN AcceptIt,
+ PLPC_SECTION_WRITE WriteMap,
+ PLPC_SECTION_READ ReadMap
+ )
+{
+ NTSTATUS Status;
+ PEPORT NamedPort;
+ PEPORT OurPort = NULL;
+ PQUEUEDMESSAGE ConnectionRequest;
+ KIRQL oldIrql;
+
+ Status = ObReferenceObjectByHandle (
+ NamedPortHandle,
+ PORT_ALL_ACCESS,
+ ExPortType,
+ UserMode,
+ (PVOID *) & NamedPort,
+ NULL
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ return (Status);
+ }
+ /*
+ * Create a port object for our side of the connection
+ */
+ if (AcceptIt == 1)
+ {
+ OurPort = ObCreateObject (
+ ServerPortHandle,
+ PORT_ALL_ACCESS,
+ NULL,
+ ExPortType
+ );
+ NiInitializePort(OurPort);
+ }
+ /*
+ * Dequeue the connection request
+ */
+ KeAcquireSpinLock (& NamedPort->Lock, & oldIrql);
+ ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
+ KeReleaseSpinLock (& NamedPort->Lock, oldIrql);
+
+ if (AcceptIt != 1)
+ {
+ EiReplyOrRequestPort (
+ ConnectionRequest->Sender,
+ LpcMessage,
+ LPC_CONNECTION_REFUSED,
+ NamedPort
+ );
+ KeSetEvent (
+ & ConnectionRequest->Sender->Event,
+ IO_NO_INCREMENT,
+ FALSE
+ );
+ ObDereferenceObject (ConnectionRequest->Sender);
+ ExFreePool (ConnectionRequest);
+ ObDereferenceObject (NamedPort);
+ return (STATUS_SUCCESS);
+ }
+ /*
+ * Connect the two ports
+ */
+ OurPort->OtherPort = ConnectionRequest->Sender;
+ OurPort->OtherPort->OtherPort = OurPort;
+ EiReplyOrRequestPort (
+ ConnectionRequest->Sender,
+ LpcMessage,
+ LPC_REPLY,
+ OurPort
+ );
+ ExFreePool (ConnectionRequest);
+
+ ObDereferenceObject (OurPort);
+ ObDereferenceObject (NamedPort);
+
+ return (STATUS_SUCCESS);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: create.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/create.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+NTSTATUS
+NiCreatePort (
+ PVOID ObjectBody,
+ PVOID Parent,
+ PWSTR RemainingPath,
+ POBJECT_ATTRIBUTES ObjectAttributes
+ )
+{
+ NTSTATUS Status;
+
+ if (RemainingPath == NULL)
+ {
+ return (STATUS_SUCCESS);
+ }
+
+ if (wcschr(RemainingPath+1, '\\') != NULL)
+ {
+ return (STATUS_UNSUCCESSFUL);
+ }
+
+ Status = ObReferenceObjectByPointer (
+ Parent,
+ STANDARD_RIGHTS_REQUIRED,
+ ObDirectoryType,
+ UserMode
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ return (Status);
+ }
+
+ ObAddEntryDirectory (
+ Parent,
+ ObjectBody,
+ (RemainingPath + 1)
+ );
+ ObDereferenceObject (Parent);
+
+ return (STATUS_SUCCESS);
+}
+
+
+EXPORTED
+NTSTATUS
+STDCALL
+NtCreatePort (
+ PHANDLE PortHandle,
+ POBJECT_ATTRIBUTES ObjectAttributes,
+ ULONG MaxConnectInfoLength,
+ ULONG MaxDataLength,
+ ULONG Reserved
+ )
+{
+ PEPORT Port;
+ NTSTATUS Status;
+
+ DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer);
+
+ Port = ObCreateObject (
+ PortHandle,
+ PORT_ALL_ACCESS,
+ ObjectAttributes,
+ ExPortType
+ );
+ if (Port == NULL)
+ {
+ return (STATUS_UNSUCCESSFUL);
+ }
+
+ Status = NiInitializePort (Port);
+ Port->MaxConnectInfoLength = 260;
+ Port->MaxDataLength = 328;
+
+ ObDereferenceObject (Port);
+
+ return (Status);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: listen.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/listen.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * NtListenPort@8
+ *
+ * DESCRIPTION
+ * Listen on a named port and wait for a connection attempt.
+ *
+ * ARGUMENTS
+ * PortHandle [IN] LPC port to listen on.
+ *
+ * ConnectMsg [IN] User provided storage for a
+ * possible connection request LPC message.
+ *
+ * RETURN VALUE
+ * STATUS_SUCCESS if a connection request is received
+ * successfully; otherwise an error code.
+ *
+ * The buffer ConnectMessage is filled with the connection
+ * request message queued by NtConnectPort() in PortHandle.
+ *
+ * NOTE
+ *
+ */
+EXPORTED
+NTSTATUS
+STDCALL
+NtListenPort (
+ IN HANDLE PortHandle,
+ IN PLPC_MESSAGE ConnectMsg
+ )
+{
+ NTSTATUS Status;
+
+ /*
+ * Wait forever for a connection request.
+ */
+ for (;;)
+ {
+ Status = NtReplyWaitReceivePort (
+ PortHandle,
+ NULL,
+ NULL,
+ ConnectMsg
+ );
+ /*
+ * Accept only LPC_CONNECTION_REQUEST requests.
+ * Drop any other message.
+ */
+ if ( !NT_SUCCESS(Status)
+ || (LPC_CONNECTION_REQUEST == ConnectMsg->MessageType)
+ )
+ {
+ DPRINT("Got message (type %x)\n", LPC_CONNECTION_REQUEST);
+ break;
+ }
+ DPRINT("Got message (type %x)\n", ConnectMsg->MessageType);
+ }
+
+ return (Status);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: port.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/port.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ *
+ * 2000-06-04 (ea)
+ * ntoskrnl/nt/port.c moved in ntoskrnl/lpc/port.c
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/* GLOBALS *******************************************************************/
+
+POBJECT_TYPE ExPortType = NULL;
+ULONG EiNextLpcMessageId = 0;
+
+/* FUNCTIONS *****************************************************************/
+
+
+NTSTATUS NiInitPort (VOID)
+{
+ ExPortType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
+
+ RtlInitUnicodeString(&ExPortType->TypeName,L"Port");
+
+ ExPortType->MaxObjects = ULONG_MAX;
+ ExPortType->MaxHandles = ULONG_MAX;
+ ExPortType->TotalObjects = 0;
+ ExPortType->TotalHandles = 0;
+ ExPortType->PagedPoolCharge = 0;
+ ExPortType->NonpagedPoolCharge = sizeof(EPORT);
+ ExPortType->Dump = NULL;
+ ExPortType->Open = NULL;
+ ExPortType->Close = NiClosePort;
+ ExPortType->Delete = NiDeletePort;
+ ExPortType->Parse = NULL;
+ ExPortType->Security = NULL;
+ ExPortType->QueryName = NULL;
+ ExPortType->OkayToClose = NULL;
+ ExPortType->Create = NiCreatePort;
+
+ EiNextLpcMessageId = 0;
+
+ return(STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * NAME INTERNAL
+ * NiInitializePort
+ *
+ * DESCRIPTION
+ * Initialize the EPORT object attributes. The Port
+ * object enters the inactive state.
+ *
+ * ARGUMENTS
+ * Port Pointer to an EPORT object to initialize.
+ *
+ * RETURN VALUE
+ * STATUS_SUCCESS if initialization succedeed. An error code
+ * otherwise.
+ */
+NTSTATUS
+STDCALL
+NiInitializePort (
+ IN OUT PEPORT Port
+ )
+{
+ memset (Port, 0, sizeof(EPORT));
+ KeInitializeSpinLock (& Port->Lock);
+ KeInitializeEvent (& Port->Event, SynchronizationEvent, FALSE);
+ Port->OtherPort = NULL;
+ Port->QueueLength = 0;
+ Port->ConnectQueueLength = 0;
+ Port->State = EPORT_INACTIVE;
+ InitializeListHead (& Port->QueueListHead);
+ InitializeListHead (& Port->ConnectQueueListHead);
+
+ return (STATUS_SUCCESS);
+}
+
+
+/* MISCELLANEA SYSTEM SERVICES */
+
+
+/**********************************************************************
+ * NAME SYSTEM
+ * NtImpersonateClientOfPort@8
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * PortHandle,
+ * ClientMessage
+ *
+ * RETURN VALUE
+ *
+ */
+NTSTATUS
+STDCALL
+NtImpersonateClientOfPort (
+ HANDLE PortHandle,
+ PLPC_MESSAGE ClientMessage
+ )
+{
+ UNIMPLEMENTED;
+}
+
+
+
+/* EOF */
--- /dev/null
+/* $Id: query.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/query.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ * NtQueryInformationPort@20
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ * PortHandle [IN]
+ * PortInformationClass [IN]
+ * PortInformation [OUT]
+ * PortInformationLength [IN]
+ * ReturnLength [OUT]
+ *
+ * RETURN VALUE
+ * STATUS_SUCCESS if the call succedeed. An error code
+ * otherwise.
+ *
+ * NOTES
+ * P. Dabak reports that this system service seems to return
+ * no information.
+ */
+EXPORTED
+NTSTATUS
+STDCALL
+NtQueryInformationPort (
+ IN HANDLE PortHandle,
+ IN CINT PortInformationClass,
+ OUT PVOID PortInformation,
+ IN ULONG PortInformationLength,
+ OUT PULONG ReturnLength
+ )
+{
+ NTSTATUS Status;
+ PEPORT Port;
+
+ Status = ObReferenceObjectByHandle (
+ PortHandle,
+ PORT_ALL_ACCESS, /* AccessRequired */
+ ExPortType,
+ UserMode,
+ (PVOID *) & Port,
+ NULL
+ );
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtQueryInformationPort() = %x\n", Status);
+ return (Status);
+ }
+ /*
+ * FIXME: NT does nothing here!
+ */
+ ObDereferenceObject (Port);
+ return STATUS_SUCCESS;
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: queue.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/queue.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+VOID
+STDCALL
+EiEnqueueMessagePort (
+ IN OUT PEPORT Port,
+ IN PQUEUEDMESSAGE Message
+ )
+{
+ InsertTailList (
+ & Port->QueueListHead,
+ & Message->QueueListEntry
+ );
+ Port->QueueLength++;
+}
+
+
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueMessagePort (
+ IN OUT PEPORT Port
+ )
+{
+ PQUEUEDMESSAGE Message;
+ PLIST_ENTRY entry;
+
+ entry = RemoveHeadList (& Port->QueueListHead);
+ Message = CONTAINING_RECORD (entry, QUEUEDMESSAGE, QueueListEntry);
+ Port->QueueLength--;
+
+ return (Message);
+}
+
+
+VOID
+STDCALL
+EiEnqueueConnectMessagePort (
+ IN OUT PEPORT Port,
+ IN PQUEUEDMESSAGE Message
+ )
+{
+ InsertTailList (
+ & Port->ConnectQueueListHead,
+ & Message->QueueListEntry
+ );
+ Port->ConnectQueueLength++;
+}
+
+
+PQUEUEDMESSAGE
+STDCALL
+EiDequeueConnectMessagePort (
+ IN OUT PEPORT Port
+ )
+{
+ PQUEUEDMESSAGE Message;
+ PLIST_ENTRY entry;
+
+ entry = RemoveHeadList (& Port->ConnectQueueListHead);
+ Message = CONTAINING_RECORD (entry, QUEUEDMESSAGE, QueueListEntry);
+ Port->ConnectQueueLength--;
+
+ return (Message);
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: receive.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/receive.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME SYSTEM
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ */
+NTSTATUS
+STDCALL
+NtReadRequestData (
+ HANDLE PortHandle,
+ PLPC_MESSAGE Message,
+ ULONG Index,
+ PVOID Buffer,
+ ULONG BufferLength,
+ PULONG Returnlength
+ )
+{
+ UNIMPLEMENTED;
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: reply.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/reply.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+EiReplyOrRequestPort (
+ IN PEPORT Port,
+ IN PLPC_MESSAGE LpcReply,
+ IN ULONG MessageType,
+ IN PEPORT Sender
+ )
+{
+ KIRQL oldIrql;
+ PQUEUEDMESSAGE MessageReply;
+
+ MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
+ MessageReply->Sender = Sender;
+
+ if (LpcReply != NULL)
+ {
+ memcpy(&MessageReply->Message, LpcReply, LpcReply->MessageSize);
+ }
+
+ MessageReply->Message.Cid.UniqueProcess = PsGetCurrentProcessId();
+ MessageReply->Message.Cid.UniqueThread = PsGetCurrentThreadId();
+ MessageReply->Message.MessageType = MessageType;
+ MessageReply->Message.MessageId = InterlockedIncrement(&EiNextLpcMessageId);
+
+ KeAcquireSpinLock(&Port->Lock, &oldIrql);
+ EiEnqueueMessagePort(Port, MessageReply);
+ KeReleaseSpinLock(&Port->Lock, oldIrql);
+
+ return(STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtReplyPort (
+ IN HANDLE PortHandle,
+ IN PLPC_MESSAGE LpcReply
+ )
+{
+ NTSTATUS Status;
+ PEPORT Port;
+
+ DPRINT("NtReplyPort(PortHandle %x, LpcReply %x)\n", PortHandle, LpcReply);
+
+ Status = ObReferenceObjectByHandle(PortHandle,
+ PORT_ALL_ACCESS, /* AccessRequired */
+ ExPortType,
+ UserMode,
+ (PVOID*)&Port,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtReplyPort() = %x\n", Status);
+ return(Status);
+ }
+
+ Status = EiReplyOrRequestPort(Port->OtherPort,
+ LpcReply,
+ LPC_REPLY,
+ Port);
+ KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+
+ ObDereferenceObject(Port);
+
+ return(Status);
+}
+
+
+/**********************************************************************
+ * NAME EXPORTED
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtReplyWaitReceivePort (
+ HANDLE PortHandle,
+ PULONG PortId,
+ PLPC_MESSAGE LpcReply,
+ PLPC_MESSAGE LpcMessage
+ )
+{
+ NTSTATUS Status;
+ PEPORT Port;
+ KIRQL oldIrql;
+ PQUEUEDMESSAGE Request;
+
+ DPRINT("NtReplyWaitReceivePort(PortHandle %x, LpcReply %x, "
+ "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
+
+ Status = ObReferenceObjectByHandle(PortHandle,
+ PORT_ALL_ACCESS,
+ ExPortType,
+ UserMode,
+ (PVOID*)&Port,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtReplyWaitReceivePort() = %x\n", Status);
+ return(Status);
+ }
+
+ /*
+ * Send the reply
+ */
+ if (LpcReply != NULL)
+ {
+ Status = EiReplyOrRequestPort(Port->OtherPort,
+ LpcReply,
+ LPC_REPLY,
+ Port);
+ KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+
+ if (!NT_SUCCESS(Status))
+ {
+ ObDereferenceObject(Port);
+ return(Status);
+ }
+ }
+
+ /*
+ * Want for a message to be received
+ */
+ DPRINT("Entering wait for message\n");
+ KeWaitForSingleObject(&Port->Event,
+ UserRequest,
+ UserMode,
+ FALSE,
+ NULL);
+ DPRINT("Woke from wait for message\n");
+
+ /*
+ * Dequeue the message
+ */
+ KeAcquireSpinLock(&Port->Lock, &oldIrql);
+ Request = EiDequeueMessagePort(Port);
+ memcpy(LpcMessage, &Request->Message, Request->Message.MessageSize);
+ if (Request->Message.MessageType == LPC_CONNECTION_REQUEST)
+ {
+ EiEnqueueConnectMessagePort(Port, Request);
+ KeReleaseSpinLock(&Port->Lock, oldIrql);
+ }
+ else
+ {
+ KeReleaseSpinLock(&Port->Lock, oldIrql);
+ ExFreePool(Request);
+ }
+
+ /*
+ *
+ */
+ ObDereferenceObject(Port);
+ return(STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtReplyWaitReplyPort (
+ HANDLE PortHandle,
+ PLPC_MESSAGE ReplyMessage
+ )
+{
+ UNIMPLEMENTED;
+}
+
+
+/* EOF */
--- /dev/null
+/* $Id: send.c,v 1.1 2000/06/04 17:27:39 ea Exp $
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/lpc/send.c
+ * PURPOSE: Communication mechanism
+ * PROGRAMMER: David Welch (welch@cwcom.net)
+ * UPDATE HISTORY:
+ * Created 22/05/98
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ddk/ntddk.h>
+#include <internal/ob.h>
+#include <string.h>
+#include <internal/string.h>
+#include <internal/port.h>
+#include <internal/dbg.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+LpcSendTerminationPort (
+ IN PEPORT Port,
+ IN TIME CreationTime
+ )
+{
+ NTSTATUS Status;
+ LPC_TERMINATION_MESSAGE Msg;
+
+ Msg.CreationTime = CreationTime;
+ Status = LpcRequestPort (
+ Port,
+ & Msg.Header
+ );
+ return(Status);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+LpcSendDebugMessagePort (
+ IN PEPORT Port,
+ IN PLPC_DBG_MESSAGE Message
+ )
+{
+ NTSTATUS Status;
+
+ Status = LpcRequestPort(Port,
+ &Message->Header);
+ return(Status);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+LpcRequestPort (
+ IN PEPORT Port,
+ IN PLPC_MESSAGE LpcMessage
+ )
+{
+ NTSTATUS Status;
+
+ DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port, LpcMessage);
+
+ Status = EiReplyOrRequestPort(Port,
+ LpcMessage,
+ LPC_DATAGRAM,
+ Port);
+ KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE);
+
+ return(Status);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtRequestPort (
+ IN HANDLE PortHandle,
+ IN PLPC_MESSAGE LpcMessage
+ )
+{
+ NTSTATUS Status;
+ PEPORT Port;
+
+ DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle,
+ LpcMessage);
+
+ Status = ObReferenceObjectByHandle(PortHandle,
+ PORT_ALL_ACCESS,
+ ExPortType,
+ UserMode,
+ (PVOID*)&Port,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtRequestPort() = %x\n", Status);
+ return(Status);
+ }
+
+ Status = LpcRequestPort(Port->OtherPort,
+ LpcMessage);
+
+ ObDereferenceObject(Port);
+ return(Status);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtRequestWaitReplyPort (
+ IN HANDLE PortHandle,
+ PLPC_MESSAGE LpcRequest,
+ PLPC_MESSAGE LpcReply
+ )
+{
+ NTSTATUS Status;
+ PEPORT Port;
+ PQUEUEDMESSAGE Message;
+ KIRQL oldIrql;
+
+ DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
+ "LpcReply %x)\n", PortHandle, LpcRequest, LpcReply);
+
+ Status = ObReferenceObjectByHandle(PortHandle,
+ PORT_ALL_ACCESS,
+ ExPortType,
+ UserMode,
+ (PVOID*)&Port,
+ NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ return(Status);
+ }
+
+
+ Status = EiReplyOrRequestPort(Port->OtherPort,
+ LpcRequest,
+ LPC_REQUEST,
+ Port);
+ KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DbgPrint("Enqueue failed\n");
+ ObDereferenceObject(Port);
+ return(Status);
+ }
+
+ /*
+ * Wait for a reply
+ */
+ KeWaitForSingleObject(&Port->Event,
+ UserRequest,
+ UserMode,
+ FALSE,
+ NULL);
+
+ /*
+ * Dequeue the reply
+ */
+ KeAcquireSpinLock(&Port->Lock, &oldIrql);
+ Message = EiDequeueMessagePort(Port);
+ KeReleaseSpinLock(&Port->Lock, oldIrql);
+ DPRINT("Message->Message.MessageSize %d\n",
+ Message->Message.MessageSize);
+ memcpy(LpcReply, &Message->Message, Message->Message.MessageSize);
+ ExFreePool(Message);
+
+ ObDereferenceObject(Port);
+
+ return(STATUS_SUCCESS);
+}
+
+
+/**********************************************************************
+ * NAME
+ *
+ * DESCRIPTION
+ *
+ * ARGUMENTS
+ *
+ * RETURN VALUE
+ *
+ * REVISIONS
+ *
+ */
+NTSTATUS
+STDCALL
+NtWriteRequestData (
+ HANDLE PortHandle,
+ PLPC_MESSAGE Message,
+ ULONG Index,
+ PVOID Buffer,
+ ULONG BufferLength,
+ PULONG ReturnLength
+ )
+{
+ UNIMPLEMENTED;
+}
+
+
+/* EOF */
-# $Id: makefile_rex,v 1.70 2000/05/07 23:04:43 ekohl Exp $
+# $Id: makefile_rex,v 1.71 2000/06/04 17:27:35 ea Exp $
#
# ReactOS Operating System
#
nt/ntsem.o \
nt/nttimer.o \
nt/plugplay.o \
- nt/port.o \
nt/profile.o \
nt/zw.o
ldr/sysdll.o \
ldr/userldr.o
+# Local Procedure Call (Lpc)
+OBJECTS_LPC = \
+ lpc/close.o \
+ lpc/complete.o \
+ lpc/connect.o \
+ lpc/create.o \
+ lpc/listen.o \
+ lpc/port.o \
+ lpc/query.o \
+ lpc/queue.o \
+ lpc/receive.o \
+ lpc/reply.o \
+ lpc/send.o
+
# Nation Language Support Library (Nls)
OBJECTS_NLS = nls/nls.o
-o $(OBJECTS_PATH)/ldr.o \
$(OBJECTS_LDR)
+$(OBJECTS_PATH)/lpc.o: $(OBJECTS_LPC)
+ $(LD) \
+ -r \
+ -o $(OBJECTS_PATH)/lpc.o \
+ $(OBJECTS_LPC)
+
$(OBJECTS_PATH)/nls.o: $(OBJECTS_NLS)
$(LD) \
-r \
$(OBJECTS_PATH)/cm.o \
$(OBJECTS_PATH)/dbg.o \
$(OBJECTS_PATH)/ex.o \
+ $(OBJECTS_PATH)/lpc.o \
$(OBJECTS_PATH)/fs.o \
$(OBJECTS_PATH)/io.o \
$(OBJECTS_PATH)/kd.o \
ifeq ($(DOSCLI),yes)
CLEAN_FILES = $(OBJECTS_PATH)\*.o cc\*.o cm\*.o dbg\*.o ex\*.o hal\x86\*.o io\*.o \
ke\*.o ldr\*.o mm\*.o nt\*.o ob\*.o ps\*.o rtl\*.o se\*.o \
- ke\i386\*.o mm\i386\*.o fs\*.o po\*.o nls\*.o \
+ ke\i386\*.o mm\i386\*.o fs\*.o po\*.o nls\*.o lpc\*.o \
kd\*.o utils\export\export.exe $(TARGETNAME).o $(TARGETNAME).a junk.tmp \
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
else
CLEAN_FILES = $(OBJECTS_PATH)/*.o cc/*.o cm/*.o dbg/*.o ex/*.o hal/x86/*.o io/*.o \
ke/*.o ldr/*.o mm/*.o nt/*.o ob/*.o ps/*.o rtl/*.o se/*.o \
- ke/i386/*.o mm/i386/*.o fs/*.o po/*.o nls/*.o \
+ ke/i386/*.o mm/i386/*.o fs/*.o po/*.o nls/*.o lpc/*.o \
kd/*.o utils/export/export $(TARGETNAME).o $(TARGETNAME).a junk.tmp \
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
endif
WARNINGS_ARE_ERRORS = yes
include ../rules.mak
+# EOF
+++ /dev/null
-/* $Id: port.c,v 1.19 2000/04/07 02:24:02 dwelch Exp $
- *
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: ntoskrnl/nt/port.c
- * PURPOSE: Communication mechanism
- * PROGRAMMER: David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- * Created 22/05/98
- */
-
-/* INCLUDES *****************************************************************/
-
-#include <ddk/ntddk.h>
-#include <internal/ob.h>
-#include <string.h>
-#include <internal/string.h>
-#include <internal/port.h>
-#include <internal/dbg.h>
-
-#define NDEBUG
-#include <internal/debug.h>
-
-
-/* TYPES ********************************************************************/
-
-#define EPORT_INACTIVE (0)
-#define EPORT_WAIT_FOR_CONNECT (1)
-#define EPORT_WAIT_FOR_ACCEPT (2)
-#define EPORT_WAIT_FOR_COMPLETE_SRV (3)
-#define EPORT_WAIT_FOR_COMPLETE_CLT (4)
-#define EPORT_CONNECTED_CLIENT (5)
-#define EPORT_CONNECTED_SERVER (6)
-#define EPORT_DISCONNECTED (7)
-
-struct _EPORT;
-
-typedef struct _QUEUEDMESSAGE
-{
- struct _EPORT* Sender;
- LIST_ENTRY QueueListEntry;
- LPC_MESSAGE Message;
- UCHAR MessageData[MAX_MESSAGE_DATA];
-} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
-
-/* GLOBALS *******************************************************************/
-
-POBJECT_TYPE ExPortType = NULL;
-static ULONG EiNextLpcMessageId;
-
-/* FUNCTIONS *****************************************************************/
-
-VOID EiEnqueueMessagePort(PEPORT Port, PQUEUEDMESSAGE Message)
-{
- InsertTailList(&Port->QueueListHead, &Message->QueueListEntry);
- Port->QueueLength++;
-}
-
-PQUEUEDMESSAGE EiDequeueMessagePort(PEPORT Port)
-{
- PQUEUEDMESSAGE Message;
- PLIST_ENTRY entry;
-
- entry = RemoveHeadList(&Port->QueueListHead);
- Message = CONTAINING_RECORD(entry, QUEUEDMESSAGE, QueueListEntry);
- Port->QueueLength--;
-
- return(Message);
-}
-
-VOID EiEnqueueConnectMessagePort(PEPORT Port, PQUEUEDMESSAGE Message)
-{
- InsertTailList(&Port->ConnectQueueListHead, &Message->QueueListEntry);
- Port->ConnectQueueLength++;
-}
-
-PQUEUEDMESSAGE EiDequeueConnectMessagePort(PEPORT Port)
-{
- PQUEUEDMESSAGE Message;
- PLIST_ENTRY entry;
-
- entry = RemoveHeadList(&Port->ConnectQueueListHead);
- Message = CONTAINING_RECORD(entry, QUEUEDMESSAGE, QueueListEntry);
- Port->ConnectQueueLength--;
-
- return(Message);
-}
-
-NTSTATUS EiReplyOrRequestPort(PEPORT Port,
- PLPC_MESSAGE LpcReply,
- ULONG MessageType,
- PEPORT Sender)
-{
- KIRQL oldIrql;
- PQUEUEDMESSAGE MessageReply;
-
- MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
- MessageReply->Sender = Sender;
-
- if (LpcReply != NULL)
- {
- memcpy(&MessageReply->Message, LpcReply, LpcReply->MessageSize);
- }
-
- MessageReply->Message.Cid.UniqueProcess = PsGetCurrentProcessId();
- MessageReply->Message.Cid.UniqueThread = PsGetCurrentThreadId();
- MessageReply->Message.MessageType = MessageType;
- MessageReply->Message.MessageId = InterlockedIncrement(&EiNextLpcMessageId);
-
- KeAcquireSpinLock(&Port->Lock, &oldIrql);
- EiEnqueueMessagePort(Port, MessageReply);
- KeReleaseSpinLock(&Port->Lock, oldIrql);
-
- return(STATUS_SUCCESS);
-}
-
-VOID NiClosePort(PVOID ObjectBody,
- ULONG HandleCount)
-{
- PEPORT Port = (PEPORT)ObjectBody;
- LPC_MESSAGE Message;
-
-// DPRINT1("NiClosePort(ObjectBody %x, HandleCount %d) RefCount %d\n",
-// ObjectBody, HandleCount, ObGetReferenceCount(Port));
-
- if (HandleCount == 0 &&
- Port->State == EPORT_CONNECTED_CLIENT &&
- ObGetReferenceCount(Port) == 2)
- {
-// DPRINT1("All handles closed to client port\n");
-
- Message.MessageSize = sizeof(LPC_MESSAGE);
- Message.DataSize = 0;
-
- EiReplyOrRequestPort(Port->OtherPort,
- &Message,
- LPC_PORT_CLOSED,
- Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
- Port->OtherPort->OtherPort = NULL;
- Port->OtherPort->State = EPORT_DISCONNECTED;
- ObDereferenceObject(Port);
- }
- if (HandleCount == 0 &&
- Port->State == EPORT_CONNECTED_SERVER &&
- ObGetReferenceCount(Port) == 2)
- {
-// DPRINT("All handles closed to server\n");
-
- Port->OtherPort->OtherPort = NULL;
- Port->OtherPort->State = EPORT_DISCONNECTED;
- ObDereferenceObject(Port->OtherPort);
- }
-}
-
-VOID NiDeletePort(PVOID ObjectBody)
-{
-// PEPORT Port = (PEPORT)ObjectBody;
-
-// DPRINT1("Deleting port %x\n", Port);
-}
-
-NTSTATUS NiCreatePort(PVOID ObjectBody,
- PVOID Parent,
- PWSTR RemainingPath,
- POBJECT_ATTRIBUTES ObjectAttributes)
-{
- NTSTATUS Status;
-
- if (RemainingPath == NULL)
- {
- return(STATUS_SUCCESS);
- }
-
- if (wcschr(RemainingPath+1, '\\') != NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- Status = ObReferenceObjectByPointer(Parent,
- STANDARD_RIGHTS_REQUIRED,
- ObDirectoryType,
- UserMode);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- ObAddEntryDirectory(Parent, ObjectBody, RemainingPath+1);
- ObDereferenceObject(Parent);
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS NiInitPort(VOID)
-{
- ExPortType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
-
- RtlInitUnicodeString(&ExPortType->TypeName,L"Port");
-
- ExPortType->MaxObjects = ULONG_MAX;
- ExPortType->MaxHandles = ULONG_MAX;
- ExPortType->TotalObjects = 0;
- ExPortType->TotalHandles = 0;
- ExPortType->PagedPoolCharge = 0;
- ExPortType->NonpagedPoolCharge = sizeof(EPORT);
- ExPortType->Dump = NULL;
- ExPortType->Open = NULL;
- ExPortType->Close = NiClosePort;
- ExPortType->Delete = NiDeletePort;
- ExPortType->Parse = NULL;
- ExPortType->Security = NULL;
- ExPortType->QueryName = NULL;
- ExPortType->OkayToClose = NULL;
- ExPortType->Create = NiCreatePort;
-
- EiNextLpcMessageId = 0;
-
- return(STATUS_SUCCESS);
-}
-
-static NTSTATUS NiInitializePort(PEPORT Port)
-{
- memset(Port, 0, sizeof(EPORT));
- KeInitializeSpinLock(&Port->Lock);
- KeInitializeEvent(&Port->Event, SynchronizationEvent, FALSE);
- Port->OtherPort = NULL;
- Port->QueueLength = 0;
- Port->ConnectQueueLength = 0;
- Port->State = EPORT_INACTIVE;
- InitializeListHead(&Port->QueueListHead);
- InitializeListHead(&Port->ConnectQueueListHead);
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
- POBJECT_ATTRIBUTES ObjectAttributes,
- ULONG MaxConnectInfoLength,
- ULONG MaxDataLength,
- ULONG Reserved)
-{
- PEPORT Port;
- NTSTATUS Status;
-
- DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer);
-
- Port = ObCreateObject(PortHandle,
- PORT_ALL_ACCESS,
- ObjectAttributes,
- ExPortType);
- if (Port == NULL)
- {
- return(STATUS_UNSUCCESSFUL);
- }
-
- Status = NiInitializePort(Port);
- Port->MaxConnectInfoLength = 260;
- Port->MaxDataLength = 328;
-
- ObDereferenceObject(Port);
-
- return(Status);
-}
-
-NTSTATUS STDCALL NtConnectPort (PHANDLE ConnectedPort,
- PUNICODE_STRING PortName,
- PSECURITY_QUALITY_OF_SERVICE Qos,
- PLPC_SECTION_WRITE WriteMap,
- PLPC_SECTION_READ ReadMap,
- PULONG MaxMessageSize,
- PVOID ConnectInfo,
- PULONG UserConnectInfoLength)
-/*
- * FUNCTION: Connect to a named port and wait for the other side to
- * accept the connection
- */
-{
- NTSTATUS Status;
- PEPORT NamedPort;
- PEPORT OurPort;
- HANDLE OurPortHandle;
- PLPC_MESSAGE Request;
- PQUEUEDMESSAGE Reply;
- ULONG ConnectInfoLength;
- KIRQL oldIrql;
-
- DPRINT("PortName %x\n", PortName);
- DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
-
- /*
- * Copy in user parameters
- */
- memcpy(&ConnectInfoLength,
- UserConnectInfoLength,
- sizeof(*UserConnectInfoLength));
-
- /*
- * Get access to the port
- */
- Status = ObReferenceObjectByName(PortName,
- 0,
- NULL,
- PORT_ALL_ACCESS, /* DesiredAccess */
- ExPortType,
- UserMode,
- NULL,
- (PVOID*)&NamedPort);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("Failed to reference named port (status %x)\n", Status);
- return(Status);
- }
-
- /*
- * Create a port to represent our side of the connection
- */
- OurPort = ObCreateObject(&OurPortHandle,
- PORT_ALL_ACCESS,
- NULL,
- ExPortType);
- NiInitializePort(OurPort);
-
- /*
- * Create a request message
- */
- DPRINT("Creating request message\n");
-
- Request = ExAllocatePool(NonPagedPool,
- sizeof(LPC_MESSAGE) + ConnectInfoLength);
-
- Request->DataSize = ConnectInfoLength;
- Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
- Request->SharedSectionSize = 0;
- if (ConnectInfo != NULL && ConnectInfoLength > 0)
- {
- memcpy((PVOID)(Request + 1), ConnectInfo, ConnectInfoLength);
- }
-
- /*
- * Queue the message to the named port
- */
- DPRINT("Queuing message\n");
-
- EiReplyOrRequestPort(NamedPort, Request, LPC_CONNECTION_REQUEST, OurPort);
- KeSetEvent(&NamedPort->Event, IO_NO_INCREMENT, FALSE);
-
- DPRINT("Waiting for connection completion\n");
-
- /*
- * Wait for them to accept our connection
- */
- KeWaitForSingleObject(&OurPort->Event,
- UserRequest,
- UserMode,
- FALSE,
- NULL);
-
- DPRINT("Received connection completion\n");
- KeAcquireSpinLock(&OurPort->Lock, &oldIrql);
- Reply = EiDequeueMessagePort(OurPort);
- KeReleaseSpinLock(&OurPort->Lock, oldIrql);
- memcpy(ConnectInfo,
- Reply->MessageData,
- Reply->Message.DataSize);
- *UserConnectInfoLength = Reply->Message.DataSize;
-
- if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
- {
- ObDereferenceObject(NamedPort);
- ObDereferenceObject(OurPort);
- ZwClose(OurPortHandle);
- ExFreePool(Request);
- ExFreePool(Reply);
- return(STATUS_UNSUCCESSFUL);
- }
-
- OurPort->State = EPORT_CONNECTED_CLIENT;
- *ConnectedPort = OurPortHandle;
- ExFreePool(Reply);
- ExFreePool(Request);
-
- DPRINT("Exited successfully\n");
-
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE ServerPortHandle,
- HANDLE NamedPortHandle,
- PLPC_MESSAGE LpcMessage,
- BOOLEAN AcceptIt,
- PLPC_SECTION_WRITE WriteMap,
- PLPC_SECTION_READ ReadMap)
-{
- NTSTATUS Status;
- PEPORT NamedPort;
- PEPORT OurPort = NULL;
- PQUEUEDMESSAGE ConnectionRequest;
- KIRQL oldIrql;
-
- Status = ObReferenceObjectByHandle(NamedPortHandle,
- PORT_ALL_ACCESS,
- ExPortType,
- UserMode,
- (PVOID*)&NamedPort,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- /*
- * Create a port object for our side of the connection
- */
- if (AcceptIt == 1)
- {
- OurPort = ObCreateObject(ServerPortHandle,
- PORT_ALL_ACCESS,
- NULL,
- ExPortType);
- NiInitializePort(OurPort);
- }
-
- /*
- * Dequeue the connection request
- */
- KeAcquireSpinLock(&NamedPort->Lock, &oldIrql);
- ConnectionRequest = EiDequeueConnectMessagePort(NamedPort);
- KeReleaseSpinLock(&NamedPort->Lock, oldIrql);
-
- if (AcceptIt != 1)
- {
- EiReplyOrRequestPort(ConnectionRequest->Sender,
- LpcMessage,
- LPC_CONNECTION_REFUSED,
- NamedPort);
- KeSetEvent(&ConnectionRequest->Sender->Event, IO_NO_INCREMENT, FALSE);
- ObDereferenceObject(ConnectionRequest->Sender);
- ExFreePool(ConnectionRequest);
- ObDereferenceObject(NamedPort);
- return(STATUS_SUCCESS);
- }
-
- /*
- * Connect the two ports
- */
- OurPort->OtherPort = ConnectionRequest->Sender;
- OurPort->OtherPort->OtherPort = OurPort;
- EiReplyOrRequestPort(ConnectionRequest->Sender,
- LpcMessage,
- LPC_REPLY,
- OurPort);
- ExFreePool(ConnectionRequest);
-
- ObDereferenceObject(OurPort);
- ObDereferenceObject(NamedPort);
-
- return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle)
-{
- NTSTATUS Status;
- PEPORT OurPort;
-
- DPRINT("NtCompleteConnectPort(PortHandle %x)\n", PortHandle);
-
- Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS,
- ExPortType,
- UserMode,
- (PVOID*)&OurPort,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
- KeSetEvent(&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
- OurPort->State = EPORT_CONNECTED_SERVER;
-
- ObDereferenceObject(OurPort);
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtImpersonateClientOfPort (HANDLE PortHandle,
- PLPC_MESSAGE ClientMessage)
-{
- UNIMPLEMENTED;
-}
-
-
-NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle,
- IN PLPC_MESSAGE ConnectMsg)
-/*
- * FUNCTION: Listen on a named port and wait for a connection attempt
- */
-{
- NTSTATUS Status;
-
- for(;;)
- {
- Status = NtReplyWaitReceivePort(PortHandle,
- NULL,
- NULL,
- ConnectMsg);
- DPRINT("Got message (type %x)\n", LPC_CONNECTION_REQUEST);
- if (!NT_SUCCESS(Status) ||
- ConnectMsg->MessageType == LPC_CONNECTION_REQUEST)
- {
- break;
- }
- }
- return(Status);
-}
-
-
-NTSTATUS STDCALL NtQueryInformationPort (IN HANDLE PortHandle,
- IN CINT PortInformationClass,
- OUT PVOID PortInformation,
- IN ULONG PortInformationLength,
- OUT PULONG ReturnLength)
-{
- UNIMPLEMENTED;
-}
-
-
-NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle,
- IN PLPC_MESSAGE LpcReply)
-{
- NTSTATUS Status;
- PEPORT Port;
-
- DPRINT("NtReplyPort(PortHandle %x, LpcReply %x)\n", PortHandle, LpcReply);
-
- Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS, /* AccessRequired */
- ExPortType,
- UserMode,
- (PVOID*)&Port,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtReplyPort() = %x\n", Status);
- return(Status);
- }
-
- Status = EiReplyOrRequestPort(Port->OtherPort,
- LpcReply,
- LPC_REPLY,
- Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
- ObDereferenceObject(Port);
-
- return(Status);
-}
-
-
-NTSTATUS STDCALL NtReplyWaitReceivePort (HANDLE PortHandle,
- PULONG PortId,
- PLPC_MESSAGE LpcReply,
- PLPC_MESSAGE LpcMessage)
-{
- NTSTATUS Status;
- PEPORT Port;
- KIRQL oldIrql;
- PQUEUEDMESSAGE Request;
-
- DPRINT("NtReplyWaitReceivePort(PortHandle %x, LpcReply %x, "
- "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
-
- Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS,
- ExPortType,
- UserMode,
- (PVOID*)&Port,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtReplyWaitReceivePort() = %x\n", Status);
- return(Status);
- }
-
- /*
- * Send the reply
- */
- if (LpcReply != NULL)
- {
- Status = EiReplyOrRequestPort(Port->OtherPort,
- LpcReply,
- LPC_REPLY,
- Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
- if (!NT_SUCCESS(Status))
- {
- ObDereferenceObject(Port);
- return(Status);
- }
- }
-
- /*
- * Want for a message to be received
- */
- DPRINT("Entering wait for message\n");
- KeWaitForSingleObject(&Port->Event,
- UserRequest,
- UserMode,
- FALSE,
- NULL);
- DPRINT("Woke from wait for message\n");
-
- /*
- * Dequeue the message
- */
- KeAcquireSpinLock(&Port->Lock, &oldIrql);
- Request = EiDequeueMessagePort(Port);
- memcpy(LpcMessage, &Request->Message, Request->Message.MessageSize);
- if (Request->Message.MessageType == LPC_CONNECTION_REQUEST)
- {
- EiEnqueueConnectMessagePort(Port, Request);
- KeReleaseSpinLock(&Port->Lock, oldIrql);
- }
- else
- {
- KeReleaseSpinLock(&Port->Lock, oldIrql);
- ExFreePool(Request);
- }
-
- /*
- *
- */
- ObDereferenceObject(Port);
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL LpcSendTerminationPort(PEPORT Port,
- TIME CreationTime)
-{
- NTSTATUS Status;
- LPC_TERMINATION_MESSAGE Msg;
-
- Msg.CreationTime = CreationTime;
- Status = LpcRequestPort(Port,
- &Msg.Header);
- return(Status);
-}
-
-NTSTATUS STDCALL LpcSendDebugMessagePort(PEPORT Port,
- PLPC_DBG_MESSAGE Message)
-{
- NTSTATUS Status;
-
- Status = LpcRequestPort(Port,
- &Message->Header);
- return(Status);
-}
-
-NTSTATUS STDCALL LpcRequestPort(PEPORT Port,
- PLPC_MESSAGE LpcMessage)
-{
- NTSTATUS Status;
-
- DPRINT("LpcRequestPort(PortHandle %x LpcMessage %x)\n", Port, LpcMessage);
-
- Status = EiReplyOrRequestPort(Port,
- LpcMessage,
- LPC_DATAGRAM,
- Port);
- KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE);
-
- return(Status);
-}
-
-NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle,
- IN PLPC_MESSAGE LpcMessage)
-{
- NTSTATUS Status;
- PEPORT Port;
-
- DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle,
- LpcMessage);
-
- Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS,
- ExPortType,
- UserMode,
- (PVOID*)&Port,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- DPRINT("NtRequestPort() = %x\n", Status);
- return(Status);
- }
-
- Status = LpcRequestPort(Port->OtherPort,
- LpcMessage);
-
- ObDereferenceObject(Port);
- return(Status);
-}
-
-
-NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle,
- PLPC_MESSAGE LpcRequest,
- PLPC_MESSAGE LpcReply)
-{
- NTSTATUS Status;
- PEPORT Port;
- PQUEUEDMESSAGE Message;
- KIRQL oldIrql;
-
- DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
- "LpcReply %x)\n", PortHandle, LpcRequest, LpcReply);
-
- Status = ObReferenceObjectByHandle(PortHandle,
- PORT_ALL_ACCESS,
- ExPortType,
- UserMode,
- (PVOID*)&Port,
- NULL);
- if (!NT_SUCCESS(Status))
- {
- return(Status);
- }
-
-
- Status = EiReplyOrRequestPort(Port->OtherPort,
- LpcRequest,
- LPC_REQUEST,
- Port);
- KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE);
-
- if (!NT_SUCCESS(Status))
- {
- DbgPrint("Enqueue failed\n");
- ObDereferenceObject(Port);
- return(Status);
- }
-
- /*
- * Wait for a reply
- */
- KeWaitForSingleObject(&Port->Event,
- UserRequest,
- UserMode,
- FALSE,
- NULL);
-
- /*
- * Dequeue the reply
- */
- KeAcquireSpinLock(&Port->Lock, &oldIrql);
- Message = EiDequeueMessagePort(Port);
- KeReleaseSpinLock(&Port->Lock, oldIrql);
- DPRINT("Message->Message.MessageSize %d\n",
- Message->Message.MessageSize);
- memcpy(LpcReply, &Message->Message, Message->Message.MessageSize);
- ExFreePool(Message);
-
- ObDereferenceObject(Port);
-
- return(STATUS_SUCCESS);
-}
-
-NTSTATUS STDCALL NtReplyWaitReplyPort(HANDLE PortHandle,
- PLPC_MESSAGE ReplyMessage)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtReadRequestData (HANDLE PortHandle,
- PLPC_MESSAGE Message,
- ULONG Index,
- PVOID Buffer,
- ULONG BufferLength,
- PULONG Returnlength)
-{
- UNIMPLEMENTED;
-}
-
-NTSTATUS STDCALL NtWriteRequestData (HANDLE PortHandle,
- PLPC_MESSAGE Message,
- ULONG Index,
- PVOID Buffer,
- ULONG BufferLength,
- PULONG ReturnLength)
-{
- UNIMPLEMENTED;
-}
-/* $Id: process.c,v 1.43 2000/06/03 21:36:32 ekohl Exp $
+/* $Id: process.c,v 1.44 2000/06/04 17:27:39 ea Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
)
{
KIRQL OldIrql;
- PLIST_ENTRY CurrentEntry;
- PEPROCESS Current;
+ PLIST_ENTRY CurrentEntryP;
+ PEPROCESS CurrentP;
+ PLIST_ENTRY CurrentEntryT;
+ PETHREAD CurrentT;
ULONG RequiredSize = 0L;
BOOLEAN SizeOnly = FALSE;
- ULONG SpiSizeLast = 0L;
- ULONG SpiSizeCurrent = 0L;
+ ULONG SpiSize = 0L;
PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
+ PSYSTEM_PROCESS_INFORMATION pInfoPLast = NULL;
PSYSTEM_THREAD_INFO pInfoT = NULL;
* list is circular, the guard is false
* after the last process.
*/
- for ( CurrentEntry = PsProcessListHead.Flink;
- (CurrentEntry != & PsProcessListHead);
- CurrentEntry = CurrentEntry->Flink
+ for ( CurrentEntryP = PsProcessListHead.Flink;
+ (CurrentEntryP != & PsProcessListHead);
+ CurrentEntryP = CurrentEntryP->Flink
)
{
- /*
- * Get a reference to the
- * process object we are
- * handling.
- */
- Current = CONTAINING_RECORD(
- CurrentEntry,
- EPROCESS,
- Pcb.ProcessListEntry
- );
- /* FIXME: assert (NULL != Current) */
/*
* Compute how much space is
* occupied in the snapshot
* by adding this process info.
+ * (at least one thread).
*/
- SpiSizeCurrent =
- sizeof (SYSTEM_PROCESS_INFORMATION)
- + (
- (Current->ThreadCount - 1)
- * sizeof (SYSTEM_THREAD_INFORMATION)
- );
+ SpiSizeCurrent = sizeof (SYSTEM_PROCESS_INFORMATION);
RequiredSize += SpiSizeCurrent;
/*
* Do not write process data in the
SizeOnly = TRUE;
continue;
}
- /*
- * Compute the offset of the
- * SYSTEM_PROCESS_INFORMATION
- * descriptor in the snapshot
- * buffer for this process.
+ /*
+ * Get a reference to the
+ * process descriptor we are
+ * handling.
*/
- if (0L != SpiSizeLast)
- {
- (ULONG) pInfoP += SpiSizeLast;
- /* Save current process SpiSize */
- SpiSizeLast = SpiSizeCurrent;
- }
+ CurrentP = CONTAINING_RECORD(
+ CurrentEntryP,
+ EPROCESS,
+ Pcb.ProcessListEntry
+ );
/*
* Write process data in the buffer.
*/
- pInfoP->RelativeOffset = SpiSizeCurrent;
+ RtlZeroMemory (pInfoP, sizeof (SYSTEM_PROCESS_INFORMATION));
/* PROCESS */
- pInfoP->ThreadCount =
- pInfoP->ProcessId = Current->UniqueProcessId;
+ pInfoP->ThreadCount = 0L;
+ pInfoP->ProcessId = CurrentP->UniqueProcessId;
RtlInitUnicodeString (
& pInfoP->Name,
- Current->ImageFileName
+ CurrentP->ImageFileName
);
/* THREAD */
- for ( ThreadIndex = 0;
- (ThreadIndex < Current->ThreadCount);
- ThreadIndex ++
+ for ( pInfoT = & CurrentP->ThreadSysInfo [0],
+ CurrentEntryT = CurrentP->Pcb.ThreadListHead.Flink;
+
+ (CurrentEntryT != & CurrentP->Pcb.ThreadListHead);
+
+ pInfoT = & CurrentP->ThreadSysInfo [pInfoP->ThreadCount],
+ CurrentEntryT = CurrentEntryT->Flink
)
{
+ /*
+ * Recalculate the size of the
+ * information block.
+ */
+ if (0 < pInfoP->ThreadCount)
+ {
+ RequiredSize += sizeof (SYSTEM_THREAD_INFORMATION);
+ }
+ /*
+ * Do not write thread data in the
+ * buffer if it is too small.
+ */
+ if (TRUE == SizeOnly) continue;
+ /*
+ * Check if the buffer can contain
+ * the full snapshot.
+ */
+ if (Size < RequiredSize)
+ {
+ SizeOnly = TRUE;
+ continue;
+ }
+ /*
+ * Get a reference to the
+ * thread descriptor we are
+ * handling.
+ */
+ CurrentT = CONTAINING_RECORD(
+ CurrentEntryT,
+ KTHREAD,
+ Tcb.ThreadListEntry
+ );
+ /*
+ * Write thread data.
+ */
+ RtlZeroMemory (
+ pInfoT,
+ sizeof (SYSTEM_THREAD_INFORMATION)
+ );
+ pInfoT->KernelTime = CurrentT-> ; /* TIME */
+ pInfoT->UserTime = CurrentT-> ; /* TIME */
+ pInfoT->CreateTime = CurrentT-> ; /* TIME */
+ pInfoT->TickCount = CurrentT-> ; /* ULONG */
+ pInfoT->StartEIP = CurrentT-> ; /* ULONG */
+ pInfoT->ClientId = CurrentT-> ; /* CLIENT_ID */
+ pInfoT->ClientId = CurrentT-> ; /* CLIENT_ID */
+ pInfoT->DynamicPriority = CurrentT-> ; /* ULONG */
+ pInfoT->BasePriority = CurrentT-> ; /* ULONG */
+ pInfoT->nSwitches = CurrentT-> ; /* ULONG */
+ pInfoT->State = CurrentT-> ; /* DWORD */
+ pInfoT->WaitReason = CurrentT-> ; /* KWAIT_REASON */
+ /*
+ * Count the number of threads
+ * this process has.
+ */
+ ++ pInfoP->ThreadCount;
}
+ /*
+ * Save the size of information
+ * stored in the buffer for the
+ * current process.
+ */
+ pInfoP->RelativeOffset = SpiSize;
+ /*
+ * Save a reference to the last
+ * valid information block.
+ */
+ pInfoPLast = pInfoP;
+ /*
+ * Compute the offset of the
+ * SYSTEM_PROCESS_INFORMATION
+ * descriptor in the snapshot
+ * buffer for the next process.
+ */
+ (ULONG) pInfoP += SpiSize;
}
/*
* Unlock the process list.
*/
if (TRUE == SizeOnly)
{
- *pRequiredSize = RequiredSize;
+ if (NULL != RequiredSize)
+ {
+ *pRequiredSize = RequiredSize;
+ }
return STATUS_INFO_LENGTH_MISMATCH;
}
/*