Author: ion Date: Fri Oct 20 00:08:52 2006 New Revision: 24574
URL: http://svn.reactos.org/svn/reactos?rev=24574&view=rev Log: - Fixup DEBUG_OBJECT definition. - Implement DbgkpCloseObject. - Implement DbgkpOpenHandles. - Fix various bugs in the code and flag usage. - Enable calling DbgkClearProcessDebugObject when terminating a process.
Modified: trunk/reactos/include/ndk/dbgktypes.h trunk/reactos/ntoskrnl/dbgk/debug.c trunk/reactos/ntoskrnl/include/internal/dbgk.h trunk/reactos/ntoskrnl/include/internal/ke_x.h trunk/reactos/ntoskrnl/include/internal/ob.h trunk/reactos/ntoskrnl/include/internal/ps.h trunk/reactos/ntoskrnl/ps/kill.c trunk/reactos/ntoskrnl/ps/process.c
Modified: trunk/reactos/include/ndk/dbgktypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/dbgktypes.h?rev... ============================================================================== --- trunk/reactos/include/ndk/dbgktypes.h (original) +++ trunk/reactos/include/ndk/dbgktypes.h Fri Oct 20 00:08:52 2006 @@ -55,11 +55,11 @@ // // Debug Object // -typedef struct _DBGK_DEBUG_OBJECT -{ - KEVENT Event; +typedef struct _DEBUG_OBJECT +{ + KEVENT EventsPresent; FAST_MUTEX Mutex; - LIST_ENTRY StateEventListEntry; + LIST_ENTRY EventList; union { ULONG Flags; @@ -69,7 +69,7 @@ UCHAR KillProcessOnExit:1; }; }; -} DBGK_DEBUG_OBJECT, *PDBGK_DEBUG_OBJECT; +} DEBUG_OBJECT, *PDEBUG_OBJECT;
#endif
Modified: trunk/reactos/ntoskrnl/dbgk/debug.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/dbgk/debug.c (original) +++ trunk/reactos/ntoskrnl/dbgk/debug.c Fri Oct 20 00:08:52 2006 @@ -14,7 +14,7 @@ #include <internal/debug.h>
POBJECT_TYPE DbgkDebugObjectType; -KGUARDED_MUTEX DbgkpProcessDebugPortMutex; +FAST_MUTEX DbgkpProcessDebugPortMutex;
GENERIC_MAPPING DbgkDebugObjectMapping = { @@ -28,25 +28,272 @@
VOID NTAPI +DbgkCopyProcessDebugPort(IN PEPROCESS Process, + IN PEPROCESS Parent) +{ + /* FIXME: Implement */ +} + +BOOLEAN +NTAPI +DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, + IN BOOLEAN DebugPort, + IN BOOLEAN SecondChance) +{ + /* FIXME: Implement */ + return FALSE; +} + +VOID +NTAPI +DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent) +{ + /* FIXME: TODO */ + return; +} + +NTSTATUS +NTAPI +DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process, + IN PDEBUG_OBJECT DebugObject, + IN PETHREAD *LastThread) +{ + /* FIXME: Implement */ + *LastThread = NULL; + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +DbgkpSetProcessDebugObject(IN PEPROCESS Process, + IN PDEBUG_OBJECT DebugObject, + IN NTSTATUS MsgStatus, + IN PETHREAD LastThread) +{ + /* FIXME: TODO */ + return STATUS_UNSUCCESSFUL; +} + +NTSTATUS +NTAPI +DbgkClearProcessDebugObject(IN PEPROCESS Process, + IN PDEBUG_OBJECT SourceDebugObject) +{ + /* FIXME: TODO */ + return STATUS_UNSUCCESSFUL; +} + +VOID +NTAPI +DbgkpConvertKernelToUserStateChange(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, + IN PDEBUG_EVENT DebugEvent) +{ + /* FIXME: TODO */ + return; +} + +VOID +NTAPI +DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, + IN PEPROCESS Process, + 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) { - PDBGK_DEBUG_OBJECT DebugObject = Object; + PDEBUG_OBJECT DebugObject = Object; PAGED_CODE();
/* Sanity check */ - ASSERT(IsListEmpty(&DebugObject->StateEventListEntry)); + ASSERT(IsListEmpty(&DebugObject->EventList)); }
VOID NTAPI -DbgkpCloseObject(IN PEPROCESS Process OPTIONAL, +DbgkpMarkProcessPeb(IN PEPROCESS Process) +{ + /* FIXME: TODO */ + return; +} + +VOID +NTAPI +DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL, IN PVOID ObjectBody, IN ACCESS_MASK GrantedAccess, IN ULONG HandleCount, IN ULONG SystemHandleCount) { - /* FIXME: Implement */ - ASSERT(FALSE); + 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 @@ -59,13 +306,13 @@ PAGED_CODE();
/* Initialize the process debug port mutex */ - KeInitializeGuardedMutex(&DbgkpProcessDebugPortMutex); - - /* Create the Event Pair Object Type */ + ExInitializeFastMutex(&DbgkpProcessDebugPortMutex); + + /* Create the Debug Object Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"DebugObject"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); - ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DBGK_DEBUG_OBJECT); + ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEBUG_OBJECT); ObjectTypeInitializer.GenericMapping = DbgkDebugObjectMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = DEBUG_OBJECT_WAIT_STATE_CHANGE; @@ -78,83 +325,6 @@ &DbgkDebugObjectType); }
-VOID -NTAPI -DbgkCopyProcessDebugPort(IN PEPROCESS Process, - IN PEPROCESS Parent) -{ - /* FIXME: Implement */ -} - -BOOLEAN -NTAPI -DbgkForwardException(IN PEXCEPTION_RECORD ExceptionRecord, - IN BOOLEAN DebugPort, - IN BOOLEAN SecondChance) -{ - /* FIXME: Implement */ - return FALSE; -} - -VOID -NTAPI -DbgkpWakeTarget(IN PDEBUG_EVENT DebugEvent) -{ - /* FIXME: TODO */ - return; -} - -NTSTATUS -NTAPI -DbgkpPostFakeProcessCreateMessages(IN PEPROCESS Process, - IN PDBGK_DEBUG_OBJECT DebugObject, - IN PETHREAD *LastThread) -{ - /* FIXME: Implement */ - *LastThread = NULL; - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -DbgkpSetProcessDebugObject(IN PEPROCESS Process, - IN PDBGK_DEBUG_OBJECT DebugObject, - IN NTSTATUS MsgStatus, - IN PETHREAD LastThread) -{ - /* FIXME: TODO */ - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -DbgkClearProcessDebugObject(IN PEPROCESS Process, - IN PDBGK_DEBUG_OBJECT SourceDebugObject) -{ - /* FIXME: TODO */ - return STATUS_UNSUCCESSFUL; -} - -VOID -NTAPI -DbgkpConvertKernelToUserStateChange(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, - IN PDEBUG_EVENT DebugEvent) -{ - /* FIXME: TODO */ - return; -} - -VOID -NTAPI -DbgkpOpenHandles(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, - IN PEPROCESS Process, - IN PETHREAD Thread) -{ - /* FIXME: TODO */ - return; -} - - /* PUBLIC FUNCTIONS **********************************************************/
NTSTATUS @@ -165,7 +335,7 @@ IN BOOLEAN KillProcessOnExit) { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; HANDLE hDebug; NTSTATUS Status = STATUS_SUCCESS; PAGED_CODE(); @@ -193,7 +363,7 @@ ObjectAttributes, PreviousMode, NULL, - sizeof(PDBGK_DEBUG_OBJECT), + sizeof(PDEBUG_OBJECT), 0, 0, (PVOID*)&DebugObject); @@ -203,10 +373,10 @@ ExInitializeFastMutex(&DebugObject->Mutex);
/* Initialize the State Event List */ - InitializeListHead(&DebugObject->StateEventListEntry); + InitializeListHead(&DebugObject->EventList);
/* Initialize the Debug Object's Wait Event */ - KeInitializeEvent(&DebugObject->Event, NotificationEvent, 0); + KeInitializeEvent(&DebugObject->EventsPresent, NotificationEvent, 0);
/* Set the Flags */ DebugObject->KillProcessOnExit = KillProcessOnExit; @@ -245,7 +415,7 @@ IN NTSTATUS ContinueStatus) { KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; NTSTATUS Status = STATUS_SUCCESS; PDEBUG_EVENT DebugEvent = NULL, DebugEventToWake = NULL; PLIST_ENTRY ListHead, NextEntry; @@ -296,7 +466,7 @@ ExAcquireFastMutex(&DebugObject->Mutex);
/* Loop the state list */ - ListHead = &DebugObject->StateEventListEntry; + ListHead = &DebugObject->EventList; NextEntry = ListHead->Flink; while (ListHead != NextEntry) { @@ -371,7 +541,7 @@ IN HANDLE DebugHandle) { PEPROCESS Process; - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); PETHREAD LastThread; NTSTATUS Status; @@ -435,7 +605,7 @@ IN HANDLE DebugHandle) { PEPROCESS Process; - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; KPROCESSOR_MODE PreviousMode = KeGetPreviousMode(); NTSTATUS Status;
@@ -487,7 +657,7 @@ IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL) { - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; KPROCESSOR_MODE PreviousMode = ExGetPreviousMode(); NTSTATUS Status = STATUS_SUCCESS; PDEBUG_OBJECT_KILL_PROCESS_ON_EXIT_INFORMATION DebugInfo = DebugInformation; @@ -522,12 +692,12 @@ if (DebugInfo->KillProcessOnExit) { /* Enable killing the process */ - DebugObject->Flags |= 2; + DebugObject->KillProcessOnExit = TRUE; } else { /* Disable */ - DebugObject->Flags &= ~2; + DebugObject->KillProcessOnExit = FALSE; }
/* Release the mutex */ @@ -555,7 +725,7 @@ PETHREAD Thread; BOOLEAN GotEvent; LARGE_INTEGER NewTime; - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; DBGUI_WAIT_STATE_CHANGE WaitStateChange; NTSTATUS Status = STATUS_SUCCESS; PDEBUG_EVENT DebugEvent, DebugEvent2; @@ -628,7 +798,7 @@ ExAcquireFastMutex(&DebugObject->Mutex);
/* Check if a debugger is connected */ - if (DebugObject->Flags & 1) + if (DebugObject->DebuggerInactive) { /* Not connected */ Status = STATUS_DEBUGGER_INACTIVE; @@ -636,7 +806,7 @@ else { /* Loop the events */ - ListHead = &DebugObject->StateEventListEntry; + ListHead = &DebugObject->EventList; NextEntry = ListHead->Flink; while (ListHead != NextEntry) { @@ -702,7 +872,7 @@ else { /* Unsignal the event */ - DebugObject->Event.Header.SignalState = 0; + DebugObject->EventsPresent.Header.SignalState = 0; Status = STATUS_SUCCESS; } }
Modified: trunk/reactos/ntoskrnl/include/internal/dbgk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/d... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/dbgk.h (original) +++ trunk/reactos/ntoskrnl/include/internal/dbgk.h Fri Oct 20 00:08:52 2006 @@ -3,15 +3,21 @@
VOID NTAPI -DbgkCreateThread(PVOID StartAddress); +DbgkCreateThread( + IN PVOID StartAddress +);
VOID NTAPI -DbgkExitProcess(IN NTSTATUS ExitStatus); +DbgkExitProcess( + IN NTSTATUS ExitStatus +);
VOID NTAPI -DbgkExitThread(IN NTSTATUS ExitStatus); +DbgkExitThread( + IN NTSTATUS ExitStatus +);
VOID NTAPI @@ -28,6 +34,13 @@ IN BOOLEAN SecondChance );
+NTSTATUS +NTAPI +DbgkClearProcessDebugObject( + IN PEPROCESS Process, + IN PDEBUG_OBJECT SourceDebugObject +); + extern POBJECT_TYPE DbgkDebugObjectType; #endif
Modified: trunk/reactos/ntoskrnl/include/internal/ke_x.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke_x.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ke_x.h Fri Oct 20 00:08:52 2006 @@ -57,15 +57,15 @@ // #define KeEnterCriticalRegion() \ { \ - PKTHREAD Thread = KeGetCurrentThread(); \ + PKTHREAD _Thread = KeGetCurrentThread(); \ \ /* Sanity checks */ \ - ASSERT(Thread == KeGetCurrentThread()); \ - ASSERT((Thread->KernelApcDisable <= 0) && \ - (Thread->KernelApcDisable != -32768)); \ + ASSERT(_Thread == KeGetCurrentThread()); \ + ASSERT((_Thread->KernelApcDisable <= 0) && \ + (_Thread->KernelApcDisable != -32768)); \ \ /* Disable Kernel APCs */ \ - Thread->KernelApcDisable--; \ + _Thread->KernelApcDisable--; \ }
// @@ -73,21 +73,21 @@ // #define KeLeaveCriticalRegion() \ { \ - PKTHREAD Thread = KeGetCurrentThread(); \ + PKTHREAD _Thread = KeGetCurrentThread(); \ \ /* Sanity checks */ \ - ASSERT(Thread == KeGetCurrentThread()); \ - ASSERT(Thread->KernelApcDisable < 0); \ + ASSERT(_Thread == KeGetCurrentThread()); \ + ASSERT(_Thread->KernelApcDisable < 0); \ \ /* Enable Kernel APCs */ \ - Thread->KernelApcDisable++; \ + _Thread->KernelApcDisable++; \ \ /* Check if Kernel APCs are now enabled */ \ - if (!(Thread->KernelApcDisable)) \ + if (!(_Thread->KernelApcDisable)) \ { \ /* Check if we need to request an APC Delivery */ \ - if (!(IsListEmpty(&Thread->ApcState.ApcListHead[KernelMode])) && \ - !(Thread->KernelApcDisable)) \ + if (!(IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) && \ + !(_Thread->KernelApcDisable)) \ { \ /* Check for the right environment */ \ KiCheckForKernelApcDelivery(); \
Modified: trunk/reactos/ntoskrnl/include/internal/ob.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/o... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ob.h Fri Oct 20 00:08:52 2006 @@ -238,6 +238,19 @@ 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 //
Modified: trunk/reactos/ntoskrnl/include/internal/ps.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/p... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ps.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ps.h Fri Oct 20 00:08:52 2006 @@ -235,6 +235,13 @@ PspExitProcess( IN BOOLEAN LastThread, IN PEPROCESS Process +); + +NTSTATUS +NTAPI +PsTerminateProcess( + IN PEPROCESS Process, + IN NTSTATUS ExitStatus );
VOID
Modified: trunk/reactos/ntoskrnl/ps/kill.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/kill.c?rev=2457... ============================================================================== --- trunk/reactos/ntoskrnl/ps/kill.c (original) +++ trunk/reactos/ntoskrnl/ps/kill.c Fri Oct 20 00:08:52 2006 @@ -116,6 +116,15 @@ /* Return success*/ PSREFTRACE(Process); return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +PsTerminateProcess(IN PEPROCESS Process, + IN NTSTATUS ExitStatus) +{ + /* Call the internal API */ + return PspTerminateProcess(Process, ExitStatus); }
VOID @@ -1116,7 +1125,8 @@ /* Check for the DBG_TERMINATE_PROCESS exit code */ 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 */
Modified: trunk/reactos/ntoskrnl/ps/process.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/process.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/ps/process.c (original) +++ trunk/reactos/ntoskrnl/ps/process.c Fri Oct 20 00:08:52 2006 @@ -362,7 +362,7 @@ HANDLE hProcess; PEPROCESS Process, Parent; PEPORT ExceptionPortObject; - PDBGK_DEBUG_OBJECT DebugObject; + PDEBUG_OBJECT DebugObject; PSECTION_OBJECT SectionObject; NTSTATUS Status, AccessStatus; PHYSICAL_ADDRESS DirectoryTableBase = {{0}};