mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 17:03:02 +00:00
- Define DBGKM_APINUMBER
- Implement DbgkpSendApiMessageLpc, DbgkpSendApiMessage, DbgkCopyProcessDebugPort, DbgkForwardException, DbgkFreeDebugEvent, DbgpWakeTarget. - Close original handle in DbgkOpenHandles. svn path=/trunk/; revision=24575
This commit is contained in:
parent
0d09a4e5f9
commit
9c4178c05b
5 changed files with 300 additions and 14 deletions
|
@ -42,6 +42,22 @@ typedef enum _DEBUGOBJECTINFOCLASS
|
||||||
DebugObjectKillProcessOnExitInformation
|
DebugObjectKillProcessOnExitInformation
|
||||||
} DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS;
|
} DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Debug Message API Number
|
||||||
|
//
|
||||||
|
typedef enum _DBGKM_APINUMBER
|
||||||
|
{
|
||||||
|
DbgKmExceptionApi = 0,
|
||||||
|
DbgKmCreateThreadApi = 1,
|
||||||
|
DbgKmCreateProcessApi = 2,
|
||||||
|
DbgKmExitThreadApi = 3,
|
||||||
|
DbgKmExitProcessApi = 4,
|
||||||
|
DbgKmLoadDllApi = 5,
|
||||||
|
DbgKmUnloadDllApi = 6,
|
||||||
|
DbgKmErrorReportApi = 7,
|
||||||
|
DbgKmMaxApiNumber = 8,
|
||||||
|
} DBGKM_APINUMBER;
|
||||||
|
|
||||||
//
|
//
|
||||||
// Debug Object Information Structures
|
// Debug Object Information Structures
|
||||||
//
|
//
|
||||||
|
@ -173,7 +189,7 @@ typedef struct _DBGUI_WAIT_STATE_CHANGE
|
||||||
typedef struct _DBGKM_MSG
|
typedef struct _DBGKM_MSG
|
||||||
{
|
{
|
||||||
PORT_MESSAGE h;
|
PORT_MESSAGE h;
|
||||||
ULONG ApiNumber;
|
DBGKM_APINUMBER ApiNumber;
|
||||||
ULONG ReturnedStatus;
|
ULONG ReturnedStatus;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,4 +68,18 @@ DbgkExitThread(IN NTSTATUS ExitStatus)
|
||||||
/* FIXME */
|
/* FIXME */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpSuspendProcess(VOID)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpResumeProcess(VOID)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -26,12 +26,127 @@ GENERIC_MAPPING DbgkDebugObjectMapping =
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DbgkpQueueMessage(IN PEPROCESS Process,
|
||||||
|
IN PETHREAD Thread,
|
||||||
|
IN PDBGKM_MSG Message,
|
||||||
|
IN ULONG Flags,
|
||||||
|
IN PDEBUG_OBJECT TargetObject OPTIONAL)
|
||||||
|
{
|
||||||
|
/* FIXME: TODO */
|
||||||
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DbgkpSendApiMessageLpc(IN OUT PDBGKM_MSG Message,
|
||||||
|
IN PVOID Port,
|
||||||
|
IN BOOLEAN SuspendProcess)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
UCHAR Buffer[PORT_MAXIMUM_MESSAGE_LENGTH];
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Suspend process if required */
|
||||||
|
if (SuspendProcess) DbgkpSuspendProcess();
|
||||||
|
|
||||||
|
/* Set return status */
|
||||||
|
Message->ReturnedStatus = STATUS_PENDING;
|
||||||
|
|
||||||
|
/* Set create process reported state */
|
||||||
|
PsGetCurrentProcess()->CreateReported = TRUE;
|
||||||
|
|
||||||
|
/* Send the LPC command */
|
||||||
|
#if 0
|
||||||
|
Status = LpcRequestWaitReplyPort(Port,
|
||||||
|
(PPORT_MESSAGE)Message,
|
||||||
|
(PPORT_MESSAGE)&Buffer[0]);
|
||||||
|
#else
|
||||||
|
Status = STATUS_UNSUCCESSFUL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Flush the instruction cache */
|
||||||
|
ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
|
||||||
|
|
||||||
|
/* Copy the buffer back */
|
||||||
|
if (NT_SUCCESS(Status)) RtlMoveMemory(Message, Buffer, sizeof(DBGKM_MSG));
|
||||||
|
|
||||||
|
/* Resume the process if it was suspended */
|
||||||
|
if (SuspendProcess) DbgkpResumeProcess();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DbgkpSendApiMessage(IN OUT PDBGKM_MSG ApiMsg,
|
||||||
|
IN ULONG Flags)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Suspend process if required */
|
||||||
|
if (Flags) DbgkpSuspendProcess();
|
||||||
|
|
||||||
|
/* Set return status */
|
||||||
|
ApiMsg->ReturnedStatus = STATUS_PENDING;
|
||||||
|
|
||||||
|
/* Set create process reported state */
|
||||||
|
PsGetCurrentProcess()->CreateReported = TRUE;
|
||||||
|
|
||||||
|
/* Send the LPC command */
|
||||||
|
Status = DbgkpQueueMessage(PsGetCurrentProcess(),
|
||||||
|
PsGetCurrentThread(),
|
||||||
|
ApiMsg,
|
||||||
|
0,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
/* Flush the instruction cache */
|
||||||
|
ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0);
|
||||||
|
|
||||||
|
/* Resume the process if it was suspended */
|
||||||
|
if (Flags) DbgkpResumeProcess();
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
||||||
IN PEPROCESS Parent)
|
IN PEPROCESS Parent)
|
||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
PDEBUG_OBJECT DebugObject;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Clear this process's port */
|
||||||
|
Process->DebugPort = NULL;
|
||||||
|
|
||||||
|
/* Check if the parent has one */
|
||||||
|
if (!Parent->DebugPort) return;
|
||||||
|
|
||||||
|
/* It does, acquire the mutex */
|
||||||
|
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
|
|
||||||
|
/* Make sure it still has one, and that we should inherit */
|
||||||
|
DebugObject = Parent->DebugPort;
|
||||||
|
if ((DebugObject) && !(Process->NoDebugInherit))
|
||||||
|
{
|
||||||
|
/* Acquire the debug object's lock */
|
||||||
|
ExAcquireFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
|
/* Make sure the debugger is active */
|
||||||
|
if (!DebugObject->DebuggerInactive)
|
||||||
|
{
|
||||||
|
/* Reference the object and set it */
|
||||||
|
ObReferenceObject(DebugObject);
|
||||||
|
Process->DebugPort = DebugObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the debug object */
|
||||||
|
ExReleaseFastMutex(&DebugObject->Mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the port mutex */
|
||||||
|
ExReleaseFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
|
@ -40,16 +155,131 @@ DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord,
|
||||||
IN BOOLEAN DebugPort,
|
IN BOOLEAN DebugPort,
|
||||||
IN BOOLEAN SecondChance)
|
IN BOOLEAN SecondChance)
|
||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
DBGKM_MSG ApiMessage;
|
||||||
|
PDBGKM_EXCEPTION DbgKmException = &ApiMessage.Exception;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PEPROCESS Process = PsGetCurrentProcess();
|
||||||
|
PVOID Port;
|
||||||
|
BOOLEAN UseLpc = FALSE;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Setup the API Message */
|
||||||
|
ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
|
||||||
|
(8 + sizeof(DBGKM_EXCEPTION));
|
||||||
|
ApiMessage.h.u2.ZeroInit = LPC_DEBUG_EVENT;
|
||||||
|
ApiMessage.ApiNumber = DbgKmExceptionApi;
|
||||||
|
|
||||||
|
/* Check if this is to be sent on the debug port */
|
||||||
|
if (DebugPort)
|
||||||
|
{
|
||||||
|
/* Use the debug port, onless the thread is being hidden */
|
||||||
|
Port = PsGetCurrentThread()->HideFromDebugger ?
|
||||||
|
NULL : Process->DebugPort;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, use the exception port */
|
||||||
|
Port = Process->ExceptionPort;
|
||||||
|
ApiMessage.h.u2.ZeroInit = LPC_EXCEPTION;
|
||||||
|
UseLpc = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Break out if there's no port */
|
||||||
|
if (!Port) return FALSE;
|
||||||
|
|
||||||
|
/* Fill out the exception information */
|
||||||
|
DbgKmException->ExceptionRecord = *ExceptionRecord;
|
||||||
|
DbgKmException->FirstChance = !SecondChance;
|
||||||
|
|
||||||
|
/* Check if we should use LPC */
|
||||||
|
if (UseLpc)
|
||||||
|
{
|
||||||
|
/* Send the message on the LPC Port */
|
||||||
|
Status = DbgkpSendApiMessageLpc(&ApiMessage, Port, DebugPort);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Use native debug object */
|
||||||
|
Status = DbgkpSendApiMessage(&ApiMessage, DebugPort);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we failed, and for a debug port, also check the return status */
|
||||||
|
if (!(NT_SUCCESS(Status)) ||
|
||||||
|
((DebugPort) &&
|
||||||
|
(!(NT_SUCCESS(ApiMessage.ReturnedStatus)) ||
|
||||||
|
(ApiMessage.ReturnedStatus == DBG_EXCEPTION_NOT_HANDLED))))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Otherwise, we're ok */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpFreeDebugEvent(IN PDEBUG_EVENT DebugEvent)
|
||||||
|
{
|
||||||
|
PHANDLE Handle = NULL;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if this event had a file handle */
|
||||||
|
switch (DebugEvent->ApiMsg.ApiNumber)
|
||||||
|
{
|
||||||
|
/* Create process has a handle */
|
||||||
|
case DbgKmCreateProcessApi:
|
||||||
|
|
||||||
|
/* Get the pointer */
|
||||||
|
Handle = &DebugEvent->ApiMsg.CreateProcess.FileHandle;
|
||||||
|
|
||||||
|
/* As does DLL load */
|
||||||
|
case DbgKmLoadDllApi:
|
||||||
|
|
||||||
|
/* Get the pointer */
|
||||||
|
Handle = &DebugEvent->ApiMsg.LoadDll.FileHandle;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Close the handle if it exsts */
|
||||||
|
if ((Handle) && (*Handle)) ObCloseHandle(*Handle, KernelMode);
|
||||||
|
|
||||||
|
/* Dereference process and thread and free the event */
|
||||||
|
ObDereferenceObject(DebugEvent->Process);
|
||||||
|
ObDereferenceObject(DebugEvent->Thread);
|
||||||
|
ExFreePool(DebugEvent);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent)
|
DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO */
|
PETHREAD Thread = DebugEvent->Thread;
|
||||||
return;
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check if we have to wake the thread */
|
||||||
|
if (DebugEvent->Flags & 20) PsResumeThread(Thread, NULL);
|
||||||
|
|
||||||
|
/* Check if we had locked the thread */
|
||||||
|
if (DebugEvent->Flags & 8)
|
||||||
|
{
|
||||||
|
/* Unlock it */
|
||||||
|
ExReleaseRundownProtection(&Thread->RundownProtect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we have to wake up the event */
|
||||||
|
if (DebugEvent->Flags & 2)
|
||||||
|
{
|
||||||
|
/* Signal the continue event */
|
||||||
|
KeSetEvent(&DebugEvent->ContinueEvent, IO_NO_INCREMENT, FALSE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Otherwise, free the debug event */
|
||||||
|
DbgkpFreeDebugEvent(DebugEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -92,6 +322,14 @@ DbgkpConvertKernelToUserStateChange(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpMarkProcessPeb(IN PEPROCESS Process)
|
||||||
|
{
|
||||||
|
/* FIXME: TODO */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||||
|
@ -187,6 +425,10 @@ DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||||
0,
|
0,
|
||||||
DUPLICATE_SAME_ACCESS,
|
DUPLICATE_SAME_ACCESS,
|
||||||
KernelMode);
|
KernelMode);
|
||||||
|
if (NT_SUCCESS(Status)) *DupHandle = NULL;
|
||||||
|
|
||||||
|
/* Close the original handle */
|
||||||
|
ObCloseHandle(Handle, KernelMode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,14 +443,6 @@ DbgkpDeleteObject(IN PVOID Object)
|
||||||
ASSERT(IsListEmpty(&DebugObject->EventList));
|
ASSERT(IsListEmpty(&DebugObject->EventList));
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
DbgkpMarkProcessPeb(IN PEPROCESS Process)
|
|
||||||
{
|
|
||||||
/* FIXME: TODO */
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
||||||
|
|
|
@ -19,6 +19,18 @@ DbgkExitThread(
|
||||||
IN NTSTATUS ExitStatus
|
IN NTSTATUS ExitStatus
|
||||||
);
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpSuspendProcess(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpResumeProcess(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkCopyProcessDebugPort(
|
DbgkCopyProcessDebugPort(
|
||||||
|
|
|
@ -332,6 +332,16 @@ PspDeleteJob(
|
||||||
IN PVOID ObjectBody
|
IN PVOID ObjectBody
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//
|
||||||
|
// State routines
|
||||||
|
//
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsResumeThread(
|
||||||
|
IN PETHREAD Thread,
|
||||||
|
OUT PULONG PreviousCount OPTIONAL
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Global data inside the Process Manager
|
// Global data inside the Process Manager
|
||||||
//
|
//
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue