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
|
||||
NTAPI
|
||||
DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
|
||||
IN LPDEBUG_EVENT DebugEvent)
|
||||
OUT LPDEBUG_EVENT DebugEvent)
|
||||
{
|
||||
/* FIXME: UNIMPLEMENTED */
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
|
|
|
@ -9,11 +9,250 @@
|
|||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <k32.h>
|
||||
|
||||
#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);
|
||||
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue