mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 03:46:38 +00:00
- 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
This commit is contained in:
parent
7ed56310ad
commit
aced9b0023
2 changed files with 254 additions and 35 deletions
|
@ -78,7 +78,7 @@ DbgUiContinue(IN PCLIENT_ID ClientId,
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||||
IN LPDEBUG_EVENT DebugEvent)
|
OUT LPDEBUG_EVENT DebugEvent)
|
||||||
{
|
{
|
||||||
/* FIXME: UNIMPLEMENTED */
|
/* FIXME: UNIMPLEMENTED */
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
return STATUS_NOT_IMPLEMENTED;
|
||||||
|
|
|
@ -9,11 +9,250 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <k32.h>
|
#include <k32.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include "debug.h"
|
#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
|
* @implemented
|
||||||
|
@ -77,39 +316,13 @@ ContinueDebugEvent(IN DWORD dwProcessId,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Succes */
|
/* Remove the process/thread handles */
|
||||||
|
RemoveHandles(dwProcessId, dwThreadId);
|
||||||
|
|
||||||
|
/* Success */
|
||||||
return TRUE;
|
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
|
* @implemented
|
||||||
*/
|
*/
|
||||||
|
@ -134,6 +347,9 @@ DebugActiveProcess(IN DWORD dwProcessId)
|
||||||
|
|
||||||
/* Now debug the process */
|
/* Now debug the process */
|
||||||
Status = DbgUiDebugActiveProcess(Handle);
|
Status = DbgUiDebugActiveProcess(Handle);
|
||||||
|
NtClose(Handle);
|
||||||
|
|
||||||
|
/* Check if debugging worked */
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Fail */
|
/* Fail */
|
||||||
|
@ -159,6 +375,9 @@ DebugActiveProcessStop(IN DWORD dwProcessId)
|
||||||
Handle = ProcessIdToHandle(dwProcessId);
|
Handle = ProcessIdToHandle(dwProcessId);
|
||||||
if (!Handle) return FALSE;
|
if (!Handle) return FALSE;
|
||||||
|
|
||||||
|
/* Close all the process handles */
|
||||||
|
CloseAllProcessHandles(dwProcessId);
|
||||||
|
|
||||||
/* Now stop debgging the process */
|
/* Now stop debgging the process */
|
||||||
Status = DbgUiStopDebugging(Handle);
|
Status = DbgUiStopDebugging(Handle);
|
||||||
NtClose(Handle);
|
NtClose(Handle);
|
||||||
|
@ -240,7 +459,7 @@ DebugSetProcessKillOnExit(IN BOOL KillOnExit)
|
||||||
*/
|
*/
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
IsDebuggerPresent (VOID)
|
IsDebuggerPresent(VOID)
|
||||||
{
|
{
|
||||||
return (BOOL)NtCurrentPeb()->BeingDebugged;
|
return (BOOL)NtCurrentPeb()->BeingDebugged;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +470,7 @@ IsDebuggerPresent (VOID)
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
|
WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
|
||||||
DWORD dwMilliseconds)
|
IN DWORD dwMilliseconds)
|
||||||
{
|
{
|
||||||
/* FIXME: TODO */
|
/* FIXME: TODO */
|
||||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue