- 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:
Alex Ionescu 2006-10-22 23:28:33 +00:00
parent 7ed56310ad
commit aced9b0023
2 changed files with 254 additions and 35 deletions

View file

@ -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;

View file

@ -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);