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

dbgkutil.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Kernel
00003  * LICENSE:         GPL - See COPYING in the top level directory
00004  * FILE:            ntoskrnl/dbgk/dbgkutil.c
00005  * PURPOSE:         User-Mode Debugging Support, Internal Debug Functions.
00006  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
00007  */
00008 
00009 /* INCLUDES ******************************************************************/
00010 
00011 #include <ntoskrnl.h>
00012 #define NDEBUG
00013 #include <debug.h>
00014 
00015 /* FUNCTIONS *****************************************************************/
00016 
00017 HANDLE
00018 NTAPI
00019 DbgkpSectionToFileHandle(IN PVOID Section)
00020 {
00021     NTSTATUS Status;
00022     POBJECT_NAME_INFORMATION FileName;
00023     OBJECT_ATTRIBUTES ObjectAttributes;
00024     IO_STATUS_BLOCK IoStatusBlock;
00025     HANDLE Handle;
00026     PAGED_CODE();
00027 
00028     /* Get the filename of the section */
00029     Status = MmGetFileNameForSection(Section, &FileName);
00030     if (!NT_SUCCESS(Status)) return NULL;
00031 
00032     /* Initialize object attributes */
00033     InitializeObjectAttributes(&ObjectAttributes,
00034                                &FileName->Name,
00035                                OBJ_CASE_INSENSITIVE |
00036                                OBJ_FORCE_ACCESS_CHECK |
00037                                OBJ_KERNEL_HANDLE,
00038                                NULL,
00039                                NULL);
00040 
00041     /* Open the file */
00042     Status = ZwOpenFile(&Handle,
00043                         GENERIC_READ | SYNCHRONIZE,
00044                         &ObjectAttributes,
00045                         &IoStatusBlock,
00046                         FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
00047                         FILE_SYNCHRONOUS_IO_NONALERT);
00048 
00049     /* Free the name and return the handle if we succeeded */
00050     ExFreePool(FileName);
00051     if (!NT_SUCCESS(Status)) return NULL;
00052     return Handle;
00053 }
00054 
00055 BOOLEAN
00056 NTAPI
00057 DbgkpSuspendProcess(VOID)
00058 {
00059     PAGED_CODE();
00060 
00061     /* Make sure this isn't a deleted process */
00062     if (!PsGetCurrentProcess()->ProcessDelete)
00063     {
00064         /* Freeze all the threads */
00065         KeFreezeAllThreads();
00066         return TRUE;
00067     }
00068     else
00069     {
00070         /* No suspend was done */
00071         return FALSE;
00072     }
00073 }
00074 
00075 VOID
00076 NTAPI
00077 DbgkpResumeProcess(VOID)
00078 {
00079     PAGED_CODE();
00080 
00081     /* Thaw all the threads */
00082     KeThawAllThreads();
00083 }
00084 
00085 VOID
00086 NTAPI
00087 DbgkCreateThread(IN PETHREAD Thread,
00088                  IN PVOID StartAddress)
00089 {
00090     PEPROCESS Process = PsGetCurrentProcess();
00091     ULONG ProcessFlags;
00092     IMAGE_INFO ImageInfo;
00093     PIMAGE_NT_HEADERS NtHeader;
00094     POBJECT_NAME_INFORMATION ModuleName;
00095     UNICODE_STRING NtDllName;
00096     NTSTATUS Status;
00097     PVOID DebugPort;
00098     DBGKM_MSG ApiMessage;
00099     PDBGKM_CREATE_THREAD CreateThread = &ApiMessage.CreateThread;
00100     PDBGKM_CREATE_PROCESS CreateProcess = &ApiMessage.CreateProcess;
00101     PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
00102     OBJECT_ATTRIBUTES ObjectAttributes;
00103     IO_STATUS_BLOCK IoStatusBlock;
00104     PTEB Teb;
00105     PAGED_CODE();
00106 
00107     /* Sanity check */
00108     ASSERT(Thread == PsGetCurrentThread());
00109 
00110     /* Try ORing in the create reported and image notify flags */
00111     ProcessFlags = PspSetProcessFlag(Process,
00112                                      PSF_CREATE_REPORTED_BIT |
00113                                      PSF_IMAGE_NOTIFY_DONE_BIT);
00114 
00115     /* Check if we were the first to set them or if another thread raced us */
00116     if (!(ProcessFlags & PSF_IMAGE_NOTIFY_DONE_BIT) && (PsImageNotifyEnabled))
00117     {
00118         /* It hasn't.. set up the image info for the process */
00119         ImageInfo.Properties = 0;
00120         ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
00121         ImageInfo.ImageBase = Process->SectionBaseAddress;
00122         ImageInfo.ImageSize = 0;
00123         ImageInfo.ImageSelector = 0;
00124         ImageInfo.ImageSectionNumber = 0;
00125 
00126         /* Get the NT Headers */
00127         NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
00128         if (NtHeader)
00129         {
00130             /* Set image size */
00131             ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
00132         }
00133 
00134         /* Get the image name */
00135         Status = MmGetFileNameForSection(Process->SectionObject, &ModuleName);
00136         if (NT_SUCCESS(Status))
00137         {
00138             /* Call the notify routines and free the name */
00139             PspRunLoadImageNotifyRoutines(&ModuleName->Name,
00140                                           Process->UniqueProcessId,
00141                                           &ImageInfo);
00142             ExFreePool(ModuleName);
00143         }
00144         else
00145         {
00146             /* Call the notify routines */
00147             PspRunLoadImageNotifyRoutines(NULL,
00148                                           Process->UniqueProcessId,
00149                                           &ImageInfo);
00150         }
00151 
00152         /* Setup the info for ntdll.dll */
00153         ImageInfo.Properties = 0;
00154         ImageInfo.ImageAddressingMode = IMAGE_ADDRESSING_MODE_32BIT;
00155         ImageInfo.ImageBase = PspSystemDllBase;
00156         ImageInfo.ImageSize = 0;
00157         ImageInfo.ImageSelector = 0;
00158         ImageInfo.ImageSectionNumber = 0;
00159 
00160         /* Get the NT Headers */
00161         NtHeader = RtlImageNtHeader(PspSystemDllBase);
00162         if (NtHeader)
00163         {
00164             /* Set image size */
00165             ImageInfo.ImageSize = NtHeader->OptionalHeader.SizeOfImage;
00166         }
00167 
00168         /* Call the notify routines */
00169         RtlInitUnicodeString(&NtDllName,
00170                              L"\\SystemRoot\\System32\\ntdll.dll");
00171         PspRunLoadImageNotifyRoutines(&NtDllName,
00172                                       Process->UniqueProcessId,
00173                                       &ImageInfo);
00174     }
00175 
00176     /* Fail if we have no port */
00177     DebugPort = Process->DebugPort;
00178     if (!DebugPort) return;
00179 
00180     /* Check if create was not already reported */
00181     if (!(ProcessFlags & PSF_CREATE_REPORTED_BIT))
00182     {
00183         /* Setup the information structure for the new thread */
00184         CreateProcess->InitialThread.SubSystemKey = 0;
00185         CreateProcess->InitialThread.StartAddress = NULL;
00186 
00187         /* And for the new process */
00188         CreateProcess->SubSystemKey = 0;
00189         CreateProcess->FileHandle = DbgkpSectionToFileHandle(Process->
00190                                                              SectionObject);
00191         CreateProcess->BaseOfImage = Process->SectionBaseAddress;
00192         CreateProcess->DebugInfoFileOffset = 0;
00193         CreateProcess->DebugInfoSize = 0;
00194 
00195         /* Get the NT Header */
00196         NtHeader = RtlImageNtHeader(Process->SectionBaseAddress);
00197         if (NtHeader)
00198         {
00199             /* Fill out data from the header */
00200             CreateProcess->InitialThread.StartAddress =
00201                 (PVOID)((ULONG_PTR)NtHeader->OptionalHeader.ImageBase +
00202                         NtHeader->OptionalHeader.AddressOfEntryPoint);
00203             CreateProcess->DebugInfoFileOffset = NtHeader->FileHeader.
00204                                                  PointerToSymbolTable;
00205             CreateProcess->DebugInfoSize = NtHeader->FileHeader.
00206                                            NumberOfSymbols;
00207         }
00208 
00209         /* Setup the API Message */
00210         ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00211                                  (8 + sizeof(DBGKM_CREATE_PROCESS));
00212         ApiMessage.h.u2.ZeroInit = 0;
00213         ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00214         ApiMessage.ApiNumber = DbgKmCreateProcessApi;
00215 
00216         /* Send the message */
00217         DbgkpSendApiMessage(&ApiMessage, FALSE);
00218 
00219         /* Close the handle */
00220         ObCloseHandle(CreateProcess->FileHandle, KernelMode);
00221 
00222         /* Setup the parameters */
00223         LoadDll->BaseOfDll = PspSystemDllBase;
00224         LoadDll->DebugInfoFileOffset = 0;
00225         LoadDll->DebugInfoSize = 0;
00226         LoadDll->NamePointer = NULL;
00227 
00228         /* Get the NT Headers */
00229         NtHeader = RtlImageNtHeader(PspSystemDllBase);
00230         if (NtHeader)
00231         {
00232             /* Fill out debug information */
00233             LoadDll->DebugInfoFileOffset = NtHeader->
00234                                            FileHeader.PointerToSymbolTable;
00235             LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
00236         }
00237 
00238         /* Get the TEB */
00239         Teb = Thread->Tcb.Teb;
00240         if (Teb)
00241         {
00242             /* Copy the system library name and link to it */
00243             wcsncpy(Teb->StaticUnicodeBuffer,
00244                     L"ntdll.dll",
00245                     sizeof(Teb->StaticUnicodeBuffer) / sizeof(WCHAR));
00246             Teb->NtTib.ArbitraryUserPointer = Teb->StaticUnicodeBuffer;
00247 
00248             /* Return it in the debug event as well */
00249             LoadDll->NamePointer = &Teb->NtTib.ArbitraryUserPointer;
00250         }
00251 
00252         /* Get a handle */
00253         InitializeObjectAttributes(&ObjectAttributes,
00254                                    &PsNtDllPathName,
00255                                    OBJ_CASE_INSENSITIVE |
00256                                    OBJ_KERNEL_HANDLE |
00257                                    OBJ_FORCE_ACCESS_CHECK,
00258                                    NULL,
00259                                    NULL);
00260         Status = ZwOpenFile(&LoadDll->FileHandle,
00261                             GENERIC_READ | SYNCHRONIZE,
00262                             &ObjectAttributes,
00263                             &IoStatusBlock,
00264                             FILE_SHARE_DELETE |
00265                             FILE_SHARE_READ |
00266                             FILE_SHARE_WRITE,
00267                             FILE_SYNCHRONOUS_IO_NONALERT);
00268         if (NT_SUCCESS(Status))
00269         {
00270             /* Setup the API Message */
00271             ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00272                                      (8 + sizeof(DBGKM_LOAD_DLL));
00273             ApiMessage.h.u2.ZeroInit = 0;
00274             ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00275             ApiMessage.ApiNumber = DbgKmLoadDllApi;
00276 
00277             /* Send the message */
00278             DbgkpSendApiMessage(&ApiMessage, TRUE);
00279 
00280             /* Close the handle */
00281             ObCloseHandle(LoadDll->FileHandle, KernelMode);
00282         }
00283     }
00284     else
00285     {
00286         /* Otherwise, do it just for the thread */
00287         CreateThread->SubSystemKey = 0;
00288         CreateThread->StartAddress = StartAddress;
00289 
00290         /* Setup the API Message */
00291         ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00292                                  (8 + sizeof(DBGKM_CREATE_THREAD));
00293         ApiMessage.h.u2.ZeroInit = 0;
00294         ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00295         ApiMessage.ApiNumber = DbgKmCreateThreadApi;
00296 
00297         /* Send the message */
00298         DbgkpSendApiMessage(&ApiMessage, TRUE);
00299     }
00300 }
00301 
00302 VOID
00303 NTAPI
00304 DbgkExitProcess(IN NTSTATUS ExitStatus)
00305 {
00306     DBGKM_MSG ApiMessage;
00307     PDBGKM_EXIT_PROCESS ExitProcess = &ApiMessage.ExitProcess;
00308     PEPROCESS Process = PsGetCurrentProcess();
00309     PETHREAD Thread = PsGetCurrentThread();
00310     PAGED_CODE();
00311 
00312     /* Check if this thread is hidden, doesn't have a debug port, or died */
00313     if ((Thread->HideFromDebugger) ||
00314         !(Process->DebugPort) ||
00315         (Thread->DeadThread))
00316     {
00317         /* Don't notify the debugger */
00318         return;
00319     }
00320 
00321     /* Set the exit status */
00322     ExitProcess->ExitStatus = ExitStatus;
00323 
00324     /* Setup the API Message */
00325     ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00326                              (8 + sizeof(DBGKM_EXIT_PROCESS));
00327     ApiMessage.h.u2.ZeroInit = 0;
00328     ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00329     ApiMessage.ApiNumber = DbgKmExitProcessApi;
00330 
00331     /* Set the current exit time */
00332     KeQuerySystemTime(&Process->ExitTime);
00333 
00334     /* Send the message */
00335     DbgkpSendApiMessage(&ApiMessage, FALSE);
00336 }
00337 
00338 VOID
00339 NTAPI
00340 DbgkExitThread(IN NTSTATUS ExitStatus)
00341 {
00342     DBGKM_MSG ApiMessage;
00343     PDBGKM_EXIT_THREAD ExitThread = &ApiMessage.ExitThread;
00344     PEPROCESS Process = PsGetCurrentProcess();
00345     PETHREAD Thread = PsGetCurrentThread();
00346     BOOLEAN Suspended;
00347     PAGED_CODE();
00348 
00349     /* Check if this thread is hidden, doesn't have a debug port, or died */
00350     if ((Thread->HideFromDebugger) ||
00351         !(Process->DebugPort) ||
00352         (Thread->DeadThread))
00353     {
00354         /* Don't notify the debugger */
00355         return;
00356     }
00357 
00358     /* Set the exit status */
00359     ExitThread->ExitStatus = ExitStatus;
00360 
00361     /* Setup the API Message */
00362     ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00363                              (8 + sizeof(DBGKM_EXIT_THREAD));
00364     ApiMessage.h.u2.ZeroInit = 0;
00365     ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00366     ApiMessage.ApiNumber = DbgKmExitThreadApi;
00367 
00368     /* Suspend the process */
00369     Suspended = DbgkpSuspendProcess();
00370 
00371     /* Send the message */
00372     DbgkpSendApiMessage(&ApiMessage, FALSE);
00373 
00374     /* Resume the process if needed */
00375     if (Suspended) DbgkpResumeProcess();
00376 }
00377 
00378 VOID
00379 NTAPI
00380 DbgkMapViewOfSection(IN PVOID Section,
00381                      IN PVOID BaseAddress,
00382                      IN ULONG SectionOffset,
00383                      IN ULONG_PTR ViewSize)
00384 {
00385     DBGKM_MSG ApiMessage;
00386     PDBGKM_LOAD_DLL LoadDll = &ApiMessage.LoadDll;
00387     PEPROCESS Process = PsGetCurrentProcess();
00388     PETHREAD Thread = PsGetCurrentThread();
00389     PIMAGE_NT_HEADERS NtHeader;
00390     PAGED_CODE();
00391     DBGKTRACE(DBGK_PROCESS_DEBUG,
00392               "Section: %p. Base: %p\n", Section, BaseAddress);
00393 
00394     /* Check if this thread is kernel, hidden or doesn't have a debug port */
00395     if ((ExGetPreviousMode() == KernelMode) ||
00396         (Thread->HideFromDebugger) ||
00397         !(Process->DebugPort))
00398     {
00399         /* Don't notify the debugger */
00400         return;
00401     }
00402 
00403     /* Setup the parameters */
00404     LoadDll->FileHandle = DbgkpSectionToFileHandle(Section);
00405     LoadDll->BaseOfDll = BaseAddress;
00406     LoadDll->DebugInfoFileOffset = 0;
00407     LoadDll->DebugInfoSize = 0;
00408 
00409     /* Get the NT Headers */
00410     NtHeader = RtlImageNtHeader(BaseAddress);
00411     if (NtHeader)
00412     {
00413         /* Fill out debug information */
00414         LoadDll->DebugInfoFileOffset = NtHeader->FileHeader.
00415                                        PointerToSymbolTable;
00416         LoadDll->DebugInfoSize = NtHeader->FileHeader.NumberOfSymbols;
00417     }
00418 
00419     /* Setup the API Message */
00420     ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00421                              (8 + sizeof(DBGKM_LOAD_DLL));
00422     ApiMessage.h.u2.ZeroInit = 0;
00423     ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00424     ApiMessage.ApiNumber = DbgKmLoadDllApi;
00425 
00426     /* Send the message */
00427     DbgkpSendApiMessage(&ApiMessage, TRUE);
00428 
00429     /* Close the handle */
00430     ObCloseHandle(LoadDll->FileHandle, KernelMode);
00431 }
00432 
00433 VOID
00434 NTAPI
00435 DbgkUnMapViewOfSection(IN PVOID BaseAddress)
00436 {
00437     DBGKM_MSG ApiMessage;
00438     PDBGKM_UNLOAD_DLL UnloadDll = &ApiMessage.UnloadDll;
00439     PEPROCESS Process = PsGetCurrentProcess();
00440     PETHREAD Thread = PsGetCurrentThread();
00441     PAGED_CODE();
00442 
00443     /* Check if this thread is kernel, hidden or doesn't have a debug port */
00444     if ((ExGetPreviousMode() == KernelMode) ||
00445         (Thread->HideFromDebugger) ||
00446         !(Process->DebugPort))
00447     {
00448         /* Don't notify the debugger */
00449         return;
00450     }
00451 
00452     /* Set the DLL Base */
00453     UnloadDll->BaseAddress = BaseAddress;
00454 
00455     /* Setup the API Message */
00456     ApiMessage.h.u1.Length = sizeof(DBGKM_MSG) << 16 |
00457                              (8 + sizeof(DBGKM_UNLOAD_DLL));
00458     ApiMessage.h.u2.ZeroInit = 0;
00459     ApiMessage.h.u2.s2.Type = LPC_DEBUG_EVENT;
00460     ApiMessage.ApiNumber = DbgKmUnloadDllApi;
00461 
00462     /* Send the message */
00463     DbgkpSendApiMessage(&ApiMessage, TRUE);
00464 }

Generated on Sun May 27 2012 04:37:09 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.