Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygendbgbuffer.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
1.7.6.1
|