ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

dbgui.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS NT Layer/System API
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            dll/ntdll/dbg/dbgui.c
00005  * PURPOSE:         Native Wrappers for the NT Debug Implementation
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include <ntdll.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* FUNCTIONS *****************************************************************/
00016 
00017 /*
00018  * @implemented
00019  */
00020 NTSTATUS
00021 NTAPI
00022 DbgUiConnectToDbg(VOID)
00023 {
00024     OBJECT_ATTRIBUTES ObjectAttributes;
00025 
00026     /* Don't connect twice */
00027     if (NtCurrentTeb()->DbgSsReserved[1]) return STATUS_SUCCESS;
00028 
00029     /* Setup the Attributes */
00030     InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, 0);
00031 
00032     /* Create the object */
00033     return ZwCreateDebugObject(&NtCurrentTeb()->DbgSsReserved[1],
00034                                DEBUG_OBJECT_ALL_ACCESS,
00035                                &ObjectAttributes,
00036                                DBGK_KILL_PROCESS_ON_EXIT);
00037 }
00038 
00039 /*
00040  * @implemented
00041  */
00042 NTSTATUS
00043 NTAPI
00044 DbgUiContinue(IN PCLIENT_ID ClientId,
00045               IN NTSTATUS ContinueStatus)
00046 {
00047     /* Tell the kernel object to continue */
00048     return ZwDebugContinue(NtCurrentTeb()->DbgSsReserved[1],
00049                            ClientId,
00050                            ContinueStatus);
00051 }
00052 
00053 /*
00054  * @implemented
00055  */
00056 NTSTATUS
00057 NTAPI
00058 DbgUiConvertStateChangeStructure(IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
00059                                  OUT PVOID Win32DebugEvent)
00060 {
00061     NTSTATUS Status;
00062     OBJECT_ATTRIBUTES ObjectAttributes;
00063     THREAD_BASIC_INFORMATION ThreadBasicInfo;
00064     LPDEBUG_EVENT DebugEvent = Win32DebugEvent;
00065     HANDLE ThreadHandle;
00066 
00067     /* Write common data */
00068     DebugEvent->dwProcessId = (DWORD)WaitStateChange->
00069                                      AppClientId.UniqueProcess;
00070     DebugEvent->dwThreadId = (DWORD)WaitStateChange->AppClientId.UniqueThread;
00071 
00072     /* Check what kind of even this is */
00073     switch (WaitStateChange->NewState)
00074     {
00075         /* New thread */
00076         case DbgCreateThreadStateChange:
00077 
00078             /* Setup Win32 code */
00079             DebugEvent->dwDebugEventCode = CREATE_THREAD_DEBUG_EVENT;
00080 
00081             /* Copy data over */
00082             DebugEvent->u.CreateThread.hThread =
00083                 WaitStateChange->StateInfo.CreateThread.HandleToThread;
00084             DebugEvent->u.CreateThread.lpStartAddress =
00085                 WaitStateChange->StateInfo.CreateThread.NewThread.StartAddress;
00086 
00087             /* Query the TEB */
00088             Status = NtQueryInformationThread(WaitStateChange->StateInfo.
00089                                               CreateThread.HandleToThread,
00090                                               ThreadBasicInformation,
00091                                               &ThreadBasicInfo,
00092                                               sizeof(ThreadBasicInfo),
00093                                               NULL);
00094             if (!NT_SUCCESS(Status))
00095             {
00096                 /* Failed to get PEB address */
00097                 DebugEvent->u.CreateThread.lpThreadLocalBase = NULL;
00098             }
00099             else
00100             {
00101                 /* Write PEB Address */
00102                 DebugEvent->u.CreateThread.lpThreadLocalBase =
00103                     ThreadBasicInfo.TebBaseAddress;
00104             }
00105             break;
00106 
00107         /* New process */
00108         case DbgCreateProcessStateChange:
00109 
00110             /* Write Win32 debug code */
00111             DebugEvent->dwDebugEventCode = CREATE_PROCESS_DEBUG_EVENT;
00112 
00113             /* Copy data over */
00114             DebugEvent->u.CreateProcessInfo.hProcess =
00115                 WaitStateChange->StateInfo.CreateProcessInfo.HandleToProcess;
00116             DebugEvent->u.CreateProcessInfo.hThread =
00117                 WaitStateChange->StateInfo.CreateProcessInfo.HandleToThread;
00118             DebugEvent->u.CreateProcessInfo.hFile =
00119                 WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
00120                 FileHandle;
00121             DebugEvent->u.CreateProcessInfo.lpBaseOfImage =
00122                 WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
00123                 BaseOfImage;
00124             DebugEvent->u.CreateProcessInfo.dwDebugInfoFileOffset =
00125                 WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
00126                 DebugInfoFileOffset;
00127             DebugEvent->u.CreateProcessInfo.nDebugInfoSize =
00128                 WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
00129                 DebugInfoSize;
00130             DebugEvent->u.CreateProcessInfo.lpStartAddress =
00131                 WaitStateChange->StateInfo.CreateProcessInfo.NewProcess.
00132                 InitialThread.StartAddress;
00133 
00134             /* Query TEB address */
00135             Status = NtQueryInformationThread(WaitStateChange->StateInfo.
00136                                               CreateProcessInfo.HandleToThread,
00137                                               ThreadBasicInformation,
00138                                               &ThreadBasicInfo,
00139                                               sizeof(ThreadBasicInfo),
00140                                               NULL);
00141             if (!NT_SUCCESS(Status))
00142             {
00143                 /* Failed to get PEB address */
00144                 DebugEvent->u.CreateProcessInfo.lpThreadLocalBase = NULL;
00145             }
00146             else
00147             {
00148                 /* Write PEB Address */
00149                 DebugEvent->u.CreateProcessInfo.lpThreadLocalBase =
00150                     ThreadBasicInfo.TebBaseAddress;
00151             }
00152 
00153             /* Clear image name */
00154             DebugEvent->u.CreateProcessInfo.lpImageName = NULL;
00155             DebugEvent->u.CreateProcessInfo.fUnicode = TRUE;
00156             break;
00157 
00158         /* Thread exited */
00159         case DbgExitThreadStateChange:
00160 
00161             /* Write the Win32 debug code and the exit status */
00162             DebugEvent->dwDebugEventCode = EXIT_THREAD_DEBUG_EVENT;
00163             DebugEvent->u.ExitThread.dwExitCode =
00164                 WaitStateChange->StateInfo.ExitThread.ExitStatus;
00165             break;
00166 
00167         /* Process exited */
00168         case DbgExitProcessStateChange:
00169 
00170             /* Write the Win32 debug code and the exit status */
00171             DebugEvent->dwDebugEventCode = EXIT_PROCESS_DEBUG_EVENT;
00172             DebugEvent->u.ExitProcess.dwExitCode =
00173                 WaitStateChange->StateInfo.ExitProcess.ExitStatus;
00174             break;
00175 
00176         /* Any sort of exception */
00177         case DbgExceptionStateChange:
00178         case DbgBreakpointStateChange:
00179         case DbgSingleStepStateChange:
00180 
00181             /* Check if this was a debug print */
00182             if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
00183                 ExceptionCode == DBG_PRINTEXCEPTION_C)
00184             {
00185                 /* Set the Win32 code */
00186                 DebugEvent->dwDebugEventCode = OUTPUT_DEBUG_STRING_EVENT;
00187 
00188                 /* Copy debug string information */
00189                 DebugEvent->u.DebugString.lpDebugStringData =
00190                     (PVOID)WaitStateChange->
00191                            StateInfo.Exception.ExceptionRecord.
00192                            ExceptionInformation[1];
00193                 DebugEvent->u.DebugString.nDebugStringLength =
00194                     WaitStateChange->StateInfo.Exception.ExceptionRecord.
00195                     ExceptionInformation[0];
00196                 DebugEvent->u.DebugString.fUnicode = FALSE;
00197             }
00198             else if (WaitStateChange->StateInfo.Exception.ExceptionRecord.
00199                      ExceptionCode == DBG_RIPEXCEPTION)
00200             {
00201                 /* Set the Win32 code */
00202                 DebugEvent->dwDebugEventCode = RIP_EVENT;
00203 
00204                 /* Set exception information */
00205                 DebugEvent->u.RipInfo.dwType =
00206                     WaitStateChange->StateInfo.Exception.ExceptionRecord.
00207                     ExceptionInformation[1];
00208                 DebugEvent->u.RipInfo.dwError =
00209                     WaitStateChange->StateInfo.Exception.ExceptionRecord.
00210                     ExceptionInformation[0];
00211             }
00212             else
00213             {
00214                 /* Otherwise, this is a debug event, copy info over */
00215                 DebugEvent->dwDebugEventCode = EXCEPTION_DEBUG_EVENT;
00216                 DebugEvent->u.Exception.ExceptionRecord =
00217                     WaitStateChange->StateInfo.Exception.ExceptionRecord;
00218                 DebugEvent->u.Exception.dwFirstChance =
00219                     WaitStateChange->StateInfo.Exception.FirstChance;
00220             }
00221             break;
00222 
00223         /* DLL Load */
00224         case DbgLoadDllStateChange:
00225 
00226             /* Set the Win32 debug code */
00227             DebugEvent->dwDebugEventCode = LOAD_DLL_DEBUG_EVENT;
00228 
00229             /* Copy the rest of the data */
00230             DebugEvent->u.LoadDll.lpBaseOfDll =
00231                 WaitStateChange->StateInfo.LoadDll.BaseOfDll;
00232             DebugEvent->u.LoadDll.hFile =
00233                 WaitStateChange->StateInfo.LoadDll.FileHandle;
00234             DebugEvent->u.LoadDll.dwDebugInfoFileOffset =
00235                 WaitStateChange->StateInfo.LoadDll.DebugInfoFileOffset;
00236             DebugEvent->u.LoadDll.nDebugInfoSize =
00237                 WaitStateChange->StateInfo.LoadDll.DebugInfoSize;
00238 
00239             /* Open the thread */
00240             InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
00241             Status = NtOpenThread(&ThreadHandle,
00242                                   THREAD_QUERY_INFORMATION,
00243                                   &ObjectAttributes,
00244                                   &WaitStateChange->AppClientId);
00245             if (NT_SUCCESS(Status))
00246             {
00247                 /* Query thread information */
00248                 Status = NtQueryInformationThread(ThreadHandle,
00249                                                   ThreadBasicInformation,
00250                                                   &ThreadBasicInfo,
00251                                                   sizeof(ThreadBasicInfo),
00252                                                   NULL);
00253                 NtClose(ThreadHandle);
00254             }
00255 
00256             /* Check if we got thread information */
00257             if (NT_SUCCESS(Status))
00258             {
00259                 /* Save the image name from the TIB */
00260                 DebugEvent->u.LoadDll.lpImageName =
00261                     ((PTEB)ThreadBasicInfo.TebBaseAddress)->
00262                     NtTib.ArbitraryUserPointer;
00263             }
00264             else
00265             {
00266                 /* Otherwise, no name */
00267                 DebugEvent->u.LoadDll.lpImageName = NULL;
00268             }
00269 
00270             /* It's Unicode */
00271             DebugEvent->u.LoadDll.fUnicode = TRUE;
00272             break;
00273 
00274         /* DLL Unload */
00275         case DbgUnloadDllStateChange:
00276 
00277             /* Set Win32 code and DLL Base */
00278             DebugEvent->dwDebugEventCode = UNLOAD_DLL_DEBUG_EVENT;
00279             DebugEvent->u.UnloadDll.lpBaseOfDll =
00280                 WaitStateChange->StateInfo.UnloadDll.BaseAddress;
00281             break;
00282 
00283         /* Anything else, fail */
00284         default: return STATUS_UNSUCCESSFUL;
00285     }
00286 
00287     /* Return success */
00288     return STATUS_SUCCESS;
00289 }
00290 
00291 /*
00292  * @implemented
00293  */
00294 NTSTATUS
00295 NTAPI
00296 DbgUiWaitStateChange(OUT PDBGUI_WAIT_STATE_CHANGE DbgUiWaitStateCange,
00297                      IN PLARGE_INTEGER TimeOut OPTIONAL)
00298 {
00299     /* Tell the kernel to wait */
00300     return NtWaitForDebugEvent(NtCurrentTeb()->DbgSsReserved[1],
00301                                TRUE,
00302                                TimeOut,
00303                                DbgUiWaitStateCange);
00304 }
00305 
00306 /*
00307  * @implemented
00308  */
00309 VOID
00310 NTAPI
00311 DbgUiRemoteBreakin(VOID)
00312 {
00313     /* Make sure a debugger is enabled; if so, breakpoint */
00314     if (NtCurrentPeb()->BeingDebugged) DbgBreakPoint();
00315 
00316     /* Exit the thread */
00317     RtlExitUserThread(STATUS_SUCCESS);
00318 }
00319 
00320 /*
00321  * @implemented
00322  */
00323 NTSTATUS
00324 NTAPI
00325 DbgUiIssueRemoteBreakin(IN HANDLE Process)
00326 {
00327     HANDLE hThread;
00328     CLIENT_ID ClientId;
00329     NTSTATUS Status;
00330 
00331     /* Create the thread that will do the breakin */
00332     Status = RtlCreateUserThread(Process,
00333                                  NULL,
00334                                  FALSE,
00335                                  0,
00336                                  0,
00337                                  PAGE_SIZE,
00338                                  (PVOID)DbgUiRemoteBreakin,
00339                                  NULL,
00340                                  &hThread,
00341                                  &ClientId);
00342 
00343     /* Close the handle on success */
00344     if(NT_SUCCESS(Status)) NtClose(hThread);
00345 
00346     /* Return status */
00347     return Status;
00348 }
00349 
00350 /*
00351  * @implemented
00352  */
00353 HANDLE
00354 NTAPI
00355 DbgUiGetThreadDebugObject(VOID)
00356 {
00357     /* Just return the handle from the TEB */
00358     return NtCurrentTeb()->DbgSsReserved[1];
00359 }
00360 
00361 /*
00362 * @implemented
00363 */
00364 VOID
00365 NTAPI
00366 DbgUiSetThreadDebugObject(HANDLE DebugObject)
00367 {
00368     /* Just set the handle in the TEB */
00369     NtCurrentTeb()->DbgSsReserved[1] = DebugObject;
00370 }
00371 
00372 /*
00373  * @implemented
00374  */
00375 NTSTATUS
00376 NTAPI
00377 DbgUiDebugActiveProcess(IN HANDLE Process)
00378 {
00379     NTSTATUS Status;
00380 
00381     /* Tell the kernel to start debugging */
00382     Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[1]);
00383     if (NT_SUCCESS(Status))
00384     {
00385         /* Now break-in the process */
00386         Status = DbgUiIssueRemoteBreakin(Process);
00387         if (!NT_SUCCESS(Status))
00388         {
00389             /* We couldn't break-in, cancel debugging */
00390             DbgUiStopDebugging(Process);
00391         }
00392     }
00393 
00394     /* Return status */
00395     return Status;
00396 }
00397 
00398 /*
00399  * @implemented
00400  */
00401 NTSTATUS
00402 NTAPI
00403 DbgUiStopDebugging(IN HANDLE Process)
00404 {
00405     /* Call the kernel to remove the debug object */
00406     return NtRemoveProcessDebug(Process, NtCurrentTeb()->DbgSsReserved[1]);
00407 }
00408 
00409 /* EOF */

Generated on Sun May 27 2012 04:22:34 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.