mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 18:45:46 +00:00
[KERNEL32]: User-mode Debugging fixes.
Bug: RemoveHandles was checking for process AND thread handle match, instead of OR. Bug: CloseAllProcessHandles and RemoveHandles's processing loop was buggy with its unlinking and re-use of nested ThreadData. Bug: ProcessIdToHandle was requesting more process rights than needed. Bug: Some ULONG<->BOOL conversions were dirty (as in, could result in values of 2 or higher). Bug: In WaitForDebugEvent, During CREATE_PROCESS_DEBUG_EVENT, the wrong handle was saved as the thread handle. Bug: In WaitForDebugEvent, all events returned TRUE. Instead, only valid events should return TRUE, and non-existing events should return FALSE. Add some asserts. Simplify MarkThreadHandle and MarkProcessHandle. Simplify OutputDebugStringW. svn path=/trunk/; revision=52813
This commit is contained in:
parent
3459e1cb1d
commit
90e2e1bad0
1 changed files with 74 additions and 105 deletions
|
@ -264,8 +264,7 @@ MarkThreadHandle(IN DWORD dwThreadId)
|
|||
PDBGSS_THREAD_DATA ThreadData;
|
||||
|
||||
/* Loop all thread data events */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
while (ThreadData)
|
||||
for (ThreadData = DbgSsGetThreadData(); ThreadData; ThreadData = ThreadData->Next)
|
||||
{
|
||||
/* Check if this one matches */
|
||||
if (ThreadData->ThreadId == dwThreadId)
|
||||
|
@ -274,9 +273,6 @@ MarkThreadHandle(IN DWORD dwThreadId)
|
|||
ThreadData->HandleMarked = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to the next one */
|
||||
ThreadData = ThreadData->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,23 +283,15 @@ MarkProcessHandle(IN DWORD dwProcessId)
|
|||
PDBGSS_THREAD_DATA ThreadData;
|
||||
|
||||
/* Loop all thread data events */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
while (ThreadData)
|
||||
for (ThreadData = DbgSsGetThreadData(); ThreadData; ThreadData = ThreadData->Next)
|
||||
{
|
||||
/* Check if this one matches */
|
||||
if (ThreadData->ProcessId == dwProcessId)
|
||||
if ((ThreadData->ProcessId == dwProcessId) && !(ThreadData->ThreadId))
|
||||
{
|
||||
/* Make sure the thread ID is empty */
|
||||
if (!ThreadData->ThreadId)
|
||||
{
|
||||
/* Mark the structure and break out */
|
||||
ThreadData->HandleMarked = TRUE;
|
||||
break;
|
||||
}
|
||||
/* Mark the structure and break out */
|
||||
ThreadData->HandleMarked = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Move to the next one */
|
||||
ThreadData = ThreadData->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,46 +300,31 @@ WINAPI
|
|||
RemoveHandles(IN DWORD dwProcessId,
|
||||
IN DWORD dwThreadId)
|
||||
{
|
||||
PDBGSS_THREAD_DATA ThreadData;
|
||||
PDBGSS_THREAD_DATA ThreadData, ThisData;
|
||||
|
||||
/* Loop all thread data events */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
while (ThreadData)
|
||||
for (ThisData = ThreadData; ThisData; ThisData = ThisData->Next)
|
||||
{
|
||||
/* Check if this one matches */
|
||||
if (ThreadData->ProcessId == dwProcessId)
|
||||
if ((ThisData->HandleMarked) &&
|
||||
((ThisData->ProcessId == dwProcessId) || (ThisData->ThreadId == dwThreadId)))
|
||||
{
|
||||
/* 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);
|
||||
}
|
||||
/* Close open handles */
|
||||
if (ThisData->ThreadHandle) CloseHandle(ThisData->ThreadHandle);
|
||||
if (ThisData->ProcessHandle) CloseHandle(ThisData->ProcessHandle);
|
||||
|
||||
/* Check if we have a process handle */
|
||||
if (ThreadData->ProcessHandle)
|
||||
{
|
||||
/* Close it */
|
||||
CloseHandle(ThreadData->ProcessHandle);
|
||||
}
|
||||
/* Unlink the thread data */
|
||||
ThreadData->Next = ThisData->Next;
|
||||
|
||||
/* Unlink the thread data */
|
||||
DbgSsSetThreadData(ThreadData->Next);
|
||||
|
||||
/* Free it*/
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ThreadData);
|
||||
|
||||
/* Move to the next structure */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
continue;
|
||||
}
|
||||
/* Free it*/
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ThisData);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move to the next one */
|
||||
ThreadData = ThisData;
|
||||
}
|
||||
|
||||
/* Move to the next one */
|
||||
ThreadData = ThreadData->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -359,42 +332,30 @@ VOID
|
|||
WINAPI
|
||||
CloseAllProcessHandles(IN DWORD dwProcessId)
|
||||
{
|
||||
PDBGSS_THREAD_DATA ThreadData;
|
||||
PDBGSS_THREAD_DATA ThreadData, ThisData;
|
||||
|
||||
/* Loop all thread data events */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
while (ThreadData)
|
||||
for (ThisData = ThreadData; ThisData; ThisData = ThisData->Next)
|
||||
{
|
||||
/* Check if this one matches */
|
||||
if (ThreadData->ProcessId == dwProcessId)
|
||||
if (ThisData->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);
|
||||
}
|
||||
/* Close open handles */
|
||||
if (ThisData->ThreadHandle) CloseHandle(ThisData->ThreadHandle);
|
||||
if (ThisData->ProcessHandle) CloseHandle(ThisData->ProcessHandle);
|
||||
|
||||
/* Unlink the thread data */
|
||||
DbgSsSetThreadData(ThreadData->Next);
|
||||
ThreadData->Next = ThisData->Next;
|
||||
|
||||
/* Free it*/
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ThreadData);
|
||||
|
||||
/* Move to the next structure */
|
||||
ThreadData = DbgSsGetThreadData();
|
||||
continue;
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ThisData);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Move to the next one */
|
||||
ThreadData = ThisData;
|
||||
}
|
||||
|
||||
/* Move to the next one */
|
||||
ThreadData = ThreadData->Next;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,7 +376,9 @@ ProcessIdToHandle(IN DWORD dwProcessId)
|
|||
ClientId.UniqueProcess = UlongToHandle(dwProcessId);
|
||||
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
||||
Status = NtOpenProcess(&Handle,
|
||||
PROCESS_ALL_ACCESS,
|
||||
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
|
||||
PROCESS_VM_WRITE | PROCESS_VM_READ |
|
||||
PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION,
|
||||
&ObjectAttributes,
|
||||
&ClientId);
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -459,7 +422,7 @@ CheckRemoteDebuggerPresent(IN HANDLE hProcess,
|
|||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Return the current state */
|
||||
*pbDebuggerPresent = (DebugPort) ? TRUE : FALSE;
|
||||
*pbDebuggerPresent = DebugPort != NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -507,7 +470,7 @@ BOOL
|
|||
WINAPI
|
||||
DebugActiveProcess(IN DWORD dwProcessId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status, Status1;
|
||||
HANDLE Handle;
|
||||
|
||||
/* Connect to the debugger */
|
||||
|
@ -524,7 +487,10 @@ DebugActiveProcess(IN DWORD dwProcessId)
|
|||
|
||||
/* Now debug the process */
|
||||
Status = DbgUiDebugActiveProcess(Handle);
|
||||
NtClose(Handle);
|
||||
|
||||
/* Close the handle since we're done */
|
||||
Status1 = NtClose(Handle);
|
||||
ASSERT(NT_SUCCESS(Status1));
|
||||
|
||||
/* Check if debugging worked */
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -545,7 +511,7 @@ BOOL
|
|||
WINAPI
|
||||
DebugActiveProcessStop(IN DWORD dwProcessId)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
NTSTATUS Status, Status1;
|
||||
HANDLE Handle;
|
||||
|
||||
/* Get the process handle */
|
||||
|
@ -557,7 +523,8 @@ DebugActiveProcessStop(IN DWORD dwProcessId)
|
|||
|
||||
/* Now stop debgging the process */
|
||||
Status = DbgUiStopDebugging(Handle);
|
||||
NtClose(Handle);
|
||||
Status1 = NtClose(Handle);
|
||||
ASSERT(NT_SUCCESS(Status1));
|
||||
|
||||
/* Check for failure */
|
||||
if (!NT_SUCCESS(Status))
|
||||
|
@ -614,7 +581,7 @@ DebugSetProcessKillOnExit(IN BOOL KillOnExit)
|
|||
}
|
||||
|
||||
/* Now set the kill-on-exit state */
|
||||
State = KillOnExit;
|
||||
State = KillOnExit != 0;
|
||||
Status = NtSetInformationDebugObject(Handle,
|
||||
DebugObjectKillProcessOnExitInformation,
|
||||
&State,
|
||||
|
@ -711,15 +678,14 @@ WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
|
|||
/* Setup the thread data */
|
||||
SaveThreadHandle(lpDebugEvent->dwProcessId,
|
||||
lpDebugEvent->dwThreadId,
|
||||
lpDebugEvent->u.CreateThread.hThread);
|
||||
lpDebugEvent->u.CreateProcessInfo.hThread);
|
||||
break;
|
||||
|
||||
/* Process was exited */
|
||||
case EXIT_PROCESS_DEBUG_EVENT:
|
||||
|
||||
/* Mark the thread data as such */
|
||||
/* Mark the thread data as such and fall through */
|
||||
MarkProcessHandle(lpDebugEvent->dwProcessId);
|
||||
break;
|
||||
|
||||
/* Thread was exited */
|
||||
case EXIT_THREAD_DEBUG_EVENT:
|
||||
|
@ -727,10 +693,18 @@ WaitForDebugEvent(IN LPDEBUG_EVENT lpDebugEvent,
|
|||
/* Mark the thread data */
|
||||
MarkThreadHandle(lpDebugEvent->dwThreadId);
|
||||
break;
|
||||
|
||||
/* Nothing to do for anything else */
|
||||
default:
|
||||
|
||||
/* Nothing to do */
|
||||
case EXCEPTION_DEBUG_EVENT:
|
||||
case LOAD_DLL_DEBUG_EVENT:
|
||||
case UNLOAD_DLL_DEBUG_EVENT:
|
||||
case OUTPUT_DEBUG_STRING_EVENT:
|
||||
case RIP_EVENT:
|
||||
break;
|
||||
|
||||
/* Fail anything else */
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Return success */
|
||||
|
@ -957,29 +931,24 @@ OutputDebugStringA(IN LPCSTR _OutputString)
|
|||
*/
|
||||
VOID
|
||||
WINAPI
|
||||
OutputDebugStringW(IN LPCWSTR _OutputString)
|
||||
OutputDebugStringW(IN LPCWSTR OutputString)
|
||||
{
|
||||
UNICODE_STRING wstrOut;
|
||||
ANSI_STRING strOut;
|
||||
NTSTATUS nErrCode;
|
||||
UNICODE_STRING UnicodeString;
|
||||
ANSI_STRING AnsiString;
|
||||
NTSTATUS Status;
|
||||
|
||||
/* convert the string in ANSI */
|
||||
RtlInitUnicodeString(&wstrOut, _OutputString);
|
||||
nErrCode = RtlUnicodeStringToAnsiString(&strOut, &wstrOut, TRUE);
|
||||
RtlInitUnicodeString(&UnicodeString, OutputString);
|
||||
Status = RtlUnicodeStringToAnsiString(&AnsiString, &UnicodeString, TRUE);
|
||||
|
||||
if(!NT_SUCCESS(nErrCode))
|
||||
{
|
||||
/* Microsoft's kernel32.dll always prints something, even in case the conversion fails */
|
||||
OutputDebugStringA("");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* output the converted string */
|
||||
OutputDebugStringA(strOut.Buffer);
|
||||
/* OutputDebugStringW always prints something, even if conversion fails */
|
||||
if (!NT_SUCCESS(Status)) AnsiString.Buffer = "";
|
||||
|
||||
/* free the converted string */
|
||||
RtlFreeAnsiString(&strOut);
|
||||
}
|
||||
/* Output the converted string */
|
||||
OutputDebugStringA(AnsiString.Buffer);
|
||||
|
||||
/* free the converted string */
|
||||
if (NT_SUCCESS(Status)) RtlFreeAnsiString(&AnsiString);
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue