mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
754 lines
21 KiB
754 lines
21 KiB
/*++
|
|
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
apireqst.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the Server Request thread procedure
|
|
|
|
Author:
|
|
|
|
Steve Wood (stevewo) 20-Sep-1989
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#define INCL_OS2V20_ERRORS
|
|
#include "os2srv.h"
|
|
#define NTOS2_ONLY
|
|
#include "sesport.h"
|
|
|
|
POS2_API_ROUTINE Os2ServerApiDispatch[ Os2MaxApiNumber+1 ] = {
|
|
Os2InternalNullApiCall,
|
|
Os2InternalAlertMuxWaiter,
|
|
Os2InternalCopyHandleTable,
|
|
Os2InternalDeviceShare,
|
|
Os2InternalTerminateThread,
|
|
Os2InternalTerminateProcess,
|
|
Os2InternalQueryVirtualMemory,
|
|
Os2InternalMarkSharedMemAsHuge,
|
|
Os2InternalReallocSharedHuge,
|
|
Os2DosCreateThread,
|
|
Os2DosExit,
|
|
Os2DosWaitChild,
|
|
Os2DosWaitThread,
|
|
Os2DosExecPgm,
|
|
Os2DosKillProcess,
|
|
Os2DosSetPriority,
|
|
Os2DosFreeMem,
|
|
Os2DosGiveSharedMem,
|
|
Os2DosGetSharedMem,
|
|
Os2DosGetNamedSharedMem,
|
|
Os2DosAllocSharedMem,
|
|
Os2DosCreateEventSem,
|
|
Os2DosOpenEventSem,
|
|
Os2DosCloseEventSem,
|
|
Os2DosCreateMutexSem,
|
|
Os2DosOpenMutexSem,
|
|
Os2DosCloseMutexSem,
|
|
Os2DosCreateMuxWaitSem,
|
|
Os2DosOpenMuxWaitSem,
|
|
Os2DosCloseMuxWaitSem,
|
|
Os2DosWaitMuxWaitSem,
|
|
Os2DosAddMuxWaitSem,
|
|
Os2DosDeleteMuxWaitSem,
|
|
Os2DosQueryMuxWaitSem,
|
|
Os2DosStartSession,
|
|
Os2DosSelectSession,
|
|
Os2DosSetSession,
|
|
Os2DosStopSession,
|
|
Os2DosSmSetTitle,
|
|
Os2DosCreateQueue,
|
|
Os2DosOpenQueue,
|
|
Os2DosCloseQueue,
|
|
Os2DosPurgeQueue,
|
|
Os2DosQueryQueue,
|
|
Os2DosPeekQueue,
|
|
Os2DosReadQueue,
|
|
Os2DosWriteQueue,
|
|
Os2DosEnterMustComplete,
|
|
Os2DosExitMustComplete,
|
|
Os2DosSetSignalExceptionFocus,
|
|
Os2DosSendSignalException,
|
|
Os2DosAcknowledgeSignalException,
|
|
Os2DosDispatch16Signal,
|
|
Os2DosGetPriority,
|
|
Os2DosGetPPID,
|
|
Os2DosError,
|
|
Os2DosRegisterCtrlHandler,
|
|
Os2DosGetCtrlPortForSessionID,
|
|
Os2DosExitGP,
|
|
Os2DosCloseHandle,
|
|
Os2ConfigSysCreator,
|
|
Os2Netbios2Request,
|
|
Os2DosReallocSharedMem,
|
|
Os2DosGetSeg,
|
|
Os2DosGiveSeg,
|
|
Os2DosGetShrSeg,
|
|
Os2DosPTrace,
|
|
LDRNewExe,
|
|
LDRDosLoadModule,
|
|
LDRDosFreeModule,
|
|
LDRDosGetModName,
|
|
LDRDosGetModHandle,
|
|
LDRDosGetProcAddr,
|
|
LDRDosQAppType,
|
|
LDRDosGetResource,
|
|
LDRDosFreeResource,
|
|
#if PMNT
|
|
LDRIdentifyCodeSelector,
|
|
PMSetPMshellFlag,
|
|
#endif
|
|
#if PMNT
|
|
LDRDumpSegments,
|
|
#endif
|
|
NULL
|
|
};
|
|
|
|
#if DBG
|
|
PSZ Os2ServerApiName[ Os2MaxApiNumber+1 ] = {
|
|
"NullApiCall",
|
|
"AlertMuxWaiter",
|
|
"CopyHandleTable",
|
|
"InternalDeviceShare",
|
|
"InternalTerminateThread",
|
|
"InternalTerminateProcess",
|
|
"InternalQueryVirtualMemory",
|
|
"InternalMarkSharedMemAsHuge",
|
|
"Os2InternaleReallocSharedHuge",
|
|
"DosCreateThread",
|
|
"DosExit",
|
|
"DosWaitChild",
|
|
"DosWaitThread",
|
|
"DosExecPgm",
|
|
"DosKillProcess",
|
|
"DosSetPriority",
|
|
"DosFreeMem",
|
|
"DosGiveSharedMem",
|
|
"DosGetSharedMem",
|
|
"DosGetNamedSharedMem",
|
|
"DosAllocSharedMem",
|
|
"DosCreateEventSem",
|
|
"DosOpenEventSem",
|
|
"DosCloseEventSem",
|
|
"DosCreateMutexSem",
|
|
"DosOpenMutexSem",
|
|
"DosCloseMutexSem",
|
|
"DosCreateMuxWaitSem",
|
|
"DosOpenMuxWaitSem",
|
|
"DosCloseMuxWaitSem",
|
|
"DosWaitMuxWaitSem",
|
|
"DosAddMuxWaitSem",
|
|
"DosDeleteMuxWaitSem",
|
|
"DosQueryMuxWaitSem",
|
|
"DosStartSession",
|
|
"DosSelectSession",
|
|
"DosSetSession",
|
|
"DosStopSession",
|
|
"DosSmSetTitle",
|
|
"DosCreateQueue",
|
|
"DosOpenQueue",
|
|
"DosCloseQueue",
|
|
"DosPurgeQueue",
|
|
"DosQueryQueue",
|
|
"DosPeekQueue",
|
|
"DosReadQueue",
|
|
"DosWriteQueue",
|
|
"DosEnterMustComplete",
|
|
"DosExitMustComplete",
|
|
"DosSetSignalExceptionFocus",
|
|
"DosSendSignalException",
|
|
"DosAcknowledgeSignalException",
|
|
"Dispatch16Signal",
|
|
"DosGetPriority",
|
|
"DosGetPPID",
|
|
"DosError",
|
|
"DosRegisterCtrlHandler",
|
|
"DosGetCtrlPortForSessionID",
|
|
"DosExitGP",
|
|
"DosCloseHandle",
|
|
"ConfigSysCreator",
|
|
"Netbios2Request",
|
|
"DosReallocSseg",
|
|
"DosGetSeg",
|
|
"DosGiveSeg",
|
|
"Os2DosGetShrSeg",
|
|
"Os2DosPTrace",
|
|
"LDRNewExe",
|
|
"LDRLoadModule",
|
|
"LDRFreeModule",
|
|
"LDRGetModuleName",
|
|
"LDRGetModuleHandle",
|
|
"LDRGetProcAddr",
|
|
"LDRQAppType",
|
|
"LDRGetResource",
|
|
"LDRFreeResource",
|
|
#if PMNT
|
|
"LDRIdentifyCodeSelector",
|
|
"PMSetPMshellFlag",
|
|
#endif
|
|
#if PMNT && DBG
|
|
"LDRDumpSegments",
|
|
#endif
|
|
"Unknown Os2 Api Number"
|
|
};
|
|
#endif // DBG
|
|
|
|
|
|
NTSTATUS
|
|
Os2ApiRequestThread(
|
|
IN PVOID Parameter
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
POS2_THREAD Thread;
|
|
POS2_PROCESS Process;
|
|
UCHAR ReceiveMsgData [sizeof(OS2SESREQUESTMSG) + sizeof(OS2_API_MSG)];
|
|
OS2_API_MSG *pReceiveMsg = (POS2_API_MSG)ReceiveMsgData;
|
|
POS2_API_MSG ReplyMsg;
|
|
|
|
UNREFERENCED_PARAMETER(Parameter);
|
|
ReplyMsg = NULL;
|
|
|
|
//
|
|
// At init time - we sync with other server threads
|
|
//
|
|
Os2AcquireStructureLock();
|
|
while (TRUE)
|
|
{
|
|
|
|
WaitAgain:
|
|
//Process = NULL;
|
|
//
|
|
// Let other server threads get in after we are done with the request
|
|
//
|
|
Os2ReleaseStructureLock();
|
|
Status = NtReplyWaitReceivePort( Os2SessionPort,
|
|
NULL,
|
|
(PPORT_MESSAGE)ReplyMsg,
|
|
(PPORT_MESSAGE)pReceiveMsg
|
|
);
|
|
//
|
|
// Sync with any other server thread before we take care of request
|
|
//
|
|
Os2AcquireStructureLock();
|
|
|
|
if (Status != 0)
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SRV: NtReplyWaitReceivePort() returned Status %x\n", Status));
|
|
#endif
|
|
if (NT_SUCCESS( Status ))
|
|
{
|
|
continue; // Try again if alerted or a failure
|
|
}
|
|
else
|
|
{
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Check for connection request
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_CONNECTION_REQUEST )
|
|
{
|
|
Os2SessionHandleConnectionRequest( (POS2SESREQUESTMSG)pReceiveMsg );
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
//
|
|
// Check for debugger event
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_DEBUG_EVENT )
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SRV: LPC_DEBUG_EVENT received in API thread"));
|
|
ASSERT(FALSE);
|
|
#endif
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
//
|
|
// if this is an exception message, assert.
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_EXCEPTION )
|
|
{
|
|
#if DBG
|
|
KdPrint(("OS2SRV: LPC_EXCEPTION received in API thread"));
|
|
ASSERT(FALSE);
|
|
#endif
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
//
|
|
// Check for error event
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_ERROR_EVENT )
|
|
{
|
|
PHARDERROR_MSG m;
|
|
|
|
m = (PHARDERROR_MSG) pReceiveMsg;
|
|
Status = m->Status;
|
|
m->Response = (ULONG) ResponseReturnToCaller;
|
|
#if DBG
|
|
KdPrint(( "OS2SRV: LPC_ERROR_EVENT in API Thread - Status == %X\n", Status ));
|
|
#endif
|
|
ASSERT(FALSE);
|
|
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
//
|
|
// Check for a terminated process, port closed
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_PORT_CLOSED)
|
|
{
|
|
#if DBG
|
|
IF_OS2_DEBUG( MISC )
|
|
{
|
|
KdPrint(( "OS2SRV: LPC_PORT_CLOSED, pReceiveMsg == %X, App will be terminated\n", pReceiveMsg));
|
|
}
|
|
#endif
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
//
|
|
// Check for a terminated process, client died
|
|
//
|
|
if ( pReceiveMsg->h.u2.s2.Type == LPC_CLIENT_DIED)
|
|
{
|
|
#if DBG
|
|
KdPrint(( "OS2SRV: LPC_CLIENT_DIED in API Thread - Status == %X, pReceiveMsg == %X, \n", Status, pReceiveMsg));
|
|
#endif
|
|
ReplyMsg = NULL;
|
|
goto WaitAgain;
|
|
}
|
|
|
|
if(pReceiveMsg->PortType == 1)
|
|
{
|
|
HandleOs2ConRequest(
|
|
(PVOID)pReceiveMsg,
|
|
(PVOID *)&ReplyMsg
|
|
);
|
|
continue;
|
|
}
|
|
|
|
ASSERT(pReceiveMsg->PortType == 0);
|
|
|
|
if (pReceiveMsg->ApiNumber >= Os2MaxApiNumber)
|
|
{
|
|
#if DBG
|
|
KdPrint(( "OS2SRV: %lx is invalid ApiNumber\n",
|
|
pReceiveMsg->ApiNumber
|
|
));
|
|
#endif
|
|
pReceiveMsg->ApiNumber = Os2MaxApiNumber;
|
|
}
|
|
|
|
#if DBG
|
|
IF_OS2_DEBUG( LPC )
|
|
{
|
|
if (pReceiveMsg->ApiNumber != Os2ExitMustComplete &&
|
|
pReceiveMsg->ApiNumber != Os2EnterMustComplete)
|
|
{
|
|
KdPrint(( "OS2SRV: %s Api Request received from %lx.%lx\n",
|
|
Os2ServerApiName[ pReceiveMsg->ApiNumber ],
|
|
pReceiveMsg->h.ClientId.UniqueProcess,
|
|
pReceiveMsg->h.ClientId.UniqueThread
|
|
));
|
|
}
|
|
}
|
|
#endif // DBG
|
|
|
|
ReplyMsg = pReceiveMsg;
|
|
if (pReceiveMsg->ApiNumber < Os2MaxApiNumber)
|
|
{
|
|
Thread = Os2LocateThreadByClientId( NULL /*Process*/, &pReceiveMsg->h.ClientId );
|
|
if (!Thread)
|
|
{
|
|
switch (pReceiveMsg->ApiNumber) {
|
|
case Os2CreateThread :
|
|
// Thats right, the thread isn't known yet by the server
|
|
Process = Os2LocateProcessByClientId(&pReceiveMsg->h.ClientId);
|
|
break;
|
|
case Os2CloseHandle :
|
|
// This API may be called from the thread startup. It might
|
|
// be done while exit in progress too. In any case, close
|
|
// the handles.
|
|
Os2DosCloseHandle(NULL, pReceiveMsg);
|
|
ReplyMsg->ReturnedErrorValue = NO_ERROR;
|
|
goto failit;
|
|
case Os2Exit :
|
|
case Os2ExitGP :
|
|
case Oi2TerminateProcess :
|
|
#if DBG
|
|
IF_OS2_DEBUG( TASKING ) {
|
|
DbgPrint("OS2SRV: Api Request (exit) - illegal client\n");
|
|
}
|
|
#endif // DBG
|
|
ReplyMsg = NULL;
|
|
goto failit;
|
|
default:
|
|
#if DBG
|
|
IF_OS2_DEBUG( TASKING ) {
|
|
DbgPrint("OS2SRV: Api Request - illegal client\n");
|
|
}
|
|
#endif // DBG
|
|
ReplyMsg->ReturnedErrorValue = ERROR_INVALID_FUNCTION;
|
|
goto failit;
|
|
}
|
|
}
|
|
else
|
|
Process = Thread->Process;
|
|
|
|
ReplyMsg->ReturnedErrorValue = NO_ERROR;
|
|
|
|
if (Process->ExitStatus & OS2_EXIT_IN_PROGRESS)
|
|
{
|
|
//
|
|
// We started termination. Don't let new threads come in
|
|
//
|
|
if (pReceiveMsg->ApiNumber == Os2CreateThread) {
|
|
// Thread strcuture will not be allocated by the server, but
|
|
// the handle that was duplicated by the client must be closed.
|
|
NtClose(pReceiveMsg->u.DosCreateThread.ThreadHandle);
|
|
ReplyMsg->ReturnedErrorValue = ERROR_INVALID_FUNCTION;
|
|
#if DBG
|
|
IF_OD2_DEBUG( TASKING ) {
|
|
KdPrint(( "OS2SRV: in termination, don't allow new threads in\n"));
|
|
}
|
|
#endif // DBG
|
|
goto failit;
|
|
}
|
|
}
|
|
|
|
if (pReceiveMsg->CaptureBuffer != NULL)
|
|
{
|
|
if (!Os2CaptureArguments( Thread, pReceiveMsg ))
|
|
{
|
|
goto failit;
|
|
}
|
|
}
|
|
|
|
if ((*Os2ServerApiDispatch[ pReceiveMsg->ApiNumber ])( Thread, pReceiveMsg ))
|
|
{
|
|
//if (!Thread) {
|
|
//
|
|
// Attaching a Win32 Thread to OS/2, take ClientPort from Process
|
|
//
|
|
// Process = Os2LocateProcessByClientId(&(pReceiveMsg->h.ClientId));
|
|
//}
|
|
} else
|
|
{
|
|
ReplyMsg = NULL;
|
|
if ((pReceiveMsg->ApiNumber == Os2ExecPgm) ||
|
|
(pReceiveMsg->ApiNumber == Os2StartSession))
|
|
goto failit;
|
|
}
|
|
|
|
if (pReceiveMsg->CaptureBuffer != NULL)
|
|
{
|
|
Os2ReleaseCapturedArguments( pReceiveMsg );
|
|
}
|
|
failit:
|
|
;
|
|
} else
|
|
{
|
|
ReplyMsg->ReturnedErrorValue = ERROR_INVALID_FUNCTION;
|
|
}
|
|
#if DBG
|
|
IF_OS2_DEBUG( LPC )
|
|
{
|
|
if (ReplyMsg != NULL)
|
|
{
|
|
if (pReceiveMsg->ApiNumber != Os2ExitMustComplete &&
|
|
pReceiveMsg->ApiNumber != Os2EnterMustComplete)
|
|
{
|
|
KdPrint(( "OS2SRV: %s Api sending %lX error code reply to %lx.%lx\n",
|
|
Os2ServerApiName[ pReceiveMsg->ApiNumber ],
|
|
ReplyMsg->ReturnedErrorValue,
|
|
ReplyMsg->h.ClientId.UniqueProcess,
|
|
ReplyMsg->h.ClientId.UniqueThread
|
|
));
|
|
}
|
|
}
|
|
}
|
|
#endif // DBG
|
|
}
|
|
|
|
NtTerminateThread( NtCurrentThread(), Status );
|
|
return( Status );
|
|
}
|
|
|
|
|
|
BOOLEAN
|
|
Os2CaptureArguments(
|
|
IN POS2_THREAD t,
|
|
IN POS2_API_MSG m
|
|
)
|
|
{
|
|
POS2_CAPTURE_HEADER ClientCaptureBuffer;
|
|
POS2_CAPTURE_HEADER ServerCaptureBuffer;
|
|
PULONG PointerOffsets;
|
|
ULONG PointerDelta, Length, CountPointers, Pointer;
|
|
|
|
ClientCaptureBuffer = m->CaptureBuffer;
|
|
Length = ClientCaptureBuffer->Length;
|
|
if ((PCH)ClientCaptureBuffer < t->Process->ClientViewBase ||
|
|
((PCH)ClientCaptureBuffer + Length) >= t->Process->ClientViewBounds
|
|
) {
|
|
#if DBG
|
|
KdPrint(( "*** OS2SRV: CaptureBuffer %lx (len %lx) outside of ClientView %lx-%lx\n",
|
|
ClientCaptureBuffer, Length,
|
|
t->Process->ClientViewBase, t->Process->ClientViewBounds
|
|
));
|
|
DbgBreakPoint();
|
|
#endif
|
|
m->ReturnedErrorValue = ERROR_INVALID_PARAMETER;
|
|
return( FALSE );
|
|
}
|
|
|
|
ServerCaptureBuffer = RtlAllocateHeap( Os2Heap, 0, Length );
|
|
if (ServerCaptureBuffer == NULL) {
|
|
m->ReturnedErrorValue = ERROR_NOT_ENOUGH_MEMORY;
|
|
return( FALSE );
|
|
}
|
|
|
|
RtlMoveMemory( ServerCaptureBuffer, ClientCaptureBuffer, Length );
|
|
PointerDelta = (ULONG)ServerCaptureBuffer - (ULONG)ClientCaptureBuffer;
|
|
|
|
PointerOffsets = ServerCaptureBuffer->MessagePointerOffsets;
|
|
CountPointers = ServerCaptureBuffer->CountMessagePointers;
|
|
while (CountPointers--) {
|
|
Pointer = *PointerOffsets++;
|
|
if (Pointer != 0) {
|
|
Pointer += (ULONG)m;
|
|
if ((PCH)*(PULONG)Pointer >= t->Process->ClientViewBase &&
|
|
(PCH)*(PULONG)Pointer < t->Process->ClientViewBounds
|
|
) {
|
|
*(PULONG)Pointer += PointerDelta;
|
|
}
|
|
else {
|
|
#if DBG
|
|
KdPrint(( "*** OS2SRV: CaptureBuffer MessagePointer %d of '%s' outside of ClientView\n",
|
|
ServerCaptureBuffer->CountMessagePointers - CountPointers,
|
|
Os2ServerApiName[ m->ApiNumber ] ));
|
|
DbgBreakPoint();
|
|
#endif
|
|
m->ReturnedErrorValue = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
PointerOffsets = ServerCaptureBuffer->CapturePointerOffsets;
|
|
CountPointers = ServerCaptureBuffer->CountCapturePointers;
|
|
while (CountPointers--) {
|
|
Pointer = *PointerOffsets++;
|
|
if (Pointer != 0) {
|
|
Pointer += (ULONG)ServerCaptureBuffer;
|
|
if ((PCH)*(PULONG)Pointer >= t->Process->ClientViewBase &&
|
|
(PCH)*(PULONG)Pointer < t->Process->ClientViewBounds
|
|
) {
|
|
*(PULONG)Pointer += PointerDelta;
|
|
}
|
|
else {
|
|
#if DBG
|
|
KdPrint(( "*** OS2SRV: CaptureBuffer CapturePointer outside of ClientView\n" ));
|
|
DbgBreakPoint();
|
|
#endif
|
|
m->ReturnedErrorValue = ERROR_INVALID_PARAMETER;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (m->ReturnedErrorValue != NO_ERROR) {
|
|
RtlFreeHeap( Os2Heap, 0, ServerCaptureBuffer );
|
|
return( FALSE );
|
|
}
|
|
else {
|
|
ServerCaptureBuffer->RelatedCaptureBuffer = ClientCaptureBuffer;
|
|
m->CaptureBuffer = ServerCaptureBuffer;
|
|
return( TRUE );
|
|
}
|
|
}
|
|
|
|
VOID
|
|
Os2ReleaseCapturedArguments(
|
|
IN POS2_API_MSG m
|
|
)
|
|
{
|
|
POS2_CAPTURE_HEADER ClientCaptureBuffer;
|
|
POS2_CAPTURE_HEADER ServerCaptureBuffer;
|
|
PULONG PointerOffsets;
|
|
ULONG PointerDelta, CountPointers, Pointer;
|
|
|
|
ServerCaptureBuffer = m->CaptureBuffer;
|
|
ClientCaptureBuffer = ServerCaptureBuffer->RelatedCaptureBuffer;
|
|
if (ServerCaptureBuffer == NULL) {
|
|
return;
|
|
}
|
|
ServerCaptureBuffer->RelatedCaptureBuffer = NULL;
|
|
|
|
PointerDelta = (ULONG)ClientCaptureBuffer - (ULONG)ServerCaptureBuffer;
|
|
|
|
PointerOffsets = ServerCaptureBuffer->MessagePointerOffsets;
|
|
CountPointers = ServerCaptureBuffer->CountMessagePointers;
|
|
while (CountPointers--) {
|
|
Pointer = *PointerOffsets++;
|
|
if (Pointer != 0) {
|
|
Pointer += (ULONG)m;
|
|
*(PULONG)Pointer += PointerDelta;
|
|
}
|
|
}
|
|
|
|
PointerOffsets = ServerCaptureBuffer->CapturePointerOffsets;
|
|
CountPointers = ServerCaptureBuffer->CountCapturePointers;
|
|
while (CountPointers--) {
|
|
Pointer = *PointerOffsets++;
|
|
if (Pointer != 0) {
|
|
Pointer += (ULONG)ServerCaptureBuffer;
|
|
*(PULONG)Pointer += PointerDelta;
|
|
}
|
|
}
|
|
|
|
RtlMoveMemory( ClientCaptureBuffer,
|
|
ServerCaptureBuffer,
|
|
ServerCaptureBuffer->Length
|
|
);
|
|
|
|
RtlFreeHeap( Os2Heap, 0, ServerCaptureBuffer );
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
BOOLEAN
|
|
Os2InternalNullApiCall(
|
|
IN POS2_THREAD t,
|
|
IN POS2_API_MSG m
|
|
)
|
|
{
|
|
POS2_NULLAPICALL_MSG a = &m->u.NullApiCall;
|
|
ULONG i, j;
|
|
LONG CountArguments;
|
|
PCHAR *Arguments;
|
|
|
|
UNREFERENCED_PARAMETER(t);
|
|
CountArguments = a->CountArguments;
|
|
if (CountArguments > 0) {
|
|
Arguments = a->Arguments;
|
|
j = 0;
|
|
for (i=0; i<(ULONG)CountArguments; i++) {
|
|
if (Arguments[ i ] != NULL && *Arguments[ i ] != '\0') {
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
j = 0;
|
|
CountArguments = -CountArguments;
|
|
Arguments = (PCHAR *)(&a->FastArguments[ 0 ]);
|
|
for (i=0; i<(ULONG)CountArguments; i++) {
|
|
if (Arguments[ i ]) {
|
|
j++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return( TRUE );
|
|
}
|
|
|
|
NTSTATUS
|
|
Os2DebugRequestThread(
|
|
IN PVOID Parameter
|
|
)
|
|
{
|
|
NTSTATUS Status;
|
|
POS2_PROCESS Process;
|
|
OS2_API_MSG ReceiveMsg;
|
|
POS2_API_MSG ReplyMsg;
|
|
|
|
UNREFERENCED_PARAMETER(Parameter);
|
|
ReplyMsg = NULL;
|
|
|
|
//
|
|
// At init time - we sync with other server threads
|
|
//
|
|
Os2AcquireStructureLock();
|
|
|
|
//
|
|
// Let other server threads get in after we are in sync
|
|
//
|
|
Os2ReleaseStructureLock();
|
|
|
|
while (TRUE) {
|
|
|
|
Status = NtReplyWaitReceivePort( Os2DebugPort,
|
|
(PVOID *)&Process,
|
|
(PPORT_MESSAGE)ReplyMsg,
|
|
(PPORT_MESSAGE)&ReceiveMsg
|
|
);
|
|
if (Status != 0) {
|
|
if (!NT_SUCCESS( Status )) {
|
|
#if DBG
|
|
KdPrint(( "OS2SRV: DebugPort failed - Status == %X\n", Status ));
|
|
DbgBreakPoint();
|
|
#endif
|
|
// NtTerminateThread( NtCurrentThread(), Status );
|
|
}
|
|
ReplyMsg = NULL;
|
|
continue; // Try again if alerted or a failure
|
|
}
|
|
|
|
//
|
|
// Check for debugger event
|
|
//
|
|
if ( ReceiveMsg.h.u2.s2.Type != LPC_DEBUG_EVENT ) {
|
|
#if DBG
|
|
KdPrint(("OS2SRV: LPC_DEBUG_EVENT not received"));
|
|
ASSERT(FALSE);
|
|
#endif
|
|
}
|
|
else {
|
|
if ( (((PDBGKM_APIMSG)&ReceiveMsg)->ApiNumber == DbgKmExceptionApi) ) {
|
|
//
|
|
// sync with other server threads before we muck with global
|
|
// structures
|
|
//
|
|
Os2AcquireStructureLock();
|
|
Os2HandleDebugEvent(Process,(PDBGKM_APIMSG)&ReceiveMsg);
|
|
//
|
|
// Let other server threads get in after we are done with the request
|
|
//
|
|
Os2ReleaseStructureLock();
|
|
}
|
|
else {
|
|
//
|
|
// Don't lock for other kernel notifications, which do not require
|
|
// mucking with server structures
|
|
// (thread creation/termination etc.)
|
|
//
|
|
Os2HandleDebugEvent(Process,(PDBGKM_APIMSG)&ReceiveMsg);
|
|
}
|
|
}
|
|
|
|
ReplyMsg = NULL;
|
|
continue;
|
|
|
|
}
|
|
|
|
NtTerminateThread( NtCurrentThread(), Status );
|
|
return( Status );
|
|
}
|