mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 16:35:49 +00:00
- Fixup DEBUG_OBJECT definition.
- Implement DbgkpCloseObject. - Implement DbgkpOpenHandles. - Fix various bugs in the code and flag usage. - Enable calling DbgkClearProcessDebugObject when terminating a process. svn path=/trunk/; revision=24574
This commit is contained in:
parent
41ba900587
commit
0d09a4e5f9
8 changed files with 305 additions and 92 deletions
|
@ -55,11 +55,11 @@ typedef struct _DEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION
|
||||||
//
|
//
|
||||||
// Debug Object
|
// Debug Object
|
||||||
//
|
//
|
||||||
typedef struct _DBGK_DEBUG_OBJECT
|
typedef struct _DEBUG_OBJECT
|
||||||
{
|
{
|
||||||
KEVENT Event;
|
KEVENT EventsPresent;
|
||||||
FAST_MUTEX Mutex;
|
FAST_MUTEX Mutex;
|
||||||
LIST_ENTRY StateEventListEntry;
|
LIST_ENTRY EventList;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
ULONG Flags;
|
ULONG Flags;
|
||||||
|
@ -69,7 +69,7 @@ typedef struct _DBGK_DEBUG_OBJECT
|
||||||
UCHAR KillProcessOnExit:1;
|
UCHAR KillProcessOnExit:1;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} DBGK_DEBUG_OBJECT, *PDBGK_DEBUG_OBJECT;
|
} DEBUG_OBJECT, *PDEBUG_OBJECT;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
POBJECT_TYPE DbgkDebugObjectType;
|
POBJECT_TYPE DbgkDebugObjectType;
|
||||||
KGUARDED_MUTEX DbgkpProcessDebugPortMutex;
|
FAST_MUTEX DbgkpProcessDebugPortMutex;
|
||||||
|
|
||||||
GENERIC_MAPPING DbgkDebugObjectMapping =
|
GENERIC_MAPPING DbgkDebugObjectMapping =
|
||||||
{
|
{
|
||||||
|
@ -26,58 +26,6 @@ GENERIC_MAPPING DbgkDebugObjectMapping =
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
DbgkpDeleteObject(IN PVOID Object)
|
|
||||||
{
|
|
||||||
PDBGK_DEBUG_OBJECT DebugObject = Object;
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Sanity check */
|
|
||||||
ASSERT(IsListEmpty(&DebugObject->StateEventListEntry));
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
NTAPI
|
|
||||||
DbgkpCloseObject(IN PEPROCESS Process OPTIONAL,
|
|
||||||
IN PVOID ObjectBody,
|
|
||||||
IN ACCESS_MASK GrantedAccess,
|
|
||||||
IN ULONG HandleCount,
|
|
||||||
IN ULONG SystemHandleCount)
|
|
||||||
{
|
|
||||||
/* FIXME: Implement */
|
|
||||||
ASSERT(FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
|
||||||
INIT_FUNCTION
|
|
||||||
NTAPI
|
|
||||||
DbgkInitialize(VOID)
|
|
||||||
{
|
|
||||||
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
|
||||||
UNICODE_STRING Name;
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
/* Initialize the process debug port mutex */
|
|
||||||
KeInitializeGuardedMutex(&DbgkpProcessDebugPortMutex);
|
|
||||||
|
|
||||||
/* Create the Event Pair Object Type */
|
|
||||||
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
|
||||||
RtlInitUnicodeString(&Name, L"DebugObject");
|
|
||||||
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
|
||||||
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DBGK_DEBUG_OBJECT);
|
|
||||||
ObjectTypeInitializer.GenericMapping = DbgkDebugObjectMapping;
|
|
||||||
ObjectTypeInitializer.PoolType = NonPagedPool;
|
|
||||||
ObjectTypeInitializer.ValidAccessMask = DEBUG_OBJECT_WAIT_STATE_CHANGE;
|
|
||||||
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
|
||||||
ObjectTypeInitializer.CloseProcedure = DbgkpCloseObject;
|
|
||||||
ObjectTypeInitializer.DeleteProcedure = DbgkpDeleteObject;
|
|
||||||
ObCreateObjectType(&Name,
|
|
||||||
&ObjectTypeInitializer,
|
|
||||||
NULL,
|
|
||||||
&DbgkDebugObjectType);
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
DbgkCopyProcessDebugPort(IN PEPROCESS Process,
|
||||||
|
@ -107,7 +55,7 @@ DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent)
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process,
|
DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process,
|
||||||
IN PDBGK_DEBUG_OBJECT DebugObject,
|
IN PDEBUG_OBJECT DebugObject,
|
||||||
IN PETHREAD *LastThread)
|
IN PETHREAD *LastThread)
|
||||||
{
|
{
|
||||||
/* FIXME: Implement */
|
/* FIXME: Implement */
|
||||||
|
@ -118,7 +66,7 @@ DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkpSetProcessDebugObject(IN PEPROCESS Process,
|
DbgkpSetProcessDebugObject(IN PEPROCESS Process,
|
||||||
IN PDBGK_DEBUG_OBJECT DebugObject,
|
IN PDEBUG_OBJECT DebugObject,
|
||||||
IN NTSTATUS MsgStatus,
|
IN NTSTATUS MsgStatus,
|
||||||
IN PETHREAD LastThread)
|
IN PETHREAD LastThread)
|
||||||
{
|
{
|
||||||
|
@ -129,7 +77,7 @@ DbgkpSetProcessDebugObject(IN PEPROCESS Process,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkClearProcessDebugObject(IN PEPROCESS Process,
|
DbgkClearProcessDebugObject(IN PEPROCESS Process,
|
||||||
IN PDBGK_DEBUG_OBJECT SourceDebugObject)
|
IN PDEBUG_OBJECT SourceDebugObject)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO */
|
/* FIXME: TODO */
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
@ -149,11 +97,233 @@ NTAPI
|
||||||
DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||||
IN PEPROCESS Process,
|
IN PEPROCESS Process,
|
||||||
IN PETHREAD Thread)
|
IN PETHREAD Thread)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE Handle;
|
||||||
|
PHANDLE DupHandle;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Check which state this is */
|
||||||
|
switch (WaitStateChange->NewState)
|
||||||
|
{
|
||||||
|
/* New thread */
|
||||||
|
case DbgCreateThreadStateChange:
|
||||||
|
|
||||||
|
/* Get handle to thread */
|
||||||
|
Status = ObOpenObjectByPointer(Thread,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
PsThreadType,
|
||||||
|
KernelMode,
|
||||||
|
&Handle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Save the thread handle */
|
||||||
|
WaitStateChange->
|
||||||
|
StateInfo.CreateThread.HandleToThread = Handle;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* New process */
|
||||||
|
case DbgCreateProcessStateChange:
|
||||||
|
|
||||||
|
/* Get handle to thread */
|
||||||
|
Status = ObOpenObjectByPointer(Thread,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
THREAD_ALL_ACCESS,
|
||||||
|
PsThreadType,
|
||||||
|
KernelMode,
|
||||||
|
&Handle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Save the thread handle */
|
||||||
|
WaitStateChange->
|
||||||
|
StateInfo.CreateProcessInfo.HandleToThread = Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get handle to process */
|
||||||
|
Status = ObOpenObjectByPointer(Process,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
PROCESS_ALL_ACCESS,
|
||||||
|
PsProcessType,
|
||||||
|
KernelMode,
|
||||||
|
&Handle);
|
||||||
|
if (NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Save the process handle */
|
||||||
|
WaitStateChange->
|
||||||
|
StateInfo.CreateProcessInfo.HandleToProcess = Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fall through to duplicate file handle */
|
||||||
|
DupHandle = &WaitStateChange->
|
||||||
|
StateInfo.CreateProcessInfo.NewProcess.FileHandle;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* DLL Load */
|
||||||
|
case DbgLoadDllStateChange:
|
||||||
|
|
||||||
|
/* Fall through to duplicate file handle */
|
||||||
|
DupHandle = &WaitStateChange->StateInfo.LoadDll.FileHandle;
|
||||||
|
|
||||||
|
/* Anything else has no handles */
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we got here, then we have to duplicate a handle, possibly */
|
||||||
|
Handle = *DupHandle;
|
||||||
|
if (Handle)
|
||||||
|
{
|
||||||
|
/* Duplicate it */
|
||||||
|
Status = ObDuplicateObject(PsGetCurrentProcess(),
|
||||||
|
Handle,
|
||||||
|
PsGetCurrentProcess(),
|
||||||
|
DupHandle,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
DUPLICATE_SAME_ACCESS,
|
||||||
|
KernelMode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpDeleteObject(IN PVOID Object)
|
||||||
|
{
|
||||||
|
PDEBUG_OBJECT DebugObject = Object;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Sanity check */
|
||||||
|
ASSERT(IsListEmpty(&DebugObject->EventList));
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpMarkProcessPeb(IN PEPROCESS Process)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO */
|
/* FIXME: TODO */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL,
|
||||||
|
IN PVOID ObjectBody,
|
||||||
|
IN ACCESS_MASK GrantedAccess,
|
||||||
|
IN ULONG HandleCount,
|
||||||
|
IN ULONG SystemHandleCount)
|
||||||
|
{
|
||||||
|
PDEBUG_OBJECT DebugObject = ObjectBody;
|
||||||
|
PEPROCESS Process = NULL;
|
||||||
|
BOOLEAN DebugPortCleared = FALSE;
|
||||||
|
PLIST_ENTRY DebugEventList;
|
||||||
|
PDEBUG_EVENT DebugEvent;
|
||||||
|
|
||||||
|
/* If this isn't the last handle, do nothing */
|
||||||
|
if (HandleCount > 1) return;
|
||||||
|
|
||||||
|
/* Otherwise, lock the debug object */
|
||||||
|
ExAcquireFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
|
/* Set it as inactive */
|
||||||
|
DebugObject->DebuggerInactive = TRUE;
|
||||||
|
|
||||||
|
/* Remove it from the debug event list */
|
||||||
|
DebugEventList = DebugObject->EventList.Flink;
|
||||||
|
InitializeListHead(&DebugObject->EventList);
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
|
ExReleaseFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
|
/* Signal the wait event */
|
||||||
|
KeSetEvent(&DebugObject->EventsPresent, IO_NO_INCREMENT, FALSE);
|
||||||
|
|
||||||
|
/* Start looping each process */
|
||||||
|
while ((Process = PsGetNextProcess(Process)))
|
||||||
|
{
|
||||||
|
/* Check if the process has us as their debug port */
|
||||||
|
if (Process->DebugPort == DebugObject)
|
||||||
|
{
|
||||||
|
/* Acquire the process debug port lock */
|
||||||
|
ExAcquireFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
|
|
||||||
|
/* Check if it's still us */
|
||||||
|
if (Process->DebugPort == DebugObject)
|
||||||
|
{
|
||||||
|
/* Clear it and remember */
|
||||||
|
Process->DebugPort = NULL;
|
||||||
|
DebugPortCleared = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the port lock */
|
||||||
|
ExReleaseFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
|
|
||||||
|
/* Check if we cleared the debug port */
|
||||||
|
if (DebugPortCleared)
|
||||||
|
{
|
||||||
|
/* Mark this in the PEB */
|
||||||
|
DbgkpMarkProcessPeb(OwnerProcess);
|
||||||
|
|
||||||
|
/* Check if we terminate on exit */
|
||||||
|
if (DebugObject->KillProcessOnExit)
|
||||||
|
{
|
||||||
|
/* Terminate the process */
|
||||||
|
PsTerminateProcess(OwnerProcess, STATUS_DEBUGGER_INACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dereference the debug object */
|
||||||
|
ObDereferenceObject(DebugObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Loop debug events */
|
||||||
|
while (DebugEventList != &DebugObject->EventList)
|
||||||
|
{
|
||||||
|
/* Get the debug event */
|
||||||
|
DebugEvent = CONTAINING_RECORD(DebugEventList, DEBUG_EVENT, EventList);
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
DebugEventList = DebugEventList->Flink;
|
||||||
|
|
||||||
|
/* Wake it up */
|
||||||
|
DebugEvent->Status = STATUS_DEBUGGER_INACTIVE;
|
||||||
|
DbgkpWakeTarget(DebugEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
INIT_FUNCTION
|
||||||
|
NTAPI
|
||||||
|
DbgkInitialize(VOID)
|
||||||
|
{
|
||||||
|
OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
|
||||||
|
UNICODE_STRING Name;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Initialize the process debug port mutex */
|
||||||
|
ExInitializeFastMutex(&DbgkpProcessDebugPortMutex);
|
||||||
|
|
||||||
|
/* Create the Debug Object Type */
|
||||||
|
RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
|
||||||
|
RtlInitUnicodeString(&Name, L"DebugObject");
|
||||||
|
ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
|
||||||
|
ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEBUG_OBJECT);
|
||||||
|
ObjectTypeInitializer.GenericMapping = DbgkDebugObjectMapping;
|
||||||
|
ObjectTypeInitializer.PoolType = NonPagedPool;
|
||||||
|
ObjectTypeInitializer.ValidAccessMask = DEBUG_OBJECT_WAIT_STATE_CHANGE;
|
||||||
|
ObjectTypeInitializer.UseDefaultObject = TRUE;
|
||||||
|
ObjectTypeInitializer.CloseProcedure = DbgkpCloseObject;
|
||||||
|
ObjectTypeInitializer.DeleteProcedure = DbgkpDeleteObject;
|
||||||
|
ObCreateObjectType(&Name,
|
||||||
|
&ObjectTypeInitializer,
|
||||||
|
NULL,
|
||||||
|
&DbgkDebugObjectType);
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -165,7 +335,7 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
|
||||||
IN BOOLEAN KillProcessOnExit)
|
IN BOOLEAN KillProcessOnExit)
|
||||||
{
|
{
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
HANDLE hDebug;
|
HANDLE hDebug;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
@ -193,7 +363,7 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
|
||||||
ObjectAttributes,
|
ObjectAttributes,
|
||||||
PreviousMode,
|
PreviousMode,
|
||||||
NULL,
|
NULL,
|
||||||
sizeof(PDBGK_DEBUG_OBJECT),
|
sizeof(PDEBUG_OBJECT),
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(PVOID*)&DebugObject);
|
(PVOID*)&DebugObject);
|
||||||
|
@ -203,10 +373,10 @@ NtCreateDebugObject(OUT PHANDLE DebugHandle,
|
||||||
ExInitializeFastMutex(&DebugObject->Mutex);
|
ExInitializeFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
/* Initialize the State Event List */
|
/* Initialize the State Event List */
|
||||||
InitializeListHead(&DebugObject->StateEventListEntry);
|
InitializeListHead(&DebugObject->EventList);
|
||||||
|
|
||||||
/* Initialize the Debug Object's Wait Event */
|
/* Initialize the Debug Object's Wait Event */
|
||||||
KeInitializeEvent(&DebugObject->Event, NotificationEvent, 0);
|
KeInitializeEvent(&DebugObject->EventsPresent, NotificationEvent, 0);
|
||||||
|
|
||||||
/* Set the Flags */
|
/* Set the Flags */
|
||||||
DebugObject->KillProcessOnExit = KillProcessOnExit;
|
DebugObject->KillProcessOnExit = KillProcessOnExit;
|
||||||
|
@ -245,7 +415,7 @@ NtDebugContinue(IN HANDLE DebugHandle,
|
||||||
IN NTSTATUS ContinueStatus)
|
IN NTSTATUS ContinueStatus)
|
||||||
{
|
{
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDEBUG_EVENT DebugEvent = NULL, DebugEventToWake = NULL;
|
PDEBUG_EVENT DebugEvent = NULL, DebugEventToWake = NULL;
|
||||||
PLIST_ENTRY ListHead, NextEntry;
|
PLIST_ENTRY ListHead, NextEntry;
|
||||||
|
@ -296,7 +466,7 @@ NtDebugContinue(IN HANDLE DebugHandle,
|
||||||
ExAcquireFastMutex(&DebugObject->Mutex);
|
ExAcquireFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
/* Loop the state list */
|
/* Loop the state list */
|
||||||
ListHead = &DebugObject->StateEventListEntry;
|
ListHead = &DebugObject->EventList;
|
||||||
NextEntry = ListHead->Flink;
|
NextEntry = ListHead->Flink;
|
||||||
while (ListHead != NextEntry)
|
while (ListHead != NextEntry)
|
||||||
{
|
{
|
||||||
|
@ -371,7 +541,7 @@ NtDebugActiveProcess(IN HANDLE ProcessHandle,
|
||||||
IN HANDLE DebugHandle)
|
IN HANDLE DebugHandle)
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||||
PETHREAD LastThread;
|
PETHREAD LastThread;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
@ -435,7 +605,7 @@ NtRemoveProcessDebug(IN HANDLE ProcessHandle,
|
||||||
IN HANDLE DebugHandle)
|
IN HANDLE DebugHandle)
|
||||||
{
|
{
|
||||||
PEPROCESS Process;
|
PEPROCESS Process;
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = KeGetPreviousMode();
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
@ -487,7 +657,7 @@ NtSetInformationDebugObject(IN HANDLE DebugHandle,
|
||||||
IN ULONG DebugInformationLength,
|
IN ULONG DebugInformationLength,
|
||||||
OUT PULONG ReturnLength OPTIONAL)
|
OUT PULONG ReturnLength OPTIONAL)
|
||||||
{
|
{
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION DebugInfo = DebugInformation;
|
PDEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION DebugInfo = DebugInformation;
|
||||||
|
@ -522,12 +692,12 @@ NtSetInformationDebugObject(IN HANDLE DebugHandle,
|
||||||
if (DebugInfo->KillProcessOnExit)
|
if (DebugInfo->KillProcessOnExit)
|
||||||
{
|
{
|
||||||
/* Enable killing the process */
|
/* Enable killing the process */
|
||||||
DebugObject->Flags |= 2;
|
DebugObject->KillProcessOnExit = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Disable */
|
/* Disable */
|
||||||
DebugObject->Flags &= ~2;
|
DebugObject->KillProcessOnExit = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the mutex */
|
/* Release the mutex */
|
||||||
|
@ -555,7 +725,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
PETHREAD Thread;
|
PETHREAD Thread;
|
||||||
BOOLEAN GotEvent;
|
BOOLEAN GotEvent;
|
||||||
LARGE_INTEGER NewTime;
|
LARGE_INTEGER NewTime;
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
DBGUI_WAIT_STATE_CHANGE WaitStateChange;
|
DBGUI_WAIT_STATE_CHANGE WaitStateChange;
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
PDEBUG_EVENT DebugEvent, DebugEvent2;
|
PDEBUG_EVENT DebugEvent, DebugEvent2;
|
||||||
|
@ -628,7 +798,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
ExAcquireFastMutex(&DebugObject->Mutex);
|
ExAcquireFastMutex(&DebugObject->Mutex);
|
||||||
|
|
||||||
/* Check if a debugger is connected */
|
/* Check if a debugger is connected */
|
||||||
if (DebugObject->Flags & 1)
|
if (DebugObject->DebuggerInactive)
|
||||||
{
|
{
|
||||||
/* Not connected */
|
/* Not connected */
|
||||||
Status = STATUS_DEBUGGER_INACTIVE;
|
Status = STATUS_DEBUGGER_INACTIVE;
|
||||||
|
@ -636,7 +806,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Loop the events */
|
/* Loop the events */
|
||||||
ListHead = &DebugObject->StateEventListEntry;
|
ListHead = &DebugObject->EventList;
|
||||||
NextEntry = ListHead->Flink;
|
NextEntry = ListHead->Flink;
|
||||||
while (ListHead != NextEntry)
|
while (ListHead != NextEntry)
|
||||||
{
|
{
|
||||||
|
@ -702,7 +872,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Unsignal the event */
|
/* Unsignal the event */
|
||||||
DebugObject->Event.Header.SignalState = 0;
|
DebugObject->EventsPresent.Header.SignalState = 0;
|
||||||
Status = STATUS_SUCCESS;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,15 +3,21 @@
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkCreateThread(PVOID StartAddress);
|
DbgkCreateThread(
|
||||||
|
IN PVOID StartAddress
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkExitProcess(IN NTSTATUS ExitStatus);
|
DbgkExitProcess(
|
||||||
|
IN NTSTATUS ExitStatus
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgkExitThread(IN NTSTATUS ExitStatus);
|
DbgkExitThread(
|
||||||
|
IN NTSTATUS ExitStatus
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
|
@ -28,6 +34,13 @@ DbgkForwardException(
|
||||||
IN BOOLEAN SecondChance
|
IN BOOLEAN SecondChance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
DbgkClearProcessDebugObject(
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN PDEBUG_OBJECT SourceDebugObject
|
||||||
|
);
|
||||||
|
|
||||||
extern POBJECT_TYPE DbgkDebugObjectType;
|
extern POBJECT_TYPE DbgkDebugObjectType;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -57,15 +57,15 @@
|
||||||
//
|
//
|
||||||
#define KeEnterCriticalRegion() \
|
#define KeEnterCriticalRegion() \
|
||||||
{ \
|
{ \
|
||||||
PKTHREAD Thread = KeGetCurrentThread(); \
|
PKTHREAD _Thread = KeGetCurrentThread(); \
|
||||||
\
|
\
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(Thread == KeGetCurrentThread()); \
|
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||||
ASSERT((Thread->KernelApcDisable <= 0) && \
|
ASSERT((_Thread->KernelApcDisable <= 0) && \
|
||||||
(Thread->KernelApcDisable != -32768)); \
|
(_Thread->KernelApcDisable != -32768)); \
|
||||||
\
|
\
|
||||||
/* Disable Kernel APCs */ \
|
/* Disable Kernel APCs */ \
|
||||||
Thread->KernelApcDisable--; \
|
_Thread->KernelApcDisable--; \
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -73,21 +73,21 @@
|
||||||
//
|
//
|
||||||
#define KeLeaveCriticalRegion() \
|
#define KeLeaveCriticalRegion() \
|
||||||
{ \
|
{ \
|
||||||
PKTHREAD Thread = KeGetCurrentThread(); \
|
PKTHREAD _Thread = KeGetCurrentThread(); \
|
||||||
\
|
\
|
||||||
/* Sanity checks */ \
|
/* Sanity checks */ \
|
||||||
ASSERT(Thread == KeGetCurrentThread()); \
|
ASSERT(_Thread == KeGetCurrentThread()); \
|
||||||
ASSERT(Thread->KernelApcDisable < 0); \
|
ASSERT(_Thread->KernelApcDisable < 0); \
|
||||||
\
|
\
|
||||||
/* Enable Kernel APCs */ \
|
/* Enable Kernel APCs */ \
|
||||||
Thread->KernelApcDisable++; \
|
_Thread->KernelApcDisable++; \
|
||||||
\
|
\
|
||||||
/* Check if Kernel APCs are now enabled */ \
|
/* Check if Kernel APCs are now enabled */ \
|
||||||
if (!(Thread->KernelApcDisable)) \
|
if (!(_Thread->KernelApcDisable)) \
|
||||||
{ \
|
{ \
|
||||||
/* Check if we need to request an APC Delivery */ \
|
/* Check if we need to request an APC Delivery */ \
|
||||||
if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) && \
|
if (!(IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) && \
|
||||||
!(Thread->KernelApcDisable)) \
|
!(_Thread->KernelApcDisable)) \
|
||||||
{ \
|
{ \
|
||||||
/* Check for the right environment */ \
|
/* Check for the right environment */ \
|
||||||
KiCheckForKernelApcDelivery(); \
|
KiCheckForKernelApcDelivery(); \
|
||||||
|
|
|
@ -238,6 +238,19 @@ ObClearProcessHandleTable(
|
||||||
IN PEPROCESS Process
|
IN PEPROCESS Process
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
ObDuplicateObject(
|
||||||
|
IN PEPROCESS SourceProcess,
|
||||||
|
IN HANDLE SourceHandle,
|
||||||
|
IN PEPROCESS TargetProcess OPTIONAL,
|
||||||
|
IN PHANDLE TargetHandle OPTIONAL,
|
||||||
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
IN ULONG HandleAttributes,
|
||||||
|
IN ULONG Options,
|
||||||
|
IN KPROCESSOR_MODE PreviousMode
|
||||||
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
// DOS Devices Functions
|
// DOS Devices Functions
|
||||||
//
|
//
|
||||||
|
|
|
@ -237,6 +237,13 @@ PspExitProcess(
|
||||||
IN PEPROCESS Process
|
IN PEPROCESS Process
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsTerminateProcess(
|
||||||
|
IN PEPROCESS Process,
|
||||||
|
IN NTSTATUS ExitStatus
|
||||||
|
);
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PspDeleteProcess(
|
PspDeleteProcess(
|
||||||
|
|
|
@ -118,6 +118,15 @@ PspTerminateProcess(IN PEPROCESS Process,
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NTSTATUS
|
||||||
|
NTAPI
|
||||||
|
PsTerminateProcess(IN PEPROCESS Process,
|
||||||
|
IN NTSTATUS ExitStatus)
|
||||||
|
{
|
||||||
|
/* Call the internal API */
|
||||||
|
return PspTerminateProcess(Process, ExitStatus);
|
||||||
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
PspShutdownProcessManager(VOID)
|
PspShutdownProcessManager(VOID)
|
||||||
|
@ -1116,7 +1125,8 @@ NtTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
|
||||||
/* Check for the DBG_TERMINATE_PROCESS exit code */
|
/* Check for the DBG_TERMINATE_PROCESS exit code */
|
||||||
if (ExitStatus == DBG_TERMINATE_PROCESS)
|
if (ExitStatus == DBG_TERMINATE_PROCESS)
|
||||||
{
|
{
|
||||||
/* FIXME: Disable debugging on this process */
|
/* Disable debugging on this process */
|
||||||
|
DbgkClearProcessDebugObject(Process, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Make sure that we got a handle */
|
/* Make sure that we got a handle */
|
||||||
|
|
|
@ -362,7 +362,7 @@ PspCreateProcess(OUT PHANDLE ProcessHandle,
|
||||||
HANDLE hProcess;
|
HANDLE hProcess;
|
||||||
PEPROCESS Process, Parent;
|
PEPROCESS Process, Parent;
|
||||||
PEPORT ExceptionPortObject;
|
PEPORT ExceptionPortObject;
|
||||||
PDBGK_DEBUG_OBJECT DebugObject;
|
PDEBUG_OBJECT DebugObject;
|
||||||
PSECTION_OBJECT SectionObject;
|
PSECTION_OBJECT SectionObject;
|
||||||
NTSTATUS Status, AccessStatus;
|
NTSTATUS Status, AccessStatus;
|
||||||
PHYSICAL_ADDRESS DirectoryTableBase = {{0}};
|
PHYSICAL_ADDRESS DirectoryTableBase = {{0}};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue