mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 18:31:56 +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
|
||||
} 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
|
||||
//
|
||||
|
@ -173,7 +189,7 @@ typedef struct _DBGUI_WAIT_STATE_CHANGE
|
|||
typedef struct _DBGKM_MSG
|
||||
{
|
||||
PORT_MESSAGE h;
|
||||
ULONG ApiNumber;
|
||||
DBGKM_APINUMBER ApiNumber;
|
||||
ULONG ReturnedStatus;
|
||||
union
|
||||
{
|
||||
|
|
|
@ -68,4 +68,18 @@ DbgkExitThread(IN NTSTATUS ExitStatus)
|
|||
/* FIXME */
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpSuspendProcess(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpResumeProcess(VOID)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -26,12 +26,127 @@ GENERIC_MAPPING DbgkDebugObjectMapping =
|
|||
|
||||
/* 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
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
||||
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
|
||||
|
@ -40,16 +155,131 @@ DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord,
|
|||
IN BOOLEAN DebugPort,
|
||||
IN BOOLEAN SecondChance)
|
||||
{
|
||||
/* FIXME: Implement */
|
||||
return FALSE;
|
||||
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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
NTAPI
|
||||
DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
return;
|
||||
PETHREAD Thread = DebugEvent->Thread;
|
||||
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
|
||||
|
@ -92,6 +322,14 @@ DbgkpConvertKernelToUserStateChange(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
|||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpMarkProcessPeb(IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||
|
@ -187,6 +425,10 @@ DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
|||
0,
|
||||
DUPLICATE_SAME_ACCESS,
|
||||
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));
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpMarkProcessPeb(IN PEPROCESS Process)
|
||||
{
|
||||
/* FIXME: TODO */
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
||||
|
|
|
@ -19,6 +19,18 @@ DbgkExitThread(
|
|||
IN NTSTATUS ExitStatus
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpSuspendProcess(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkpResumeProcess(
|
||||
VOID
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
DbgkCopyProcessDebugPort(
|
||||
|
|
|
@ -332,6 +332,16 @@ PspDeleteJob(
|
|||
IN PVOID ObjectBody
|
||||
);
|
||||
|
||||
//
|
||||
// State routines
|
||||
//
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
PsResumeThread(
|
||||
IN PETHREAD Thread,
|
||||
OUT PULONG PreviousCount OPTIONAL
|
||||
);
|
||||
|
||||
//
|
||||
// Global data inside the Process Manager
|
||||
//
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue