mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
Fixes for problems with NtReplyWaitReceive and KeWaitForSingleObject
svn path=/trunk/; revision=1540
This commit is contained in:
parent
3116ca9df2
commit
a8660c1f02
10 changed files with 268 additions and 312 deletions
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include <napi/lpc.h>
|
||||
|
||||
typedef
|
||||
struct _EPORT
|
||||
typedef struct _EPORT
|
||||
{
|
||||
KSPIN_LOCK Lock;
|
||||
KEVENT Event;
|
||||
|
@ -21,30 +20,23 @@ struct _EPORT
|
|||
|
||||
ULONG MaxDataLength;
|
||||
ULONG MaxConnectInfoLength;
|
||||
|
||||
} EPORT, * PEPORT;
|
||||
|
||||
|
||||
typedef struct _EPORT_TERMINATION_REQUEST
|
||||
{
|
||||
LIST_ENTRY ThreadListEntry;
|
||||
PEPORT Port;
|
||||
|
||||
PEPORT Port;
|
||||
} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
LpcRequestPort (PEPORT Port,
|
||||
PLPC_MESSAGE LpcMessage);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
LpcRequestPort (
|
||||
PEPORT Port,
|
||||
PLPC_MESSAGE LpcMessage
|
||||
);
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
LpcSendTerminationPort (
|
||||
PEPORT Port,
|
||||
TIME CreationTime
|
||||
);
|
||||
LpcSendTerminationPort (PEPORT Port,
|
||||
TIME CreationTime);
|
||||
|
||||
|
||||
/* Port Object Access */
|
||||
|
@ -63,14 +55,12 @@ LpcSendTerminationPort (
|
|||
#define EPORT_CONNECTED_SERVER (6)
|
||||
#define EPORT_DISCONNECTED (7)
|
||||
|
||||
typedef
|
||||
struct _QUEUEDMESSAGE
|
||||
typedef struct _QUEUEDMESSAGE
|
||||
{
|
||||
PEPORT Sender;
|
||||
LIST_ENTRY QueueListEntry;
|
||||
LPC_MESSAGE Message;
|
||||
UCHAR MessageData [MAX_MESSAGE_DATA];
|
||||
|
||||
} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
|
||||
|
||||
/* Code in ntoskrnl/lpc/close.h */
|
||||
|
|
|
@ -69,7 +69,7 @@ BOOLEAN KiTestAlert(VOID)
|
|||
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
||||
return(FALSE);
|
||||
}
|
||||
KeGetCurrentThread()->ApcState.UserApcPending = 1;
|
||||
KeGetCurrentThread()->ApcState.UserApcPending++;
|
||||
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
||||
return(TRUE);
|
||||
}
|
||||
|
@ -94,7 +94,6 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
|||
DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame,
|
||||
KeGetCurrentThread()->TrapFrame);
|
||||
Thread = KeGetCurrentThread();
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
|
||||
/*
|
||||
* Check for thread termination
|
||||
|
@ -111,6 +110,8 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
|||
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
|
||||
}
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
|
||||
current_entry = Thread->ApcState.ApcListHead[1].Flink;
|
||||
|
||||
/*
|
||||
|
@ -225,13 +226,9 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
|
|||
KeCallKernelRoutineApc(Apc);
|
||||
|
||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||
DPRINT("Called kernel routine for APC\n");
|
||||
// PsFreezeThread(Thread, NULL, FALSE, KernelMode);
|
||||
DPRINT("Done frozen thread\n");
|
||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||
}
|
||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||
// Thread->Tcb.WaitStatus = STATUS_KERNEL_APC;
|
||||
}
|
||||
|
||||
VOID STDCALL
|
||||
|
@ -285,6 +282,15 @@ KeInsertQueueApc (PKAPC Apc,
|
|||
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
|
||||
STATUS_KERNEL_APC);
|
||||
}
|
||||
|
||||
/*
|
||||
* For user mode APCs if the thread is already waiting then we wait it
|
||||
* up and increment UserApcPending so it will deliver the APC on exit
|
||||
* from kernel mode. If the thread isn't waiting then before it
|
||||
* enters an alertable, user mode wait then it will check for
|
||||
* user mode APCs and if there are any pending then return immediately
|
||||
* and they will be delivered on exit from kernel mode
|
||||
*/
|
||||
if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE &&
|
||||
TargetThread->WaitMode == UserMode)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: irq.c,v 1.3 2000/12/10 23:42:00 dwelch Exp $
|
||||
/* $Id: irq.c,v 1.4 2001/01/18 15:00:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -190,24 +190,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
|
|||
HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
|
||||
__asm__("sti\n\t");
|
||||
|
||||
if (irq == 0)
|
||||
{
|
||||
KeExpireTimers();
|
||||
}
|
||||
if (KeGetCurrentThread() != NULL)
|
||||
{
|
||||
KeGetCurrentThread()->LastEip = Trapframe->Eip;
|
||||
}
|
||||
KiDispatchInterrupt();
|
||||
PsDispatchThread(THREAD_STATE_RUNNABLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// DbgPrint("$");
|
||||
if (irq == 0)
|
||||
{
|
||||
PsDispatchThread(THREAD_STATE_RUNNABLE);
|
||||
}
|
||||
}
|
||||
|
||||
HalEndSystemInterrupt (old_level, 0);
|
||||
// DbgPrint("}");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: usercall.c,v 1.16 2000/10/11 20:50:34 dwelch Exp $
|
||||
/* $Id: usercall.c,v 1.17 2001/01/18 15:00:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -44,12 +44,14 @@ VOID KiSystemCallHook(ULONG Nr, ...)
|
|||
|
||||
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
||||
{
|
||||
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
if (KeGetCurrentThread()->ApcState.UserApcPending == 0 ||
|
||||
TrapFrame->Cs == KERNEL_CS)
|
||||
{
|
||||
return(NtStatus);
|
||||
}
|
||||
KiDeliverUserApc(TrapFrame);
|
||||
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||
return(NtStatus);
|
||||
}
|
||||
|
||||
|
|
|
@ -422,37 +422,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
|||
return(STATUS_WAIT_0);
|
||||
}
|
||||
|
||||
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
||||
/* Append wait block to the KTHREAD wait block list */
|
||||
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
|
||||
|
||||
CurrentThread->WaitBlockList = &CurrentThread->WaitBlock[0];
|
||||
CurrentThread->WaitBlock[0].Object = Object;
|
||||
CurrentThread->WaitBlock[0].Thread = CurrentThread;
|
||||
CurrentThread->WaitBlock[0].WaitKey = 0;
|
||||
CurrentThread->WaitBlock[0].WaitType = WaitAny;
|
||||
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
||||
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x CurrentThread->WaitBlock[0].WaitListEntry = %x\n",
|
||||
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, CurrentThread->WaitBlock[0].WaitListEntry );
|
||||
InsertTailList(&hdr->WaitListHead, &CurrentThread->WaitBlock[0].WaitListEntry);
|
||||
InsertTailList(&hdr->WaitListHead,
|
||||
&CurrentThread->WaitBlock[0].WaitListEntry);
|
||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||
DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql());
|
||||
Status = STATUS_SUCCESS;
|
||||
PsFreezeThread(PsGetCurrentThread(),
|
||||
&Status,
|
||||
(UCHAR)Alertable,
|
||||
WaitMode);
|
||||
DPRINT("Woke from wait\n");
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Woke from wait with status %x\n", Status);
|
||||
}
|
||||
} while (Status == STATUS_KERNEL_APC);
|
||||
|
||||
if (Timeout != NULL)
|
||||
{
|
||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||
}
|
||||
if (Status == STATUS_USER_APC)
|
||||
{
|
||||
KiTestAlert();
|
||||
}
|
||||
|
||||
DPRINT("Returning from KeWaitForSingleObject()\n");
|
||||
return Status;
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: complete.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $
|
||||
/* $Id: complete.c,v 1.3 2001/01/18 15:00:08 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -26,40 +26,32 @@
|
|||
*
|
||||
*
|
||||
*/
|
||||
EXPORTED
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
EXPORTED NTSTATUS STDCALL
|
||||
NtCompleteConnectPort (HANDLE PortHandle)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
PEPORT OurPort;
|
||||
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);
|
||||
|
||||
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);
|
||||
OurPort->State = EPORT_CONNECTED_SERVER;
|
||||
|
||||
ObDereferenceObject (OurPort);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: connect.c,v 1.2 2000/10/22 16:36:51 ekohl Exp $
|
||||
/* $Id: connect.c,v 1.3 2001/01/18 15:00:09 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -41,155 +41,120 @@
|
|||
* 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 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;
|
||||
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("PortName %x\n", PortName);
|
||||
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
|
||||
|
||||
/*
|
||||
* Copy in user parameters
|
||||
*/
|
||||
memcpy (&ConnectInfoLength, UserConnectInfoLength,
|
||||
sizeof (*UserConnectInfoLength));
|
||||
|
||||
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;
|
||||
/*
|
||||
* 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));
|
||||
|
||||
if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED)
|
||||
{
|
||||
ObDereferenceObject (NamedPort);
|
||||
ObDereferenceObject (OurPort);
|
||||
ZwClose (OurPortHandle);
|
||||
ExFreePool (Request);
|
||||
ExFreePool (Reply);
|
||||
return (STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
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);
|
||||
|
||||
OurPort->State = EPORT_CONNECTED_CLIENT;
|
||||
*ConnectedPort = OurPortHandle;
|
||||
ExFreePool (Reply);
|
||||
ExFreePool (Request);
|
||||
|
||||
DPRINT("Exited successfully\n");
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,91 +175,77 @@ NtConnectPort (
|
|||
* RETURN VALUE
|
||||
*
|
||||
*/
|
||||
EXPORTED
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtAcceptConnectPort (
|
||||
PHANDLE ServerPortHandle,
|
||||
HANDLE NamedPortHandle,
|
||||
PLPC_MESSAGE LpcMessage,
|
||||
BOOLEAN AcceptIt,
|
||||
PLPC_SECTION_WRITE WriteMap,
|
||||
PLPC_SECTION_READ ReadMap
|
||||
)
|
||||
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,
|
||||
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,
|
||||
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_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);
|
||||
LPC_REPLY,
|
||||
OurPort);
|
||||
ExFreePool (ConnectionRequest);
|
||||
|
||||
ObDereferenceObject (OurPort);
|
||||
ObDereferenceObject (NamedPort);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
ObDereferenceObject (OurPort);
|
||||
ObDereferenceObject (NamedPort);
|
||||
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: reply.c,v 1.3 2000/12/28 03:38:07 dwelch Exp $
|
||||
/* $Id: reply.c,v 1.4 2001/01/18 15:00:09 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -42,6 +42,11 @@ EiReplyOrRequestPort (IN PEPORT Port,
|
|||
KIRQL oldIrql;
|
||||
PQUEUEDMESSAGE MessageReply;
|
||||
|
||||
if (Port == NULL)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
|
||||
MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
|
||||
MessageReply->Sender = Sender;
|
||||
|
||||
|
@ -142,10 +147,19 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
|||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("NtReplyWaitReceivePort() = %x\n", Status);
|
||||
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
if (Port->State != EPORT_CONNECTED_CLIENT &&
|
||||
Port->State != EPORT_CONNECTED_SERVER &&
|
||||
LpcReply != NULL)
|
||||
{
|
||||
DPRINT1("NtReplyWaitReceivePort() = %x (State was %x)\n",
|
||||
STATUS_PORT_DISCONNECTED, Port->State);
|
||||
return(STATUS_PORT_DISCONNECTED);
|
||||
}
|
||||
|
||||
/*
|
||||
* Send the reply
|
||||
*/
|
||||
|
@ -160,6 +174,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
|||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
ObDereferenceObject(Port);
|
||||
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
}
|
||||
|
@ -176,6 +191,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
|||
NULL);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -186,7 +202,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
|||
Request = EiDequeueMessagePort(Port);
|
||||
|
||||
/*
|
||||
* There is a race between the event being set and the port being
|
||||
* There is a race between the event being set and the port lock being
|
||||
* taken in which another thread may dequeue the same request so
|
||||
* we may need to loop.
|
||||
*/
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: thread.c,v 1.64 2000/12/26 05:32:44 dwelch Exp $
|
||||
/* $Id: thread.c,v 1.65 2001/01/18 15:00:09 dwelch Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -225,7 +225,11 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
|
|||
|
||||
if (WaitStatus != NULL)
|
||||
{
|
||||
Thread->Tcb.WaitStatus = *WaitStatus;
|
||||
if (!NT_SUCCESS((*WaitStatus)))
|
||||
{
|
||||
KeBugCheck(0);
|
||||
}
|
||||
Thread->Tcb.WaitStatus = *WaitStatus;
|
||||
}
|
||||
|
||||
if (r <= 0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: wapi.c,v 1.9 2000/07/11 04:09:25 phreak Exp $
|
||||
/* $Id: wapi.c,v 1.10 2001/01/18 15:00:09 dwelch Exp $
|
||||
*
|
||||
* reactos/subsys/csrss/api/wapi.c
|
||||
*
|
||||
|
@ -63,12 +63,14 @@ static void Thread_Api2(HANDLE ServerPort)
|
|||
0,
|
||||
&Reply->Header,
|
||||
&LpcRequest.Header);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if (!NT_SUCCESS(Status) &&
|
||||
Status != STATUS_PORT_DISCONNECTED)
|
||||
{
|
||||
DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
|
||||
}
|
||||
|
||||
if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED)
|
||||
if (LpcRequest.Header.MessageType == LPC_PORT_CLOSED ||
|
||||
Status == STATUS_PORT_DISCONNECTED)
|
||||
{
|
||||
CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess );
|
||||
NtClose(ServerPort);
|
||||
|
|
Loading…
Reference in a new issue