mirror of
https://github.com/reactos/reactos.git
synced 2025-05-07 18:56:48 +00:00
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:
parent
6d5e353126
commit
9464b7005d
14 changed files with 1667 additions and 851 deletions
112
reactos/ntoskrnl/lpc/close.c
Normal file
112
reactos/ntoskrnl/lpc/close.c
Normal 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 */
|
68
reactos/ntoskrnl/lpc/complete.c
Normal file
68
reactos/ntoskrnl/lpc/complete.c
Normal 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 */
|
303
reactos/ntoskrnl/lpc/connect.c
Normal file
303
reactos/ntoskrnl/lpc/connect.c
Normal 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 */
|
104
reactos/ntoskrnl/lpc/create.c
Normal file
104
reactos/ntoskrnl/lpc/create.c
Normal 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 */
|
87
reactos/ntoskrnl/lpc/listen.c
Normal file
87
reactos/ntoskrnl/lpc/listen.c
Normal 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
127
reactos/ntoskrnl/lpc/port.c
Normal 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 */
|
81
reactos/ntoskrnl/lpc/query.c
Normal file
81
reactos/ntoskrnl/lpc/query.c
Normal 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 */
|
89
reactos/ntoskrnl/lpc/queue.c
Normal file
89
reactos/ntoskrnl/lpc/queue.c
Normal 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 */
|
50
reactos/ntoskrnl/lpc/receive.c
Normal file
50
reactos/ntoskrnl/lpc/receive.c
Normal 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 */
|
237
reactos/ntoskrnl/lpc/reply.c
Normal file
237
reactos/ntoskrnl/lpc/reply.c
Normal 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
267
reactos/ntoskrnl/lpc/send.c
Normal 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 */
|
|
@ -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
|
# ReactOS Operating System
|
||||||
#
|
#
|
||||||
|
@ -31,7 +31,6 @@ OBJECTS_NT = \
|
||||||
nt/ntsem.o \
|
nt/ntsem.o \
|
||||||
nt/nttimer.o \
|
nt/nttimer.o \
|
||||||
nt/plugplay.o \
|
nt/plugplay.o \
|
||||||
nt/port.o \
|
|
||||||
nt/profile.o \
|
nt/profile.o \
|
||||||
nt/zw.o
|
nt/zw.o
|
||||||
|
|
||||||
|
@ -233,6 +232,20 @@ OBJECTS_LDR = \
|
||||||
ldr/sysdll.o \
|
ldr/sysdll.o \
|
||||||
ldr/userldr.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)
|
# Nation Language Support Library (Nls)
|
||||||
OBJECTS_NLS = nls/nls.o
|
OBJECTS_NLS = nls/nls.o
|
||||||
|
|
||||||
|
@ -344,6 +357,12 @@ $(OBJECTS_PATH)/ldr.o: $(OBJECTS_LDR)
|
||||||
-o $(OBJECTS_PATH)/ldr.o \
|
-o $(OBJECTS_PATH)/ldr.o \
|
||||||
$(OBJECTS_LDR)
|
$(OBJECTS_LDR)
|
||||||
|
|
||||||
|
$(OBJECTS_PATH)/lpc.o: $(OBJECTS_LPC)
|
||||||
|
$(LD) \
|
||||||
|
-r \
|
||||||
|
-o $(OBJECTS_PATH)/lpc.o \
|
||||||
|
$(OBJECTS_LPC)
|
||||||
|
|
||||||
$(OBJECTS_PATH)/nls.o: $(OBJECTS_NLS)
|
$(OBJECTS_PATH)/nls.o: $(OBJECTS_NLS)
|
||||||
$(LD) \
|
$(LD) \
|
||||||
-r \
|
-r \
|
||||||
|
@ -385,6 +404,7 @@ OBJECTS = \
|
||||||
$(OBJECTS_PATH)/cm.o \
|
$(OBJECTS_PATH)/cm.o \
|
||||||
$(OBJECTS_PATH)/dbg.o \
|
$(OBJECTS_PATH)/dbg.o \
|
||||||
$(OBJECTS_PATH)/ex.o \
|
$(OBJECTS_PATH)/ex.o \
|
||||||
|
$(OBJECTS_PATH)/lpc.o \
|
||||||
$(OBJECTS_PATH)/fs.o \
|
$(OBJECTS_PATH)/fs.o \
|
||||||
$(OBJECTS_PATH)/io.o \
|
$(OBJECTS_PATH)/io.o \
|
||||||
$(OBJECTS_PATH)/kd.o \
|
$(OBJECTS_PATH)/kd.o \
|
||||||
|
@ -403,13 +423,13 @@ OBJECTS = \
|
||||||
ifeq ($(DOSCLI),yes)
|
ifeq ($(DOSCLI),yes)
|
||||||
CLEAN_FILES = $(OBJECTS_PATH)\*.o cc\*.o cm\*.o dbg\*.o ex\*.o hal\x86\*.o io\*.o \
|
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\*.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 \
|
kd\*.o utils\export\export.exe $(TARGETNAME).o $(TARGETNAME).a junk.tmp \
|
||||||
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
|
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
|
||||||
else
|
else
|
||||||
CLEAN_FILES = $(OBJECTS_PATH)/*.o cc/*.o cm/*.o dbg/*.o ex/*.o hal/x86/*.o io/*.o \
|
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/*.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 \
|
kd/*.o utils/export/export $(TARGETNAME).o $(TARGETNAME).a junk.tmp \
|
||||||
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
|
base.tmp temp.exp $(TARGETNAME).exe $(TARGETNAME).sym $(TARGETNAME).coff
|
||||||
endif
|
endif
|
||||||
|
@ -541,3 +561,4 @@ WIN32_LEAN_AND_MEAN = yes
|
||||||
WARNINGS_ARE_ERRORS = yes
|
WARNINGS_ARE_ERRORS = yes
|
||||||
include ../rules.mak
|
include ../rules.mak
|
||||||
|
|
||||||
|
# EOF
|
||||||
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -757,16 +757,18 @@ PiSnapshotProcessTable (
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PLIST_ENTRY CurrentEntry;
|
PLIST_ENTRY CurrentEntryP;
|
||||||
PEPROCESS Current;
|
PEPROCESS CurrentP;
|
||||||
|
PLIST_ENTRY CurrentEntryT;
|
||||||
|
PETHREAD CurrentT;
|
||||||
|
|
||||||
ULONG RequiredSize = 0L;
|
ULONG RequiredSize = 0L;
|
||||||
BOOLEAN SizeOnly = FALSE;
|
BOOLEAN SizeOnly = FALSE;
|
||||||
|
|
||||||
ULONG SpiSizeLast = 0L;
|
ULONG SpiSize = 0L;
|
||||||
ULONG SpiSizeCurrent = 0L;
|
|
||||||
|
|
||||||
PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
|
PSYSTEM_PROCESS_INFORMATION pInfoP = (PSYSTEM_PROCESS_INFORMATION) SnapshotBuffer;
|
||||||
|
PSYSTEM_PROCESS_INFORMATION pInfoPLast = NULL;
|
||||||
PSYSTEM_THREAD_INFO pInfoT = NULL;
|
PSYSTEM_THREAD_INFO pInfoT = NULL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -782,33 +784,18 @@ PiSnapshotProcessTable (
|
||||||
* list is circular, the guard is false
|
* list is circular, the guard is false
|
||||||
* after the last process.
|
* after the last process.
|
||||||
*/
|
*/
|
||||||
for ( CurrentEntry = PsProcessListHead.Flink;
|
for ( CurrentEntryP = PsProcessListHead.Flink;
|
||||||
(CurrentEntry != & PsProcessListHead);
|
(CurrentEntryP != & PsProcessListHead);
|
||||||
CurrentEntry = CurrentEntry->Flink
|
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
|
* Compute how much space is
|
||||||
* occupied in the snapshot
|
* occupied in the snapshot
|
||||||
* by adding this process info.
|
* by adding this process info.
|
||||||
|
* (at least one thread).
|
||||||
*/
|
*/
|
||||||
SpiSizeCurrent =
|
SpiSizeCurrent = sizeof (SYSTEM_PROCESS_INFORMATION);
|
||||||
sizeof (SYSTEM_PROCESS_INFORMATION)
|
|
||||||
+ (
|
|
||||||
(Current->ThreadCount - 1)
|
|
||||||
* sizeof (SYSTEM_THREAD_INFORMATION)
|
|
||||||
);
|
|
||||||
RequiredSize += SpiSizeCurrent;
|
RequiredSize += SpiSizeCurrent;
|
||||||
/*
|
/*
|
||||||
* Do not write process data in the
|
* Do not write process data in the
|
||||||
|
@ -824,36 +811,112 @@ PiSnapshotProcessTable (
|
||||||
SizeOnly = TRUE;
|
SizeOnly = TRUE;
|
||||||
continue;
|
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
|
* Compute the offset of the
|
||||||
* SYSTEM_PROCESS_INFORMATION
|
* SYSTEM_PROCESS_INFORMATION
|
||||||
* descriptor in the snapshot
|
* descriptor in the snapshot
|
||||||
* buffer for this process.
|
* buffer for the next process.
|
||||||
*/
|
*/
|
||||||
if (0L != SpiSizeLast)
|
(ULONG) pInfoP += SpiSize;
|
||||||
{
|
|
||||||
(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 ++
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Unlock the process list.
|
* Unlock the process list.
|
||||||
|
@ -868,7 +931,10 @@ PiSnapshotProcessTable (
|
||||||
*/
|
*/
|
||||||
if (TRUE == SizeOnly)
|
if (TRUE == SizeOnly)
|
||||||
{
|
{
|
||||||
*pRequiredSize = RequiredSize;
|
if (NULL != RequiredSize)
|
||||||
|
{
|
||||||
|
*pRequiredSize = RequiredSize;
|
||||||
|
}
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue