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

dbgbuffer.c
Go to the documentation of this file.
00001 /* COPYRIGHT:       See COPYING in the top level directory
00002 * PROJECT:         ReactOS system libraries
00003 * FILE:            lib/rtl/dbgbuffer.c
00004 * PROGRAMER:       James Tabor
00005 */
00006 
00007 /* INCLUDES *****************************************************************/
00008 
00009 #include <rtl.h>
00010 
00011 #define NDEBUG
00012 #include <debug.h>
00013 
00014 /* FUNCTIONS *****************************************************************/
00015 
00016 /*
00017 * @unimplemented
00018 */
00019 PRTL_DEBUG_INFORMATION
00020 NTAPI
00021 RtlCreateQueryDebugBuffer(IN ULONG Size,
00022                           IN BOOLEAN EventPair)
00023 {
00024     NTSTATUS Status;
00025     PRTL_DEBUG_INFORMATION Buf = NULL;
00026     SIZE_T ViewSize = 100 * PAGE_SIZE;
00027 
00028     Status = NtAllocateVirtualMemory(NtCurrentProcess(),
00029                                      (PVOID*)&Buf,
00030                                      0,
00031                                      &ViewSize,
00032                                      MEM_RESERVE | MEM_COMMIT,
00033                                      PAGE_READWRITE);
00034     if (!NT_SUCCESS(Status)) return NULL;
00035 
00036     Buf->ViewBaseClient = Buf;
00037     Buf->ViewSize = (ULONG)ViewSize;
00038 
00039     DPRINT("RtlCQDB: BA: %p BS: 0x%lx\n", Buf->ViewBaseClient, Buf->ViewSize);
00040 
00041     return Buf;
00042 }
00043 
00044 /*
00045 * @unimplemented
00046 */
00047 NTSTATUS
00048 NTAPI
00049 RtlDestroyQueryDebugBuffer(IN PRTL_DEBUG_INFORMATION Buf)
00050 {
00051     NTSTATUS Status = STATUS_SUCCESS;
00052     SIZE_T ViewSize = 0;
00053 
00054     if (NULL != Buf)
00055     {
00056         Status = NtFreeVirtualMemory(NtCurrentProcess(),
00057                                      (PVOID*)&Buf,
00058                                      &ViewSize,
00059                                      MEM_RELEASE);
00060     }
00061     if (!NT_SUCCESS(Status))
00062     {
00063         DPRINT1("RtlDQDB: Failed to free VM!\n");
00064     }
00065     return Status;
00066 }
00067 
00068 /*
00069 *   Based on lib/epsapi/enum/modules.c by KJK::Hyperion.
00070 *
00071 */
00072 NTSTATUS
00073 NTAPI
00074 RtlpQueryRemoteProcessModules(HANDLE ProcessHandle,
00075                               IN PRTL_PROCESS_MODULES Modules OPTIONAL,
00076                               IN ULONG Size OPTIONAL,
00077                               OUT PULONG ReturnedSize)
00078 {
00079     PROCESS_BASIC_INFORMATION pbiInfo;
00080     PPEB_LDR_DATA ppldLdrData;
00081     LDR_DATA_TABLE_ENTRY lmModule;
00082     PLIST_ENTRY pleListHead;
00083     PLIST_ENTRY pleCurEntry;
00084 
00085     PRTL_PROCESS_MODULE_INFORMATION ModulePtr = NULL;
00086     NTSTATUS Status = STATUS_SUCCESS;
00087     ULONG UsedSize = sizeof(ULONG);
00088     ANSI_STRING AnsiString;
00089     PCHAR p;
00090 
00091     DPRINT("RtlpQueryRemoteProcessModules Start\n");
00092 
00093     /* query the process basic information (includes the PEB address) */
00094     Status = NtQueryInformationProcess(ProcessHandle,
00095                                        ProcessBasicInformation,
00096                                        &pbiInfo,
00097                                        sizeof(PROCESS_BASIC_INFORMATION),
00098                                        NULL);
00099 
00100     if (!NT_SUCCESS(Status))
00101     {
00102         /* failure */
00103         DPRINT("NtQueryInformationProcess 1 0x%lx \n", Status);
00104         return Status;
00105     }
00106 
00107     if (Modules == NULL || Size == 0)
00108     {
00109         Status = STATUS_INFO_LENGTH_MISMATCH;
00110     }
00111     else
00112     {
00113         Modules->NumberOfModules = 0;
00114         ModulePtr = &Modules->Modules[0];
00115         Status = STATUS_SUCCESS;
00116     }
00117 
00118     /* get the address of the PE Loader data */
00119     Status = NtReadVirtualMemory(ProcessHandle,
00120                                  &(pbiInfo.PebBaseAddress->Ldr),
00121                                  &ppldLdrData,
00122                                  sizeof(ppldLdrData),
00123                                  NULL);
00124 
00125     if (!NT_SUCCESS(Status))
00126     {
00127         /* failure */
00128         DPRINT("NtReadVirtualMemory 1 0x%lx \n", Status);
00129         return Status;
00130     }
00131 
00132 
00133     /* head of the module list: the last element in the list will point to this */
00134     pleListHead = &ppldLdrData->InLoadOrderModuleList;
00135 
00136     /* get the address of the first element in the list */
00137     Status = NtReadVirtualMemory(ProcessHandle,
00138                                  &(ppldLdrData->InLoadOrderModuleList.Flink),
00139                                  &pleCurEntry,
00140                                  sizeof(pleCurEntry),
00141                                  NULL);
00142 
00143     if (!NT_SUCCESS(Status))
00144     {
00145         /* failure */
00146         DPRINT("NtReadVirtualMemory 2 0x%lx \n", Status);
00147         return Status;
00148     }
00149 
00150     while(pleCurEntry != pleListHead)
00151     {
00152         UNICODE_STRING Unicode;
00153         WCHAR  Buffer[256 * sizeof(WCHAR)];
00154 
00155         /* read the current module */
00156         Status = NtReadVirtualMemory(ProcessHandle,
00157                                      CONTAINING_RECORD(pleCurEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks),
00158                                      &lmModule,
00159                                      sizeof(LDR_DATA_TABLE_ENTRY),
00160                                      NULL);
00161 
00162         /* Import module name from remote Process user space. */
00163         Unicode.Length = lmModule.FullDllName.Length;
00164         Unicode.MaximumLength = lmModule.FullDllName.MaximumLength;
00165         Unicode.Buffer = Buffer;
00166 
00167         Status = NtReadVirtualMemory(ProcessHandle,
00168                                      lmModule.FullDllName.Buffer,
00169                                      Unicode.Buffer,
00170                                      Unicode.Length,
00171                                      NULL);
00172 
00173         if (!NT_SUCCESS(Status))
00174         {
00175             /* failure */
00176             DPRINT( "NtReadVirtualMemory 3 0x%lx \n", Status);
00177             return Status;
00178         }
00179 
00180         DPRINT("  Module %wZ\n", &Unicode);
00181 
00182         if (UsedSize > Size)
00183         {
00184             Status = STATUS_INFO_LENGTH_MISMATCH;
00185         }
00186         else if (Modules != NULL)
00187         {
00188             ModulePtr->Section        = 0;
00189             ModulePtr->MappedBase     = NULL;      // FIXME: ??
00190             ModulePtr->ImageBase      = lmModule.DllBase;
00191             ModulePtr->ImageSize      = lmModule.SizeOfImage;
00192             ModulePtr->Flags          = lmModule.Flags;
00193             ModulePtr->LoadOrderIndex = 0;      // FIXME:  ??
00194             ModulePtr->InitOrderIndex = 0;      // FIXME: ??
00195             ModulePtr->LoadCount      = lmModule.LoadCount;
00196 
00197             AnsiString.Length        = 0;
00198             AnsiString.MaximumLength = 256;
00199             AnsiString.Buffer        = ModulePtr->FullPathName;
00200             RtlUnicodeStringToAnsiString(&AnsiString,
00201                                          &Unicode,
00202                                          FALSE);
00203 
00204             p = strrchr(ModulePtr->FullPathName, '\\');
00205             if (p != NULL)
00206                 ModulePtr->OffsetToFileName = (USHORT)(p - ModulePtr->FullPathName + 1);
00207             else
00208                 ModulePtr->OffsetToFileName = 0;
00209 
00210             ModulePtr++;
00211             Modules->NumberOfModules++;
00212         }
00213         UsedSize += sizeof(RTL_PROCESS_MODULE_INFORMATION);
00214 
00215         /* address of the next module in the list */
00216         pleCurEntry = lmModule.InLoadOrderLinks.Flink;
00217     }
00218 
00219     if (ReturnedSize != 0)
00220         *ReturnedSize = UsedSize;
00221 
00222     DPRINT("RtlpQueryRemoteProcessModules End\n");
00223 
00224     /* success */
00225     return (STATUS_SUCCESS);
00226 }
00227 
00228 /*
00229 * @unimplemented
00230 */
00231 NTSTATUS
00232 NTAPI
00233 RtlQueryProcessDebugInformation(IN ULONG ProcessId,
00234                                 IN ULONG DebugInfoMask,
00235                                 IN OUT PRTL_DEBUG_INFORMATION Buf)
00236 {
00237     NTSTATUS Status = STATUS_SUCCESS;
00238     ULONG Pid = (ULONG)(ULONG_PTR) NtCurrentTeb()->ClientId.UniqueProcess;
00239 
00240     Buf->Flags = DebugInfoMask;
00241     Buf->OffsetFree = sizeof(RTL_DEBUG_INFORMATION);
00242 
00243     DPRINT("QueryProcessDebugInformation Start\n");
00244 
00245     /*
00246     Currently ROS can not read-only from kenrel space, and doesn't
00247     check for boundaries inside kernel space that are page protected
00248     from every one but the kernel. aka page 0 - 2
00249     */
00250     if (ProcessId <= 1)
00251     {
00252         Status = STATUS_ACCESS_VIOLATION;
00253     }
00254     else
00255         if (Pid == ProcessId)
00256         {
00257             if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES)
00258             {
00259                 PRTL_PROCESS_MODULES Mp;
00260                 ULONG ReturnSize = 0;
00261                 ULONG MSize;
00262 
00263                 Mp = (PRTL_PROCESS_MODULES)(Buf + Buf->OffsetFree);
00264 
00265                 /* I like this better than the do & while loop. */
00266                 Status = LdrQueryProcessModuleInformation(NULL,
00267                                                           0,
00268                                                           &ReturnSize);
00269                 Status = LdrQueryProcessModuleInformation(Mp,
00270                                                           ReturnSize ,
00271                                                           &ReturnSize);
00272                 if (!NT_SUCCESS(Status))
00273                 {
00274                     return Status;
00275                 }
00276 
00277                 MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8);
00278                 Buf->Modules = Mp;
00279                 Buf->OffsetFree = Buf->OffsetFree + MSize;
00280             }
00281 
00282             if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)
00283             {
00284                 PRTL_PROCESS_HEAPS Hp;
00285                 ULONG HSize;
00286 
00287                 Hp = (PRTL_PROCESS_HEAPS)(Buf + Buf->OffsetFree);
00288                 HSize = sizeof(RTL_PROCESS_HEAPS);
00289                 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS)
00290                 {
00291                     // TODO
00292                 }
00293                 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS)
00294                 {
00295                     // TODO
00296                 }
00297                 Buf->Heaps = Hp;
00298                 Buf->OffsetFree = Buf->OffsetFree + HSize;
00299 
00300             }
00301 
00302             if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS)
00303             {
00304                 PRTL_PROCESS_LOCKS Lp;
00305                 ULONG LSize;
00306 
00307                 Lp = (PRTL_PROCESS_LOCKS)(Buf + Buf->OffsetFree);
00308                 LSize = sizeof(RTL_PROCESS_LOCKS);
00309                 Buf->Locks = Lp;
00310                 Buf->OffsetFree = Buf->OffsetFree + LSize;
00311             }
00312 
00313             DPRINT("QueryProcessDebugInformation end \n");
00314             DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree);
00315         }
00316         else
00317         {
00318             HANDLE hProcess;
00319             CLIENT_ID ClientId;
00320             OBJECT_ATTRIBUTES ObjectAttributes;
00321 
00322             Buf->TargetProcessHandle = NtCurrentProcess();
00323 
00324             ClientId.UniqueThread = 0;
00325             ClientId.UniqueProcess = (HANDLE)(ULONG_PTR)ProcessId;
00326             InitializeObjectAttributes(&ObjectAttributes,
00327                                        NULL,
00328                                        0,
00329                                        NULL,
00330                                        NULL);
00331 
00332             Status = NtOpenProcess(&hProcess,
00333                                    (PROCESS_ALL_ACCESS),
00334                                    &ObjectAttributes,
00335                                    &ClientId );
00336             if (!NT_SUCCESS(Status))
00337             {
00338                 return Status;
00339             }
00340 
00341             if (DebugInfoMask & RTL_DEBUG_QUERY_MODULES)
00342             {
00343                 PRTL_PROCESS_MODULES Mp;
00344                 ULONG ReturnSize = 0;
00345                 ULONG MSize;
00346 
00347                 Mp = (PRTL_PROCESS_MODULES)(Buf + Buf->OffsetFree);
00348 
00349                 Status = RtlpQueryRemoteProcessModules(hProcess,
00350                                                        NULL,
00351                                                        0,
00352                                                        &ReturnSize);
00353 
00354                 Status = RtlpQueryRemoteProcessModules(hProcess,
00355                                                        Mp,
00356                                                        ReturnSize ,
00357                                                        &ReturnSize);
00358                 if (!NT_SUCCESS(Status))
00359                 {
00360                     return Status;
00361                 }
00362 
00363                 MSize = Mp->NumberOfModules * (sizeof(RTL_PROCESS_MODULES) + 8);
00364                 Buf->Modules = Mp;
00365                 Buf->OffsetFree = Buf->OffsetFree + MSize;
00366             }
00367 
00368             if (DebugInfoMask & RTL_DEBUG_QUERY_HEAPS)
00369             {
00370                 PRTL_PROCESS_HEAPS Hp;
00371                 ULONG HSize;
00372 
00373                 Hp = (PRTL_PROCESS_HEAPS)(Buf + Buf->OffsetFree);
00374                 HSize = sizeof(RTL_PROCESS_HEAPS);
00375                 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_TAGS)
00376                 {
00377                     // TODO
00378                 }
00379                 if (DebugInfoMask & RTL_DEBUG_QUERY_HEAP_BLOCKS)
00380                 {
00381                     // TODO
00382                 }
00383                 Buf->Heaps = Hp;
00384                 Buf->OffsetFree = Buf->OffsetFree + HSize;
00385 
00386             }
00387 
00388             if (DebugInfoMask & RTL_DEBUG_QUERY_LOCKS)
00389             {
00390                 PRTL_PROCESS_LOCKS Lp;
00391                 ULONG LSize;
00392 
00393                 Lp = (PRTL_PROCESS_LOCKS)(Buf + Buf->OffsetFree);
00394                 LSize = sizeof(RTL_PROCESS_LOCKS);
00395                 Buf->Locks = Lp;
00396                 Buf->OffsetFree = Buf->OffsetFree + LSize;
00397             }
00398 
00399             DPRINT("QueryProcessDebugInformation end \n");
00400             DPRINT("QueryDebugInfo : 0x%lx\n", Buf->OffsetFree);
00401         }
00402 
00403     return Status;
00404 }
00405 
00406 /* EOL */

Generated on Fri May 25 2012 04:34:50 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.