Author: ion Date: Mon Oct 23 09:08:19 2006 New Revision: 24619
URL: http://svn.reactos.org/svn/reactos?rev=24619&view=rev Log: - Implement DbgUiConvertStateChangeStructure. Win32/Native Debugging should be fully implemented now (and waiting on the kernel to support it.)
Modified: trunk/reactos/dll/ntdll/dbg/dbgui.c
Modified: trunk/reactos/dll/ntdll/dbg/dbgui.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/dbg/dbgui.c?rev=2... ============================================================================== --- trunk/reactos/dll/ntdll/dbg/dbgui.c (original) +++ trunk/reactos/dll/ntdll/dbg/dbgui.c Mon Oct 23 09:08:19 2006 @@ -73,15 +73,240 @@ }
/* - * @unimplemented + * @implemented */ NTSTATUS NTAPI DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange, OUT LPDEBUG_EVENT DebugEvent) { - /* FIXME: UNIMPLEMENTED */ - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + THREAD_BASIC_INFORMATION ThreadBasicInfo; + HANDLE ThreadHandle; + + /* Write common data */ + DebugEvent->dwProcessId = (DWORD)WaitStateChange-> + AppClientId.UniqueProcess; + DebugEvent->dwThreadId = (DWORD)WaitStateChange->AppClientId.UniqueThread; + + /* Check what kind of even this is */ + switch (WaitStateChange->NewState) + { + /* New thread */ + case DbgCreateThreadStateChange: + + /* Setup Win32 code */ + DebugEvent->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT; + + /* Copy data over */ + DebugEvent->u.CreateThread.hThread = + WaitStateChange->StateInfo.CreateThread.HandleToThread; + DebugEvent->u.CreateThread.lpStartAddress = + WaitStateChange->StateInfo.CreateThread.NewThread.StartAddress; + + /* Query the TEB */ + Status = NtQueryInformationThread(WaitStateChange->StateInfo. + CreateThread.HandleToThread, + ThreadBasicInformation, + &ThreadBasicInfo, + sizeof(ThreadBasicInfo), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed to get PEB address */ + DebugEvent->u.CreateThread.lpThreadLocalBase = NULL; + } + else + { + /* Write PEB Address */ + DebugEvent->u.CreateThread.lpThreadLocalBase = + ThreadBasicInfo.TebBaseAddress; + } + break; + + /* New process */ + case DbgCreateProcessStateChange: + + /* Write Win32 debug code */ + DebugEvent->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT; + + /* Copy data over */ + DebugEvent->u.CreateProcessInfo.hProcess = + WaitStateChange->StateInfo.CreateProcessInfo.HandleToProcess; + DebugEvent->u.CreateProcessInfo.hThread = + WaitStateChange->StateInfo.CreateProcessInfo.HandleToThread; + DebugEvent->u.CreateProcessInfo.hFile = + WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. + FileHandle; + DebugEvent->u.CreateProcessInfo.lpBaseOfImage = + WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. + BaseOfImage; + DebugEvent->u.CreateProcessInfo.dwDebugInfoFileOffset = + WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. + DebugInfoFileOffset; + DebugEvent->u.CreateProcessInfo.nDebugInfoSize = + WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. + DebugInfoSize; + DebugEvent->u.CreateProcessInfo.lpStartAddress = + WaitStateChange->StateInfo.CreateProcessInfo.NewProcess. + InitialThread.StartAddress; + + /* Query TEB address */ + Status = NtQueryInformationThread(WaitStateChange->StateInfo. + CreateProcessInfo.HandleToThread, + ThreadBasicInformation, + &ThreadBasicInfo, + sizeof(ThreadBasicInfo), + NULL); + if (!NT_SUCCESS(Status)) + { + /* Failed to get PEB address */ + DebugEvent->u.CreateThread.lpThreadLocalBase = NULL; + } + else + { + /* Write PEB Address */ + DebugEvent->u.CreateThread.lpThreadLocalBase = + ThreadBasicInfo.TebBaseAddress; + } + + /* Clear image name */ + DebugEvent->u.CreateProcessInfo.lpImageName = NULL; + DebugEvent->u.CreateProcessInfo.fUnicode = TRUE; + break; + + /* Thread exited */ + case DbgExitThreadStateChange: + + /* Write the Win32 debug code and the exit status */ + DebugEvent->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT; + DebugEvent->u.ExitThread.dwExitCode = + WaitStateChange->StateInfo.ExitThread.ExitStatus; + break; + + /* Process exited */ + case DbgExitProcessStateChange: + + /* Write the Win32 debug code and the exit status */ + DebugEvent->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT; + DebugEvent->u.ExitProcess.dwExitCode = + WaitStateChange->StateInfo.ExitProcess.ExitStatus; + break; + + /* Any sort of exception */ + case DbgExceptionStateChange: + case DbgBreakpointStateChange: + case DbgSingleStepStateChange: + + /* Check if this was a debug print */ + if (WaitStateChange->StateInfo.Exception.ExceptionRecord. + ExceptionCode == DBG_PRINTEXCEPTION_C) + { + /* Set the Win32 code */ + DebugEvent->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT; + + /* Copy debug string information */ + DebugEvent->u.DebugString.lpDebugStringData = + (PVOID)WaitStateChange-> + StateInfo.Exception.ExceptionRecord. + ExceptionInformation[1]; + DebugEvent->u.DebugString.nDebugStringLength = + WaitStateChange->StateInfo.Exception.ExceptionRecord. + ExceptionInformation[0]; + DebugEvent->u.DebugString.fUnicode = FALSE; + } + else if (WaitStateChange->StateInfo.Exception.ExceptionRecord. + ExceptionCode == DBG_RIPEXCEPTION) + { + /* Set the Win32 code */ + DebugEvent->dwDebugEventCode = RIP_EVENT; + + /* Set exception information */ + DebugEvent->u.RipInfo.dwType = + WaitStateChange->StateInfo.Exception.ExceptionRecord. + ExceptionInformation[1]; + DebugEvent->u.RipInfo.dwError = + WaitStateChange->StateInfo.Exception.ExceptionRecord. + ExceptionInformation[0]; + } + else + { + /* Otherwise, this is a debug event, copy info over */ + DebugEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT; + DebugEvent->u.Exception.ExceptionRecord = + WaitStateChange->StateInfo.Exception.ExceptionRecord; + DebugEvent->u.Exception.dwFirstChance = + WaitStateChange->StateInfo.Exception.FirstChance; + } + break; + + /* DLL Load */ + case DbgLoadDllStateChange : + + /* Set the Win32 debug code */ + DebugEvent->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT; + + /* Copy the rest of the data */ + DebugEvent->u.LoadDll.lpBaseOfDll = + WaitStateChange->StateInfo.LoadDll.BaseOfDll; + DebugEvent->u.LoadDll.hFile = + WaitStateChange->StateInfo.LoadDll.FileHandle; + DebugEvent->u.LoadDll.dwDebugInfoFileOffset = + WaitStateChange->StateInfo.LoadDll.DebugInfoFileOffset; + DebugEvent->u.LoadDll.nDebugInfoSize = + WaitStateChange->StateInfo.LoadDll.DebugInfoSize; + + /* Open the thread */ + InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL); + Status = NtOpenThread(&ThreadHandle, + THREAD_QUERY_INFORMATION, + &ObjectAttributes, + &WaitStateChange->AppClientId); + if (NT_SUCCESS(Status)) + { + /* Query thread information */ + Status = NtQueryInformationThread(ThreadHandle, + ThreadBasicInformation, + &ThreadBasicInfo, + sizeof(ThreadBasicInfo), + NULL); + NtClose(ThreadHandle); + } + + /* Check if we got thread information */ + if (NT_SUCCESS(Status)) + { + /* Save the image name from the TIB */ + DebugEvent->u.LoadDll.lpImageName = + &((PTEB)ThreadBasicInfo.TebBaseAddress)-> + Tib.ArbitraryUserPointer; + } + else + { + /* Otherwise, no name */ + DebugEvent->u.LoadDll.lpImageName = NULL; + } + + /* It's Unicode */ + DebugEvent->u.LoadDll.fUnicode = TRUE; + break; + + /* DLL Unload */ + case DbgUnloadDllStateChange: + + /* Set Win32 code and DLL Base */ + DebugEvent->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT; + DebugEvent->u.UnloadDll.lpBaseOfDll = + WaitStateChange->StateInfo.UnloadDll.BaseAddress; + break; + + /* Anything else, fail */ + default: return STATUS_UNSUCCESSFUL; + } + + /* Return success */ + return STATUS_SUCCESS; }
/*