From aced9b00235c12a0f9ff51fed53b17e47741d282 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 22 Oct 2006 23:28:33 +0000 Subject: [PATCH] - Define DBGSS_THREAD_DATA and DbgSsGet/SetThreadData. This is what is located in DbgSsReserved[0] (an internal high-level structure that subsystem debuggers can use for whatever purposes they need). DbgSsReserved[1] is the actual native debug object used only by DbgUi in ntdll. - Implement SaveThreadHandle, SaveProcesHandle, MarkThreadHandle, MarkProcessHandle, RemoveHandles and CloseAllProcessHandles to deal with this structure. - Call these functions when required, except for WaitForDebugEvent which will set them up once implemented. svn path=/trunk/; revision=24617 --- reactos/dll/ntdll/dbg/dbgui.c | 2 +- reactos/dll/win32/kernel32/debug/debugger.c | 287 +++++++++++++++++--- 2 files changed, 254 insertions(+), 35 deletions(-) diff --git a/reactos/dll/ntdll/dbg/dbgui.c b/reactos/dll/ntdll/dbg/dbgui.c index 8ec73c4cd6d..f61210e3db1 100644 --- a/reactos/dll/ntdll/dbg/dbgui.c +++ b/reactos/dll/ntdll/dbg/dbgui.c @@ -78,7 +78,7 @@ DbgUiContinue(IN PCLIENT_ID ClientId, NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, - IN LPDEBUG_EVENT DebugEvent) + OUT LPDEBUG_EVENT DebugEvent) { /* FIXME: UNIMPLEMENTED */ return STATUS_NOT_IMPLEMENTED; diff --git a/reactos/dll/win32/kernel32/debug/debugger.c b/reactos/dll/win32/kernel32/debug/debugger.c index 4a9688b8d2f..9ec67d152b8 100644 --- a/reactos/dll/win32/kernel32/debug/debugger.c +++ b/reactos/dll/win32/kernel32/debug/debugger.c @@ -9,11 +9,250 @@ /* INCLUDES *****************************************************************/ #include - #define NDEBUG #include "debug.h" -/* FUNCTIONS *****************************************************************/ +typedef struct _DBGSS_THREAD_DATA +{ + struct _DBGSS_THREAD_DATA *Next; + HANDLE ThreadHandle; + HANDLE ProcessHandle; + DWORD ProcessId; + DWORD ThreadId; + BOOLEAN HandleMarked; +} DBGSS_THREAD_DATA, *PDBGSS_THREAD_DATA; + +#define DbgSsSetThreadData(d) \ + NtCurrentTeb()->DbgSsReserved[0] = d + +#define DbgSsGetThreadData() \ + ((PDBGSS_THREAD_DATA)NtCurrentTeb()->DbgSsReserved[0]) + +/* PRIVATE FUNCTIONS *********************************************************/ + +VOID +WINAPI +SaveThreadHandle(IN DWORD dwProcessId, + IN DWORD dwThreadId, + IN HANDLE hThread) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Allocate a thread structure */ + ThreadData = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + sizeof(DBGSS_THREAD_DATA)); + if (!ThreadData) return; + + /* Fill it out */ + ThreadData->ThreadHandle = hThread; + ThreadData->ProcessId = dwProcessId; + ThreadData->ThreadId = dwThreadId; + ThreadData->ProcessHandle = NULL; + ThreadData->HandleMarked = FALSE; + + /* Link it */ + ThreadData->Next = DbgSsGetThreadData(); + DbgSsSetThreadData(ThreadData); +} + +VOID +WINAPI +SaveProcessHandle(IN DWORD dwProcessId, + IN HANDLE hProcess) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Allocate a thread structure */ + ThreadData = RtlAllocateHeap(RtlGetProcessHeap(), + 0, + sizeof(DBGSS_THREAD_DATA)); + if (!ThreadData) return; + + /* Fill it out */ + ThreadData->ProcessHandle = hProcess; + ThreadData->ProcessId = dwProcessId; + ThreadData->ThreadId = 0; + ThreadData->ThreadHandle = NULL; + ThreadData->HandleMarked = FALSE; + + /* Link it */ + ThreadData->Next = DbgSsGetThreadData(); + DbgSsSetThreadData(ThreadData); +} + +VOID +WINAPI +MarkThreadHandle(IN DWORD dwThreadId) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Loop all thread data events */ + ThreadData = DbgSsGetThreadData(); + while (ThreadData) + { + /* Check if this one matches */ + if (ThreadData->ThreadId == dwThreadId) + { + /* Mark the structure and break out */ + ThreadData->HandleMarked = TRUE; + break; + } + + /* Move to the next one */ + ThreadData = ThreadData->Next; + } +} + +VOID +WINAPI +MarkProcessHandle(IN DWORD dwProcessId) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Loop all thread data events */ + ThreadData = DbgSsGetThreadData(); + while (ThreadData) + { + /* Check if this one matches */ + if (ThreadData->ProcessId == dwProcessId) + { + /* Make sure the thread ID is empty */ + if (!ThreadData->ThreadId) + { + /* Mark the structure and break out */ + ThreadData->HandleMarked = TRUE; + break; + } + } + + /* Move to the next one */ + ThreadData = ThreadData->Next; + } +} + +VOID +WINAPI +RemoveHandles(IN DWORD dwProcessId, + IN DWORD dwThreadId) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Loop all thread data events */ + ThreadData = DbgSsGetThreadData(); + while (ThreadData) + { + /* Check if this one matches */ + if (ThreadData->ProcessId == dwProcessId) + { + /* Make sure the thread ID matches too */ + if (ThreadData->ThreadId == dwThreadId) + { + /* Check if we have a thread handle */ + if (ThreadData->ThreadHandle) + { + /* Close it */ + CloseHandle(ThreadData->ThreadHandle); + } + + /* Check if we have a process handle */ + if (ThreadData->ProcessHandle) + { + /* Close it */ + CloseHandle(ThreadData->ProcessHandle); + } + + /* Unlink the thread data */ + DbgSsSetThreadData(ThreadData->Next); + + /* Free it*/ + RtlFreeHeap(RtlGetProcessHeap(), 0, ThreadData); + + /* Move to the next structure */ + ThreadData = DbgSsGetThreadData(); + continue; + } + } + + /* Move to the next one */ + ThreadData = ThreadData->Next; + } +} + +VOID +WINAPI +CloseAllProcessHandles(IN DWORD dwProcessId) +{ + PDBGSS_THREAD_DATA ThreadData; + + /* Loop all thread data events */ + ThreadData = DbgSsGetThreadData(); + while (ThreadData) + { + /* Check if this one matches */ + if (ThreadData->ProcessId == dwProcessId) + { + /* Check if we have a thread handle */ + if (ThreadData->ThreadHandle) + { + /* Close it */ + CloseHandle(ThreadData->ThreadHandle); + } + + /* Check if we have a process handle */ + if (ThreadData->ProcessHandle) + { + /* Close it */ + CloseHandle(ThreadData->ProcessHandle); + } + + /* Unlink the thread data */ + DbgSsSetThreadData(ThreadData->Next); + + /* Free it*/ + RtlFreeHeap(RtlGetProcessHeap(), 0, ThreadData); + + /* Move to the next structure */ + ThreadData = DbgSsGetThreadData(); + continue; + } + + /* Move to the next one */ + ThreadData = ThreadData->Next; + } +} + +HANDLE +WINAPI +ProcessIdToHandle(IN DWORD dwProcessId) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + CLIENT_ID ClientId; + + /* If we don't have a PID, look it up */ + if (dwProcessId == -1) dwProcessId = (DWORD)CsrGetProcessId(); + + /* Open a handle to the process */ + ClientId.UniqueProcess = (HANDLE)dwProcessId; + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + Status = NtOpenProcess(&Handle, + PROCESS_ALL_ACCESS, + &ObjectAttributes, + &ClientId); + if (!NT_SUCCESS(Status)) + { + /* Fail */ + SetLastErrorByStatus(Status); + return 0; + } + + /* Return the handle */ + return Handle; +} + +/* PUBLIC FUNCTIONS **********************************************************/ /* * @implemented @@ -77,39 +316,13 @@ ContinueDebugEvent(IN DWORD dwProcessId, return FALSE; } - /* Succes */ + /* Remove the process/thread handles */ + RemoveHandles(dwProcessId, dwThreadId); + + /* Success */ return TRUE; } -HANDLE -ProcessIdToHandle(IN DWORD dwProcessId) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE Handle; - CLIENT_ID ClientId; - - /* If we don't have a PID, look it up */ - if (dwProcessId == 0xFFFFFFFF) dwProcessId = (DWORD)CsrGetProcessId(); - - /* Open a handle to the process */ - ClientId.UniqueProcess = (HANDLE)dwProcessId; - InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); - Status = NtOpenProcess(&Handle, - PROCESS_ALL_ACCESS, - &ObjectAttributes, - &ClientId); - if (!NT_SUCCESS(Status)) - { - /* Fail */ - SetLastErrorByStatus(Status); - return 0; - } - - /* Return the handle */ - return Handle; -} - /* * @implemented */ @@ -134,6 +347,9 @@ DebugActiveProcess(IN DWORD dwProcessId) /* Now debug the process */ Status = DbgUiDebugActiveProcess(Handle); + NtClose(Handle); + + /* Check if debugging worked */ if (!NT_SUCCESS(Status)) { /* Fail */ @@ -159,6 +375,9 @@ DebugActiveProcessStop(IN DWORD dwProcessId) Handle = ProcessIdToHandle(dwProcessId); if (!Handle) return FALSE; + /* Close all the process handles */ + CloseAllProcessHandles(dwProcessId); + /* Now stop debgging the process */ Status = DbgUiStopDebugging(Handle); NtClose(Handle); @@ -240,7 +459,7 @@ DebugSetProcessKillOnExit(IN BOOL KillOnExit) */ BOOL WINAPI -IsDebuggerPresent (VOID) +IsDebuggerPresent(VOID) { return (BOOL)NtCurrentPeb()->BeingDebugged; } @@ -251,7 +470,7 @@ IsDebuggerPresent (VOID) BOOL WINAPI WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent, - DWORD dwMilliseconds) + IN DWORD dwMilliseconds) { /* FIXME: TODO */ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);