Made and new ntoskrnl/lpc directory for the LPC subsystem.

Moved ntoskrnl/nt/port.c in ntoskrnl/lpc and split code into
smaller pieces. Little cleanup.

svn path=/trunk/; revision=1173
This commit is contained in:
Emanuele Aliberti 2000-06-04 17:27:39 +00:00
parent 6d5e353126
commit 9464b7005d
14 changed files with 1667 additions and 851 deletions

View file

@ -0,0 +1,112 @@
/* $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 */

View file

@ -0,0 +1,68 @@
/* $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 */

View file

@ -0,0 +1,303 @@
/* $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 */

View file

@ -0,0 +1,104 @@
/* $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 */

View file

@ -0,0 +1,87 @@
/* $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 */

127
reactos/ntoskrnl/lpc/port.c Normal file
View file

@ -0,0 +1,127 @@
/* $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 */

View file

@ -0,0 +1,81 @@
/* $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 */

View file

@ -0,0 +1,89 @@
/* $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 */

View file

@ -0,0 +1,50 @@
/* $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 */

View file

@ -0,0 +1,237 @@
/* $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 */

267
reactos/ntoskrnl/lpc/send.c Normal file
View file

@ -0,0 +1,267 @@
/* $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 */

View file

@ -1,4 +1,4 @@
# $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
#
@ -31,7 +31,6 @@ OBJECTS_NT = \
nt/ntsem.o \
nt/nttimer.o \
nt/plugplay.o \
nt/port.o \
nt/profile.o \
nt/zw.o
@ -233,6 +232,20 @@ OBJECTS_LDR = \
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
@ -344,6 +357,12 @@ $(OBJECTS_PATH)/ldr.o: $(OBJECTS_LDR)
-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 \
@ -385,6 +404,7 @@ OBJECTS = \
$(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 \
@ -403,13 +423,13 @@ OBJECTS = \
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
@ -541,3 +561,4 @@ WIN32_LEAN_AND_MEAN = yes
WARNINGS_ARE_ERRORS = yes
include ../rules.mak
# EOF

View file

@ -1,796 +0,0 @@
/* $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;
}

View file

@ -1,4 +1,4 @@
/* $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
@ -757,16 +757,18 @@ PiSnapshotProcessTable (
)
{
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;
@ -782,33 +784,18 @@ PiSnapshotProcessTable (
* 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
@ -824,36 +811,112 @@ PiSnapshotProcessTable (
SizeOnly = TRUE;
continue;
}
/*
* Get a reference to the
* process descriptor we are
* handling.
*/
CurrentP = CONTAINING_RECORD(
CurrentEntryP,
EPROCESS,
Pcb.ProcessListEntry
);
/*
* Write process data in the buffer.
*/
RtlZeroMemory (pInfoP, sizeof (SYSTEM_PROCESS_INFORMATION));
/* PROCESS */
pInfoP->ThreadCount = 0L;
pInfoP->ProcessId = CurrentP->UniqueProcessId;
RtlInitUnicodeString (
& pInfoP->Name,
CurrentP->ImageFileName
);
/* THREAD */
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 this process.
* buffer for the next process.
*/
if (0L != SpiSizeLast)
{
(ULONG) pInfoP += SpiSizeLast;
/* Save current process SpiSize */
SpiSizeLast = SpiSizeCurrent;
}
/*
* Write process data in the buffer.
*/
pInfoP->RelativeOffset = SpiSizeCurrent;
/* PROCESS */
pInfoP->ThreadCount =
pInfoP->ProcessId = Current->UniqueProcessId;
RtlInitUnicodeString (
& pInfoP->Name,
Current->ImageFileName
);
/* THREAD */
for ( ThreadIndex = 0;
(ThreadIndex < Current->ThreadCount);
ThreadIndex ++
)
{
}
(ULONG) pInfoP += SpiSize;
}
/*
* Unlock the process list.
@ -868,7 +931,10 @@ PiSnapshotProcessTable (
*/
if (TRUE == SizeOnly)
{
*pRequiredSize = RequiredSize;
if (NULL != RequiredSize)
{
*pRequiredSize = RequiredSize;
}
return STATUS_INFO_LENGTH_MISMATCH;
}
/*