mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +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>
|
#include <napi/lpc.h>
|
||||||
|
|
||||||
typedef
|
typedef struct _EPORT
|
||||||
struct _EPORT
|
|
||||||
{
|
{
|
||||||
KSPIN_LOCK Lock;
|
KSPIN_LOCK Lock;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
|
@ -21,30 +20,23 @@ struct _EPORT
|
||||||
|
|
||||||
ULONG MaxDataLength;
|
ULONG MaxDataLength;
|
||||||
ULONG MaxConnectInfoLength;
|
ULONG MaxConnectInfoLength;
|
||||||
|
|
||||||
} EPORT, * PEPORT;
|
} EPORT, * PEPORT;
|
||||||
|
|
||||||
|
|
||||||
typedef struct _EPORT_TERMINATION_REQUEST
|
typedef struct _EPORT_TERMINATION_REQUEST
|
||||||
{
|
{
|
||||||
LIST_ENTRY ThreadListEntry;
|
LIST_ENTRY ThreadListEntry;
|
||||||
PEPORT Port;
|
PEPORT Port;
|
||||||
|
|
||||||
} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
|
} EPORT_TERMINATION_REQUEST, *PEPORT_TERMINATION_REQUEST;
|
||||||
|
|
||||||
|
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
LpcRequestPort (PEPORT Port,
|
||||||
|
PLPC_MESSAGE LpcMessage);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
STDCALL
|
STDCALL
|
||||||
LpcRequestPort (
|
LpcSendTerminationPort (PEPORT Port,
|
||||||
PEPORT Port,
|
TIME CreationTime);
|
||||||
PLPC_MESSAGE LpcMessage
|
|
||||||
);
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
LpcSendTerminationPort (
|
|
||||||
PEPORT Port,
|
|
||||||
TIME CreationTime
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
/* Port Object Access */
|
/* Port Object Access */
|
||||||
|
@ -63,14 +55,12 @@ LpcSendTerminationPort (
|
||||||
#define EPORT_CONNECTED_SERVER (6)
|
#define EPORT_CONNECTED_SERVER (6)
|
||||||
#define EPORT_DISCONNECTED (7)
|
#define EPORT_DISCONNECTED (7)
|
||||||
|
|
||||||
typedef
|
typedef struct _QUEUEDMESSAGE
|
||||||
struct _QUEUEDMESSAGE
|
|
||||||
{
|
{
|
||||||
PEPORT Sender;
|
PEPORT Sender;
|
||||||
LIST_ENTRY QueueListEntry;
|
LIST_ENTRY QueueListEntry;
|
||||||
LPC_MESSAGE Message;
|
LPC_MESSAGE Message;
|
||||||
UCHAR MessageData [MAX_MESSAGE_DATA];
|
UCHAR MessageData [MAX_MESSAGE_DATA];
|
||||||
|
|
||||||
} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
|
} QUEUEDMESSAGE, *PQUEUEDMESSAGE;
|
||||||
|
|
||||||
/* Code in ntoskrnl/lpc/close.h */
|
/* Code in ntoskrnl/lpc/close.h */
|
||||||
|
|
|
@ -69,7 +69,7 @@ BOOLEAN KiTestAlert(VOID)
|
||||||
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
||||||
return(FALSE);
|
return(FALSE);
|
||||||
}
|
}
|
||||||
KeGetCurrentThread()->ApcState.UserApcPending = 1;
|
KeGetCurrentThread()->ApcState.UserApcPending++;
|
||||||
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
KeReleaseSpinLock(&PiApcLock, oldIrql);
|
||||||
return(TRUE);
|
return(TRUE);
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,6 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
||||||
DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame,
|
DPRINT("KiDeliverUserApc(TrapFrame %x/%x)\n", TrapFrame,
|
||||||
KeGetCurrentThread()->TrapFrame);
|
KeGetCurrentThread()->TrapFrame);
|
||||||
Thread = KeGetCurrentThread();
|
Thread = KeGetCurrentThread();
|
||||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check for thread termination
|
* Check for thread termination
|
||||||
|
@ -111,6 +110,8 @@ BOOLEAN KiDeliverUserApc(PKTRAP_FRAME TrapFrame)
|
||||||
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
|
KeReleaseSpinLock(&PiThreadListLock, oldlvl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||||
|
|
||||||
current_entry = Thread->ApcState.ApcListHead[1].Flink;
|
current_entry = Thread->ApcState.ApcListHead[1].Flink;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -225,13 +226,9 @@ VOID STDCALL KiDeliverApc(ULONG Unknown1,
|
||||||
KeCallKernelRoutineApc(Apc);
|
KeCallKernelRoutineApc(Apc);
|
||||||
|
|
||||||
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
KeAcquireSpinLock(&PiApcLock, &oldlvl);
|
||||||
DPRINT("Called kernel routine for APC\n");
|
|
||||||
// PsFreezeThread(Thread, NULL, FALSE, KernelMode);
|
|
||||||
DPRINT("Done frozen thread\n");
|
|
||||||
Thread->Tcb.ApcState.KernelApcInProgress--;
|
Thread->Tcb.ApcState.KernelApcInProgress--;
|
||||||
}
|
}
|
||||||
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
KeReleaseSpinLock(&PiApcLock, oldlvl);
|
||||||
// Thread->Tcb.WaitStatus = STATUS_KERNEL_APC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID STDCALL
|
VOID STDCALL
|
||||||
|
@ -285,6 +282,15 @@ KeInsertQueueApc (PKAPC Apc,
|
||||||
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
|
KeRemoveAllWaitsThread(CONTAINING_RECORD(TargetThread, ETHREAD, Tcb),
|
||||||
STATUS_KERNEL_APC);
|
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 &&
|
if (Apc->ApcMode == UserMode && TargetThread->Alertable == TRUE &&
|
||||||
TargetThread->WaitMode == UserMode)
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -190,24 +190,18 @@ KiInterruptDispatch (ULONG irq, PKIRQ_TRAPFRAME Trapframe)
|
||||||
HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
|
HalEndSystemInterrupt (DISPATCH_LEVEL, 0);
|
||||||
__asm__("sti\n\t");
|
__asm__("sti\n\t");
|
||||||
|
|
||||||
if (irq == 0)
|
|
||||||
{
|
|
||||||
KeExpireTimers();
|
|
||||||
}
|
|
||||||
if (KeGetCurrentThread() != NULL)
|
if (KeGetCurrentThread() != NULL)
|
||||||
{
|
{
|
||||||
KeGetCurrentThread()->LastEip = Trapframe->Eip;
|
KeGetCurrentThread()->LastEip = Trapframe->Eip;
|
||||||
}
|
}
|
||||||
KiDispatchInterrupt();
|
KiDispatchInterrupt();
|
||||||
PsDispatchThread(THREAD_STATE_RUNNABLE);
|
if (irq == 0)
|
||||||
}
|
{
|
||||||
else
|
PsDispatchThread(THREAD_STATE_RUNNABLE);
|
||||||
{
|
}
|
||||||
// DbgPrint("$");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HalEndSystemInterrupt (old_level, 0);
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -44,12 +44,14 @@ VOID KiSystemCallHook(ULONG Nr, ...)
|
||||||
|
|
||||||
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
ULONG KiAfterSystemCallHook(ULONG NtStatus, PKTRAP_FRAME TrapFrame)
|
||||||
{
|
{
|
||||||
|
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||||
if (KeGetCurrentThread()->ApcState.UserApcPending == 0 ||
|
if (KeGetCurrentThread()->ApcState.UserApcPending == 0 ||
|
||||||
TrapFrame->Cs == KERNEL_CS)
|
TrapFrame->Cs == KERNEL_CS)
|
||||||
{
|
{
|
||||||
return(NtStatus);
|
return(NtStatus);
|
||||||
}
|
}
|
||||||
KiDeliverUserApc(TrapFrame);
|
KiDeliverUserApc(TrapFrame);
|
||||||
|
assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
|
||||||
return(NtStatus);
|
return(NtStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -422,37 +422,36 @@ NTSTATUS STDCALL KeWaitForSingleObject (PVOID Object,
|
||||||
return(STATUS_WAIT_0);
|
return(STATUS_WAIT_0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CurrentThread->WaitStatus = STATUS_UNSUCCESSFUL;
|
||||||
/* Append wait block to the KTHREAD wait block list */
|
/* 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].Object = Object;
|
||||||
CurrentThread->WaitBlock[0].Thread = CurrentThread;
|
CurrentThread->WaitBlock[0].Thread = CurrentThread;
|
||||||
CurrentThread->WaitBlock[0].WaitKey = 0;
|
CurrentThread->WaitBlock[0].WaitKey = 0;
|
||||||
CurrentThread->WaitBlock[0].WaitType = WaitAny;
|
CurrentThread->WaitBlock[0].WaitType = WaitAny;
|
||||||
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
CurrentThread->WaitBlock[0].NextWaitBlock = NULL;
|
||||||
DPRINT("hdr->WaitListHead.Flink %x hdr->WaitListHead.Blink %x CurrentThread->WaitBlock[0].WaitListEntry = %x\n",
|
InsertTailList(&hdr->WaitListHead,
|
||||||
hdr->WaitListHead.Flink,hdr->WaitListHead.Blink, CurrentThread->WaitBlock[0].WaitListEntry );
|
&CurrentThread->WaitBlock[0].WaitListEntry);
|
||||||
InsertTailList(&hdr->WaitListHead, &CurrentThread->WaitBlock[0].WaitListEntry);
|
|
||||||
KeReleaseDispatcherDatabaseLock(FALSE);
|
KeReleaseDispatcherDatabaseLock(FALSE);
|
||||||
DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql());
|
DPRINT("Waiting for %x with irql %d\n", Object, KeGetCurrentIrql());
|
||||||
|
Status = STATUS_SUCCESS;
|
||||||
PsFreezeThread(PsGetCurrentThread(),
|
PsFreezeThread(PsGetCurrentThread(),
|
||||||
&Status,
|
&Status,
|
||||||
(UCHAR)Alertable,
|
(UCHAR)Alertable,
|
||||||
WaitMode);
|
WaitMode);
|
||||||
DPRINT("Woke from wait\n");
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DPRINT1("Woke from wait with status %x\n", Status);
|
||||||
|
}
|
||||||
} while (Status == STATUS_KERNEL_APC);
|
} while (Status == STATUS_KERNEL_APC);
|
||||||
|
|
||||||
if (Timeout != NULL)
|
if (Timeout != NULL)
|
||||||
{
|
{
|
||||||
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
KeCancelTimer(&KeGetCurrentThread()->Timer);
|
||||||
}
|
}
|
||||||
if (Status == STATUS_USER_APC)
|
|
||||||
{
|
|
||||||
KiTestAlert();
|
|
||||||
}
|
|
||||||
|
|
||||||
DPRINT("Returning from KeWaitForSingleObject()\n");
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -26,40 +26,32 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
EXPORTED
|
EXPORTED NTSTATUS STDCALL
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
NtCompleteConnectPort (HANDLE PortHandle)
|
NtCompleteConnectPort (HANDLE PortHandle)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PEPORT OurPort;
|
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);
|
OurPort->State = EPORT_CONNECTED_SERVER;
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (
|
ObDereferenceObject (OurPort);
|
||||||
PortHandle,
|
|
||||||
PORT_ALL_ACCESS,
|
return (STATUS_SUCCESS);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -41,155 +41,120 @@
|
||||||
* RETURN VALUE
|
* RETURN VALUE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
NtConnectPort (PHANDLE ConnectedPort,
|
||||||
NtConnectPort (
|
PUNICODE_STRING PortName,
|
||||||
PHANDLE ConnectedPort,
|
PSECURITY_QUALITY_OF_SERVICE Qos,
|
||||||
PUNICODE_STRING PortName,
|
PLPC_SECTION_WRITE WriteMap,
|
||||||
PSECURITY_QUALITY_OF_SERVICE Qos,
|
PLPC_SECTION_READ ReadMap,
|
||||||
PLPC_SECTION_WRITE WriteMap,
|
PULONG MaxMessageSize,
|
||||||
PLPC_SECTION_READ ReadMap,
|
PVOID ConnectInfo,
|
||||||
PULONG MaxMessageSize,
|
PULONG UserConnectInfoLength)
|
||||||
PVOID ConnectInfo,
|
|
||||||
PULONG UserConnectInfoLength
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PEPORT NamedPort;
|
PEPORT NamedPort;
|
||||||
PEPORT OurPort;
|
PEPORT OurPort;
|
||||||
HANDLE OurPortHandle;
|
HANDLE OurPortHandle;
|
||||||
PLPC_MESSAGE Request;
|
PLPC_MESSAGE Request;
|
||||||
PQUEUEDMESSAGE Reply;
|
PQUEUEDMESSAGE Reply;
|
||||||
ULONG ConnectInfoLength;
|
ULONG ConnectInfoLength;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("PortName %x\n", PortName);
|
DPRINT("PortName %x\n", PortName);
|
||||||
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
|
DPRINT("NtConnectPort(PortName %S)\n", PortName->Buffer);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy in user parameters
|
* Copy in user parameters
|
||||||
*/
|
*/
|
||||||
memcpy (
|
memcpy (&ConnectInfoLength, UserConnectInfoLength,
|
||||||
& ConnectInfoLength,
|
sizeof (*UserConnectInfoLength));
|
||||||
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 (
|
* Get access to the port
|
||||||
& OurPort->Lock,
|
*/
|
||||||
& oldIrql
|
Status = ObReferenceObjectByName (PortName,
|
||||||
);
|
0,
|
||||||
Reply = EiDequeueMessagePort (OurPort);
|
NULL,
|
||||||
KeReleaseSpinLock (
|
PORT_ALL_ACCESS, /* DesiredAccess */
|
||||||
& OurPort->Lock,
|
ExPortType,
|
||||||
oldIrql
|
UserMode,
|
||||||
);
|
NULL,
|
||||||
memcpy (
|
(PVOID*)&NamedPort);
|
||||||
ConnectInfo,
|
if (!NT_SUCCESS(Status))
|
||||||
Reply->MessageData,
|
{
|
||||||
Reply->Message.DataSize
|
DPRINT("Failed to reference named port (status %x)\n", Status);
|
||||||
);
|
return (Status);
|
||||||
*UserConnectInfoLength = Reply->Message.DataSize;
|
}
|
||||||
|
/*
|
||||||
|
* 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)
|
Request->DataSize = ConnectInfoLength;
|
||||||
{
|
Request->MessageSize = sizeof(LPC_MESSAGE) + ConnectInfoLength;
|
||||||
ObDereferenceObject (NamedPort);
|
Request->SharedSectionSize = 0;
|
||||||
ObDereferenceObject (OurPort);
|
if ((ConnectInfo != NULL) && (ConnectInfoLength > 0))
|
||||||
ZwClose (OurPortHandle);
|
{
|
||||||
ExFreePool (Request);
|
memcpy ((PVOID) (Request + 1), ConnectInfo, ConnectInfoLength);
|
||||||
ExFreePool (Reply);
|
}
|
||||||
return (STATUS_UNSUCCESSFUL);
|
/*
|
||||||
}
|
* 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;
|
DPRINT("Waiting for connection completion\n");
|
||||||
*ConnectedPort = OurPortHandle;
|
|
||||||
ExFreePool (Reply);
|
/*
|
||||||
ExFreePool (Request);
|
* Wait for them to accept our connection
|
||||||
|
*/
|
||||||
DPRINT("Exited successfully\n");
|
KeWaitForSingleObject (&OurPort->Event,
|
||||||
|
UserRequest,
|
||||||
return (STATUS_SUCCESS);
|
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
|
* RETURN VALUE
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
EXPORTED
|
EXPORTED NTSTATUS STDCALL
|
||||||
NTSTATUS
|
NtAcceptConnectPort (PHANDLE ServerPortHandle,
|
||||||
STDCALL
|
HANDLE NamedPortHandle,
|
||||||
NtAcceptConnectPort (
|
PLPC_MESSAGE LpcMessage,
|
||||||
PHANDLE ServerPortHandle,
|
BOOLEAN AcceptIt,
|
||||||
HANDLE NamedPortHandle,
|
PLPC_SECTION_WRITE WriteMap,
|
||||||
PLPC_MESSAGE LpcMessage,
|
PLPC_SECTION_READ ReadMap)
|
||||||
BOOLEAN AcceptIt,
|
|
||||||
PLPC_SECTION_WRITE WriteMap,
|
|
||||||
PLPC_SECTION_READ ReadMap
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PEPORT NamedPort;
|
PEPORT NamedPort;
|
||||||
PEPORT OurPort = NULL;
|
PEPORT OurPort = NULL;
|
||||||
PQUEUEDMESSAGE ConnectionRequest;
|
PQUEUEDMESSAGE ConnectionRequest;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
Status = ObReferenceObjectByHandle (
|
Status = ObReferenceObjectByHandle (NamedPortHandle,
|
||||||
NamedPortHandle,
|
PORT_ALL_ACCESS,
|
||||||
PORT_ALL_ACCESS,
|
ExPortType,
|
||||||
ExPortType,
|
UserMode,
|
||||||
UserMode,
|
(PVOID*)&NamedPort,
|
||||||
(PVOID *) & NamedPort,
|
NULL);
|
||||||
NULL
|
if (!NT_SUCCESS(Status))
|
||||||
);
|
{
|
||||||
if (!NT_SUCCESS(Status))
|
return (Status);
|
||||||
{
|
}
|
||||||
return (Status);
|
/*
|
||||||
}
|
* Create a port object for our side of the connection
|
||||||
/*
|
*/
|
||||||
* Create a port object for our side of the connection
|
if (AcceptIt == 1)
|
||||||
*/
|
{
|
||||||
if (AcceptIt == 1)
|
OurPort = ObCreateObject (ServerPortHandle,
|
||||||
{
|
|
||||||
OurPort = ObCreateObject (
|
|
||||||
ServerPortHandle,
|
|
||||||
PORT_ALL_ACCESS,
|
PORT_ALL_ACCESS,
|
||||||
NULL,
|
NULL,
|
||||||
ExPortType
|
ExPortType);
|
||||||
);
|
NiInitializePort(OurPort);
|
||||||
NiInitializePort(OurPort);
|
}
|
||||||
}
|
/*
|
||||||
/*
|
* Dequeue the connection request
|
||||||
* Dequeue the connection request
|
*/
|
||||||
*/
|
KeAcquireSpinLock (&NamedPort->Lock, & oldIrql);
|
||||||
KeAcquireSpinLock (& NamedPort->Lock, & oldIrql);
|
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
|
||||||
ConnectionRequest = EiDequeueConnectMessagePort (NamedPort);
|
KeReleaseSpinLock (&NamedPort->Lock, oldIrql);
|
||||||
KeReleaseSpinLock (& NamedPort->Lock, oldIrql);
|
|
||||||
|
if (AcceptIt != 1)
|
||||||
if (AcceptIt != 1)
|
{
|
||||||
{
|
EiReplyOrRequestPort (ConnectionRequest->Sender,
|
||||||
EiReplyOrRequestPort (
|
LpcMessage,
|
||||||
ConnectionRequest->Sender,
|
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,
|
LpcMessage,
|
||||||
LPC_CONNECTION_REFUSED,
|
LPC_REPLY,
|
||||||
NamedPort
|
OurPort);
|
||||||
);
|
ExFreePool (ConnectionRequest);
|
||||||
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 (OurPort);
|
||||||
ObDereferenceObject (NamedPort);
|
ObDereferenceObject (NamedPort);
|
||||||
|
|
||||||
return (STATUS_SUCCESS);
|
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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -42,6 +42,11 @@ EiReplyOrRequestPort (IN PEPORT Port,
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
PQUEUEDMESSAGE MessageReply;
|
PQUEUEDMESSAGE MessageReply;
|
||||||
|
|
||||||
|
if (Port == NULL)
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
|
||||||
MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
|
MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE));
|
||||||
MessageReply->Sender = Sender;
|
MessageReply->Sender = Sender;
|
||||||
|
|
||||||
|
@ -142,10 +147,19 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("NtReplyWaitReceivePort() = %x\n", Status);
|
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||||
return(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
|
* Send the reply
|
||||||
*/
|
*/
|
||||||
|
@ -160,6 +174,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
ObDereferenceObject(Port);
|
ObDereferenceObject(Port);
|
||||||
|
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,6 +191,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
||||||
NULL);
|
NULL);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
|
DPRINT1("NtReplyWaitReceivePort() = %x\n", Status);
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +202,7 @@ NtReplyWaitReceivePort (HANDLE PortHandle,
|
||||||
Request = EiDequeueMessagePort(Port);
|
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
|
* taken in which another thread may dequeue the same request so
|
||||||
* we may need to loop.
|
* 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
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -225,7 +225,11 @@ ULONG PsUnfreezeThread(PETHREAD Thread, PNTSTATUS WaitStatus)
|
||||||
|
|
||||||
if (WaitStatus != NULL)
|
if (WaitStatus != NULL)
|
||||||
{
|
{
|
||||||
Thread->Tcb.WaitStatus = *WaitStatus;
|
if (!NT_SUCCESS((*WaitStatus)))
|
||||||
|
{
|
||||||
|
KeBugCheck(0);
|
||||||
|
}
|
||||||
|
Thread->Tcb.WaitStatus = *WaitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (r <= 0)
|
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
|
* reactos/subsys/csrss/api/wapi.c
|
||||||
*
|
*
|
||||||
|
@ -63,12 +63,14 @@ static void Thread_Api2(HANDLE ServerPort)
|
||||||
0,
|
0,
|
||||||
&Reply->Header,
|
&Reply->Header,
|
||||||
&LpcRequest.Header);
|
&LpcRequest.Header);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status) &&
|
||||||
|
Status != STATUS_PORT_DISCONNECTED)
|
||||||
{
|
{
|
||||||
DisplayString(L"CSR: NtReplyWaitReceivePort failed\n");
|
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 );
|
CsrFreeProcessData( LpcRequest.Header.Cid.UniqueProcess );
|
||||||
NtClose(ServerPort);
|
NtClose(ServerPort);
|
||||||
|
|
Loading…
Reference in a new issue