Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

dmpaddr.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1989 Microsoft Corporation 00004 00005 Module Name: 00006 00007 dmpaddr.c 00008 00009 Abstract: 00010 00011 Temporary routine to print valid addresses within an 00012 address space. 00013 00014 Author: 00015 00016 Lou Perazzoli (loup) 20-Mar-1989 00017 00018 Environment: 00019 00020 Kernel Mode. 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "mi.h" 00027 00028 #if DBG 00029 00030 BOOLEAN 00031 MiFlushUnusedSectionInternal ( 00032 IN PCONTROL_AREA ControlArea 00033 ); 00034 00035 #endif //DBG 00036 00037 #if DBG 00038 VOID 00039 MiDumpValidAddresses ( 00040 ) 00041 00042 { 00043 ULONG va = 0; 00044 ULONG i,j; 00045 PMMPTE PointerPde; 00046 PMMPTE PointerPte; 00047 00048 PointerPde = MiGetPdeAddress (va); 00049 00050 00051 for (i = 0; i < PDE_PER_PAGE; i++) { 00052 if (PointerPde->u.Hard.Valid) { 00053 DbgPrint(" **valid PDE, element %ld %lx %lx\n",i,i, 00054 PointerPde->u.Long); 00055 PointerPte = MiGetPteAddress (va); 00056 for (j = 0 ; j < PTE_PER_PAGE; j++) { 00057 if (PointerPte->u.Hard.Valid) { 00058 DbgPrint("Valid address at %lx pte %lx\n", (ULONG)va, 00059 PointerPte->u.Long); 00060 } 00061 va += PAGE_SIZE; 00062 PointerPte++; 00063 } 00064 } else { 00065 va += (ULONG)PDE_PER_PAGE * (ULONG)PAGE_SIZE; 00066 } 00067 00068 PointerPde++; 00069 } 00070 00071 return; 00072 00073 } 00074 00075 #endif //DBG 00076 00077 #if DBG 00078 VOID 00079 MiFormatPte ( 00080 IN PMMPTE PointerPte 00081 ) 00082 00083 { 00084 00085 // int j; 00086 // unsigned long pte; 00087 PMMPTE proto_pte; 00088 PSUBSECTION subsect; 00089 00090 // struct a_bit { 00091 // unsigned long biggies : 31; 00092 // unsigned long bitties : 1; 00093 // }; 00094 // 00095 // struct a_bit print_pte; 00096 00097 00098 if (MmIsAddressValid (PointerPte) == FALSE) { 00099 DbgPrint(" cannot dump PTE %p - it's not valid\n\n", 00100 (ULONG_PTR)PointerPte); 00101 return; 00102 } 00103 00104 proto_pte = MiPteToProto(PointerPte); 00105 subsect = MiGetSubsectionAddress(PointerPte); 00106 00107 DbgPrint("***DumpPTE at %p contains %p\n", 00108 (ULONG_PTR)PointerPte, 00109 PointerPte->u.Long); 00110 00111 DbgPrint(" protoaddr %p subsectaddr %p\n\n", 00112 (ULONG_PTR)proto_pte, 00113 (ULONG_PTR)subsect); 00114 00115 return; 00116 00117 // DbgPrint("page frame number 0x%lx proto PTE address 0x%lx\n", 00118 // 00119 // DbgPrint("PTE is 0x%lx\n", PTETOULONG(the_pte)); 00120 // 00121 // proto_pte = MiPteToProto(PointerPte); 00122 // 00123 // DbgPrint("page frame number 0x%lx proto PTE address 0x%lx\n", 00124 // PointerPte->u.Hard.PageFrameNumber,*(PULONG)&proto_pte); 00125 // 00126 // DbgPrint(" 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 \n"); 00127 // DbgPrint(" +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \n"); 00128 // DbgPrint(" | pfn |c|p|t|r|r|d|a|c|p|o|w|v| \n"); 00129 // DbgPrint(" | |o|r|r|s|s|t|c|a|b|w|r|l| \n"); 00130 // DbgPrint(" | |w|o|n|v|v|y|c|c|o|n|t|d| \n"); 00131 // DbgPrint(" +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ \n "); 00132 // pte = PTETOULONG(the_pte); 00133 // 00134 // for (j = 0; j < 32; j++) { 00135 // *(PULONG)& print_pte = pte; 00136 // DbgPrint(" %lx",print_pte.bitties); 00137 // pte = pte << 1; 00138 // } 00139 // DbgPrint("\n"); 00140 // 00141 00142 } 00143 #endif //DBG 00144 00145 #if DBG 00146 00147 VOID 00148 MiDumpWsl ( ) 00149 00150 { 00151 ULONG i; 00152 PMMWSLE wsle; 00153 00154 DbgPrint("***WSLE cursize %lx frstfree %lx Min %lx Max %lx\n", 00155 PsGetCurrentProcess()->Vm.WorkingSetSize, 00156 MmWorkingSetList->FirstFree, 00157 PsGetCurrentProcess()->Vm.MinimumWorkingSetSize, 00158 PsGetCurrentProcess()->Vm.MaximumWorkingSetSize); 00159 00160 DbgPrint(" quota %lx firstdyn %lx last ent %lx next slot %lx\n", 00161 MmWorkingSetList->Quota, 00162 MmWorkingSetList->FirstDynamic, 00163 MmWorkingSetList->LastEntry, 00164 MmWorkingSetList->NextSlot); 00165 00166 wsle = MmWsle; 00167 00168 for (i = 0; i < MmWorkingSetList->LastEntry; i++) { 00169 DbgPrint(" index %lx %lx\n",i,wsle->u1.Long); 00170 wsle++; 00171 } 00172 return; 00173 00174 } 00175 00176 #endif //DBG 00177 00178 #if 0 //COMMENTED OUT!!! 00179 VOID 00180 MiFlushUnusedSections ( 00181 VOID 00182 ) 00183 00184 /*++ 00185 00186 Routine Description: 00187 00188 This routine rumages through the PFN database and attempts 00189 to close any unused sections. 00190 00191 Arguments: 00192 00193 None. 00194 00195 Return Value: 00196 00197 None. 00198 00199 --*/ 00200 00201 { 00202 PMMPFN LastPfn; 00203 PMMPFN Pfn1; 00204 PSUBSECTION Subsection; 00205 KIRQL OldIrql; 00206 00207 LOCK_PFN (OldIrql); 00208 Pfn1 = MI_PFN_ELEMENT (MmLowestPhysicalPage + 1); 00209 LastPfn = MI_PFN_ELEMENT(MmHighestPhysicalPage); 00210 00211 while (Pfn1 < LastPfn) { 00212 if (Pfn1->OriginalPte.u.Soft.Prototype == 1) { 00213 if ((Pfn1->u3.e1.PageLocation == ModifiedPageList) || 00214 (Pfn1->u3.e1.PageLocation == StandbyPageList)) { 00215 00216 // 00217 // Make sure the PTE is not waiting for I/O to complete. 00218 // 00219 00220 if (MI_IS_PFN_DELETED (Pfn1)) { 00221 00222 Subsection = MiGetSubsectionAddress (&Pfn1->OriginalPte); 00223 MiFlushUnusedSectionInternal (Subsection->ControlArea); 00224 } 00225 } 00226 } 00227 Pfn1++; 00228 } 00229 00230 UNLOCK_PFN (OldIrql); 00231 return; 00232 } 00233 00234 BOOLEAN 00235 MiFlushUnusedSectionInternal ( 00236 IN PCONTROL_AREA ControlArea 00237 ) 00238 00239 { 00240 BOOLEAN result; 00241 KIRQL OldIrql = APC_LEVEL; 00242 00243 if ((ControlArea->NumberOfMappedViews != 0) || 00244 (ControlArea->NumberOfSectionReferences != 0)) { 00245 00246 // 00247 // The segment is currently in use. 00248 // 00249 00250 return FALSE; 00251 } 00252 00253 // 00254 // The segment has no references, delete it. If the segment 00255 // is already being deleted, set the event field in the control 00256 // area and wait on the event. 00257 // 00258 00259 if ((ControlArea->u.Flags.BeingDeleted) || 00260 (ControlArea->u.Flags.BeingCreated)) { 00261 00262 return TRUE; 00263 } 00264 00265 // 00266 // Set the being deleted flag and up the number of mapped views 00267 // for the segment. Upping the number of mapped views prevents 00268 // the segment from being deleted and passed to the deletion thread 00269 // while we are forcing a delete. 00270 // 00271 00272 ControlArea->u.Flags.BeingDeleted = 1; 00273 ControlArea->NumberOfMappedViews = 1; 00274 00275 // 00276 // This is a page file backed or image Segment. The Segment is being 00277 // deleted, remove all references to the paging file and physical memory. 00278 // 00279 00280 UNLOCK_PFN (OldIrql); 00281 00282 MiCleanSection (ControlArea); 00283 00284 LOCK_PFN (OldIrql); 00285 return TRUE; 00286 } 00287 #endif //0 00288 00289 00290 #if DBG 00291 00292 #define ALLOC_SIZE ((ULONG)8*1024) 00293 #define MM_SAVED_CONTROL 64 00294 #define MM_KERN_MAP_SIZE 64 00295 00296 #define MM_NONPAGED_POOL_MARK ((PUCHAR)(ULONG_PTR)0xfffff123) 00297 #define MM_PAGED_POOL_MARK ((PUCHAR)(ULONG_PTR)0xfffff124) 00298 #define MM_KERNEL_STACK_MARK ((PUCHAR)(ULONG_PTR)0xfffff125) 00299 00300 extern ULONG_PTR MmSystemPtesStart[MaximumPtePoolTypes]; 00301 extern ULONG_PTR MmSystemPtesEnd[MaximumPtePoolTypes]; 00302 00303 typedef struct _KERN_MAP { 00304 ULONG_PTR StartVa; 00305 ULONG_PTR EndVa; 00306 PLDR_DATA_TABLE_ENTRY Entry; 00307 } KERN_MAP, *PKERN_MAP; 00308 00309 ULONG 00310 MiBuildKernelMap ( 00311 IN ULONG NumberOfElements, 00312 IN OUT PKERN_MAP KernelMap 00313 ); 00314 00315 NTSTATUS 00316 MmMemoryUsage ( 00317 IN PVOID Buffer, 00318 IN ULONG Size, 00319 IN ULONG Type, 00320 OUT PULONG OutLength 00321 ) 00322 00323 /*++ 00324 00325 Routine Description: 00326 00327 This routine (debugging only) dumps the current memory usage by 00328 walking the PFN database. 00329 00330 Arguments: 00331 00332 Buffer - Supplies a buffer in which to copy the data. 00333 00334 Size - Supplies the size of the buffer. 00335 00336 Type - Supplies a value of 0 to dump everything, 00337 a value of 1 to dump only valid pages. 00338 00339 OutLength - Returns how much data was written into the buffer. 00340 00341 Return Value: 00342 00343 None. 00344 00345 --*/ 00346 00347 { 00348 PMMPFN LastPfn; 00349 PMMPFN Pfn1; 00350 PMMPFN Pfn2; 00351 PSUBSECTION Subsection; 00352 KIRQL OldIrql; 00353 PSYSTEM_MEMORY_INFORMATION MemInfo; 00354 PSYSTEM_MEMORY_INFO Info; 00355 PSYSTEM_MEMORY_INFO InfoStart; 00356 PSYSTEM_MEMORY_INFO InfoEnd; 00357 PUCHAR String; 00358 PUCHAR Master; 00359 PCONTROL_AREA ControlArea; 00360 BOOLEAN Found; 00361 BOOLEAN FoundMap; 00362 PMDL Mdl; 00363 NTSTATUS status = STATUS_SUCCESS; 00364 ULONG Length; 00365 PEPROCESS Process; 00366 PUCHAR End; 00367 PCONTROL_AREA SavedControl[MM_SAVED_CONTROL]; 00368 PSYSTEM_MEMORY_INFO SavedInfo[MM_SAVED_CONTROL]; 00369 ULONG j; 00370 ULONG ControlCount = 0; 00371 PUCHAR PagedSection = NULL; 00372 ULONG Failed; 00373 UCHAR PageFileMapped[] = "PageFile Mapped"; 00374 UCHAR MetaFile[] = "Fs Meta File"; 00375 UCHAR NoName[] = "No File Name"; 00376 UCHAR NonPagedPool[] = "NonPagedPool"; 00377 UCHAR PagedPool[] = "PagedPool"; 00378 UCHAR KernelStack[] = "Kernel Stack"; 00379 PUCHAR NameString; 00380 KERN_MAP KernMap[MM_KERN_MAP_SIZE]; 00381 ULONG KernSize; 00382 ULONG_PTR VirtualAddress; 00383 PLDR_DATA_TABLE_ENTRY DataTableEntry; 00384 00385 Mdl = MmCreateMdl (NULL, Buffer, Size); 00386 try { 00387 00388 MmProbeAndLockPages (Mdl, KeGetPreviousMode(), IoWriteAccess); 00389 00390 } except (EXCEPTION_EXECUTE_HANDLER) { 00391 00392 ExFreePool (Mdl); 00393 return GetExceptionCode(); 00394 } 00395 00396 MemInfo = MmGetSystemAddressForMdl (Mdl); 00397 InfoStart = &MemInfo->Memory[0]; 00398 InfoEnd = InfoStart; 00399 End = (PUCHAR)MemInfo + Size; 00400 00401 Pfn1 = MI_PFN_ELEMENT (MmLowestPhysicalPage + 1); 00402 LastPfn = MI_PFN_ELEMENT(MmHighestPhysicalPage); 00403 00404 KernSize = MiBuildKernelMap (MM_KERN_MAP_SIZE, &KernMap[0]); 00405 00406 LOCK_PFN (OldIrql); 00407 00408 while (Pfn1 < LastPfn) { 00409 00410 Info = InfoStart; 00411 FoundMap = FALSE; 00412 00413 if ((Pfn1->u3.e1.PageLocation != FreePageList) && 00414 (Pfn1->u3.e1.PageLocation != ZeroedPageList) && 00415 (Pfn1->u3.e1.PageLocation != BadPageList)) { 00416 00417 if (Type == 1) { 00418 if (Pfn1->u3.e1.PageLocation != ActiveAndValid) { 00419 Pfn1++; 00420 continue; 00421 } 00422 } 00423 if (Pfn1->OriginalPte.u.Soft.Prototype == 1) { 00424 Subsection = MiGetSubsectionAddress (&Pfn1->OriginalPte); 00425 Master = (PUCHAR)Subsection->ControlArea; 00426 ControlArea = Subsection->ControlArea; 00427 if (!MmIsAddressValid(ControlArea)) { 00428 DbgPrint ("Pfnp %lx not found %lx\n",Pfn1 - MmPfnDatabase, 00429 (ULONG_PTR)Pfn1->PteAddress); 00430 Pfn1++; 00431 continue; 00432 } 00433 if (ControlArea->FilePointer != NULL) { 00434 if (!MmIsAddressValid(ControlArea->FilePointer)) { 00435 Pfn1++; 00436 continue; 00437 } 00438 } 00439 00440 } else { 00441 00442 FoundMap = TRUE; 00443 VirtualAddress = (ULONG_PTR)MiGetVirtualAddressMappedByPte (Pfn1->PteAddress); 00444 00445 if ((VirtualAddress >= (ULONG_PTR)MmPagedPoolStart) && 00446 (VirtualAddress <= (ULONG_PTR)MmPagedPoolEnd)) { 00447 00448 // 00449 // This is paged pool, put it in the paged pool cell. 00450 // 00451 00452 Master = MM_PAGED_POOL_MARK; 00453 00454 } else if ((VirtualAddress >= (ULONG_PTR)MmNonPagedPoolStart) && 00455 (VirtualAddress <= (ULONG_PTR)MmNonPagedPoolEnd)) { 00456 00457 // 00458 // This is nonpaged pool, put it in the nonpaged pool cell. 00459 // 00460 00461 Master = MM_NONPAGED_POOL_MARK; 00462 00463 } else { 00464 FoundMap = FALSE; 00465 for (j=0; j < KernSize; j++) { 00466 if ((VirtualAddress >= KernMap[j].StartVa) && 00467 (VirtualAddress < KernMap[j].EndVa)) { 00468 Master = (PUCHAR)&KernMap[j]; 00469 FoundMap = TRUE; 00470 break; 00471 } 00472 } 00473 } 00474 00475 if (!FoundMap) { 00476 if (((ULONG_PTR)Pfn1->PteAddress >= MmSystemPtesStart[SystemPteSpace]) && 00477 ((ULONG_PTR)Pfn1->PteAddress <= MmSystemPtesEnd[SystemPteSpace])) { 00478 00479 // 00480 // This is kernel stack. 00481 // 00482 00483 Master = MM_KERNEL_STACK_MARK; 00484 } else { 00485 Pfn2 = MI_PFN_ELEMENT (Pfn1->PteFrame); 00486 Master = (PUCHAR)Pfn2->PteFrame; 00487 if (((ULONG_PTR)Master == 0) || ((ULONG_PTR)Master > MmHighestPhysicalPage)) { 00488 DbgPrint ("Pfn %lx not found %lx\n",Pfn1 - MmPfnDatabase, 00489 (ULONG_PTR)Pfn1->PteAddress); 00490 Pfn1++; 00491 continue; 00492 } 00493 } 00494 } 00495 } 00496 00497 // 00498 // See if there is already a master info block. 00499 // 00500 00501 Found = FALSE; 00502 while (Info < InfoEnd) { 00503 if (Info->StringOffset == Master) { 00504 Found = TRUE; 00505 break; 00506 } 00507 Info += 1; 00508 } 00509 00510 if (!Found) { 00511 00512 Info = InfoEnd; 00513 InfoEnd += 1; 00514 if ((PUCHAR)Info >= ((PUCHAR)InfoStart + Size) - sizeof(SYSTEM_MEMORY_INFO)) { 00515 status = STATUS_DATA_OVERRUN; 00516 goto Done; 00517 } 00518 00519 RtlZeroMemory (Info, sizeof(*Info)); 00520 Info->StringOffset = Master; 00521 } 00522 00523 if ((Pfn1->u3.e1.PageLocation == StandbyPageList) || 00524 (Pfn1->u3.e1.PageLocation == TransitionPage)) { 00525 00526 Info->TransitionCount += 1; 00527 00528 } else if ((Pfn1->u3.e1.PageLocation == ModifiedPageList) || 00529 (Pfn1->u3.e1.PageLocation == ModifiedNoWritePageList)) { 00530 Info->ModifiedCount += 1; 00531 00532 } else { 00533 Info->ValidCount += 1; 00534 if (Type == 1) { 00535 if ((Pfn1->PteAddress >= MiGetPdeAddress (0x0)) && 00536 (Pfn1->PteAddress <= MiGetPdeAddress (0xFFFFFFFF))) { 00537 Info->PageTableCount += 1; 00538 } 00539 } 00540 } 00541 if (Type != 1) { 00542 if ((Pfn1->PteAddress >= MiGetPdeAddress (0x0)) && 00543 (Pfn1->PteAddress <= MiGetPdeAddress (0xFFFFFFFF))) { 00544 Info->PageTableCount += 1; 00545 } 00546 } 00547 } 00548 Pfn1++; 00549 } 00550 00551 MemInfo->StringStart = (ULONG)((PUCHAR)Buffer + (ULONG_PTR)InfoEnd - (PUCHAR)MemInfo); 00552 String = (PUCHAR)InfoEnd; 00553 00554 // 00555 // Process strings... 00556 // 00557 00558 Info = InfoStart; 00559 while (Info < InfoEnd) { 00560 if (Info->StringOffset > (PUCHAR)MM_HIGHEST_USER_ADDRESS) { 00561 00562 // 00563 // Make sure this is not stacks or other areas. 00564 // 00565 00566 Length = 0; 00567 ControlArea = NULL; 00568 00569 if (Info->StringOffset == MM_NONPAGED_POOL_MARK) { 00570 Length = 14; 00571 NameString = NonPagedPool; 00572 } else if (Info->StringOffset == MM_PAGED_POOL_MARK) { 00573 Length = 14; 00574 NameString = PagedPool; 00575 } else if (Info->StringOffset == MM_KERNEL_STACK_MARK) { 00576 Length = 14; 00577 NameString = KernelStack; 00578 } else if (((PUCHAR)Info->StringOffset >= (PUCHAR)&KernMap[0]) && 00579 ((PUCHAR)Info->StringOffset <= (PUCHAR)&KernMap[MM_KERN_MAP_SIZE])) { 00580 00581 DataTableEntry = ((PKERN_MAP)Info->StringOffset)->Entry; 00582 NameString = (PUCHAR)DataTableEntry->BaseDllName.Buffer; 00583 Length = DataTableEntry->BaseDllName.Length; 00584 } else { 00585 // 00586 // This points to a control area. 00587 // Get the file name. 00588 // 00589 00590 ControlArea = (PCONTROL_AREA)(Info->StringOffset); 00591 NameString = (PUCHAR)&ControlArea->FilePointer->FileName.Buffer[0]; 00592 } 00593 00594 Info->StringOffset = NULL; 00595 Failed = TRUE; 00596 if (Length == 0) { 00597 if (MmIsAddressValid (&ControlArea->FilePointer->FileName.Length)) { 00598 Length = ControlArea->FilePointer->FileName.Length; 00599 if (Length == 0) { 00600 if (ControlArea->u.Flags.NoModifiedWriting) { 00601 Length = 14; 00602 NameString = MetaFile; 00603 } else if (ControlArea->u.Flags.File == 0) { 00604 NameString = PageFileMapped; 00605 Length = 16; 00606 00607 } else { 00608 NameString = NoName; 00609 Length = 14; 00610 } 00611 } 00612 } 00613 } 00614 00615 if ((String+Length+2) >= End) { 00616 status = STATUS_DATA_OVERRUN; 00617 goto Done; 00618 } 00619 if (MmIsAddressValid (&NameString[0]) && 00620 MmIsAddressValid (&NameString[Length - 1])) { 00621 RtlMoveMemory (String, 00622 NameString, 00623 Length ); 00624 Info->StringOffset = (PUCHAR)Buffer + ((PUCHAR)String - (PUCHAR)MemInfo); 00625 String[Length] = 0; 00626 String[Length + 1] = 0; 00627 String += Length + 2; 00628 Failed = FALSE; 00629 } 00630 if (Failed && ControlArea) { 00631 if (!(ControlArea->u.Flags.BeingCreated || 00632 ControlArea->u.Flags.BeingDeleted) && 00633 (ControlCount < MM_SAVED_CONTROL)) { 00634 SavedControl[ControlCount] = ControlArea; 00635 SavedInfo[ControlCount] = Info; 00636 ControlArea->NumberOfSectionReferences += 1; 00637 ControlCount += 1; 00638 } 00639 } 00640 00641 } else { 00642 00643 // 00644 // Process... 00645 // 00646 00647 Pfn1 = MI_PFN_ELEMENT (PtrToUlong(Info->StringOffset)); 00648 Info->StringOffset = NULL; 00649 if ((String+16) >= End) { 00650 status = STATUS_DATA_OVERRUN; 00651 goto Done; 00652 } 00653 00654 Process = (PEPROCESS)Pfn1->u1.Event; 00655 if (Pfn1->PteAddress == MiGetPteAddress (PDE_BASE)) { 00656 Info->StringOffset = (PUCHAR)Buffer + ((PUCHAR)String - (PUCHAR)MemInfo); 00657 RtlMoveMemory (String, 00658 &Process->ImageFileName[0], 00659 16); 00660 String += 16; 00661 } else { 00662 00663 Info->StringOffset = PagedSection; 00664 if (PagedSection == NULL) { 00665 Info->StringOffset = (PUCHAR)Buffer + ((PUCHAR)String - (PUCHAR)MemInfo); 00666 RtlMoveMemory (String, 00667 &PageFileMapped, 00668 16); 00669 PagedSection = Info->StringOffset; 00670 String += 16; 00671 } 00672 } 00673 } 00674 00675 Info += 1; 00676 } 00677 00678 Done: 00679 UNLOCK_PFN (OldIrql); 00680 while (ControlCount != 0) { 00681 00682 // 00683 // Process all the pagable name strings. 00684 // 00685 00686 ControlCount -= 1; 00687 ControlArea = SavedControl[ControlCount]; 00688 Info = SavedInfo[ControlCount]; 00689 NameString = (PUCHAR)&ControlArea->FilePointer->FileName.Buffer[0]; 00690 Length = ControlArea->FilePointer->FileName.Length; 00691 if (Length == 0) { 00692 if (ControlArea->u.Flags.NoModifiedWriting) { 00693 Length = 12; 00694 NameString = MetaFile; 00695 } else if (ControlArea->u.Flags.File == 0) { 00696 NameString = PageFileMapped; 00697 Length = 16; 00698 00699 } else { 00700 NameString = NoName; 00701 Length = 12; 00702 } 00703 } 00704 if ((String+Length+2) >= End) { 00705 status = STATUS_DATA_OVERRUN; 00706 } 00707 if (status != STATUS_DATA_OVERRUN) { 00708 RtlMoveMemory (String, 00709 NameString, 00710 Length ); 00711 Info->StringOffset = (PUCHAR)Buffer + ((PUCHAR)String - (PUCHAR)MemInfo); 00712 String[Length] = 0; 00713 String[Length + 1] = 0; 00714 String += Length + 2; 00715 } 00716 00717 LOCK_PFN (OldIrql); 00718 ControlArea->NumberOfSectionReferences -= 1; 00719 MiCheckForControlAreaDeletion (ControlArea); 00720 UNLOCK_PFN (OldIrql); 00721 } 00722 *OutLength = (ULONG)((PUCHAR)String - (PUCHAR)MemInfo); 00723 MmUnlockPages (Mdl); 00724 ExFreePool (Mdl);; 00725 return status; 00726 } 00727 #else //DBG 00728 00729 NTSTATUS 00730 MmMemoryUsage ( 00731 IN PVOID Buffer, 00732 IN ULONG Size, 00733 IN ULONG Type, 00734 OUT PULONG OutLength 00735 ) 00736 { 00737 return STATUS_NOT_IMPLEMENTED; 00738 } 00739 00740 #endif //DBG 00741 00742 00743 #if DBG 00744 ULONG 00745 MiBuildKernelMap ( 00746 IN ULONG NumberOfElements, 00747 IN OUT PKERN_MAP KernelMap 00748 ) 00749 00750 { 00751 PLIST_ENTRY Next; 00752 PLIST_ENTRY NextEntry; 00753 PLDR_DATA_TABLE_ENTRY DataTableEntry; 00754 ULONG i = 0; 00755 00756 KeEnterCriticalRegion(); 00757 ExAcquireResourceShared (&PsLoadedModuleResource, TRUE); 00758 00759 NextEntry = PsLoadedModuleList.Flink; 00760 do { 00761 00762 DataTableEntry = CONTAINING_RECORD(NextEntry, 00763 LDR_DATA_TABLE_ENTRY, 00764 InLoadOrderLinks); 00765 00766 KernelMap[i].Entry = DataTableEntry; 00767 KernelMap[i].StartVa = (ULONG_PTR)DataTableEntry->DllBase; 00768 KernelMap[i].EndVa = KernelMap[i].StartVa + 00769 (ULONG_PTR)DataTableEntry->SizeOfImage; 00770 i += 1; 00771 if (i == NumberOfElements) { 00772 break; 00773 } 00774 Next = DataTableEntry->InLoadOrderLinks.Flink; 00775 00776 NextEntry = NextEntry->Flink; 00777 } while (NextEntry != &PsLoadedModuleList); 00778 00779 ExReleaseResource (&PsLoadedModuleResource); 00780 KeLeaveCriticalRegion(); 00781 00782 return i; 00783 } 00784 #endif //DBG 00785 00786 00787 00788 #if DBG 00789 VOID 00790 MiFlushCache ( 00791 VOID 00792 ) 00793 00794 /*++ 00795 00796 Routine Description: 00797 00798 This routine (debugging only) flushes the "cache" by moving 00799 all pages from the standby list to the free list. Modified 00800 pages are not affected. 00801 00802 Arguments: 00803 00804 None. 00805 00806 Return Value: 00807 00808 None. 00809 00810 --*/ 00811 00812 { 00813 KIRQL OldIrql; 00814 PFN_NUMBER Page; 00815 00816 LOCK_PFN (OldIrql); 00817 00818 while (MmPageLocationList[StandbyPageList]->Total != 0) { 00819 00820 Page = MiRemovePageFromList (MmPageLocationList[StandbyPageList]); 00821 00822 // 00823 // A page has been removed from the standby list. The 00824 // PTE which refers to this page is currently in the transition 00825 // state and must have its original contents restored to free 00826 // the last reference to this physical page. 00827 // 00828 00829 // MiRestoreTransitionPte (Page); <-- Done by MiRemove above 00830 00831 // 00832 // Put the page into the free list. 00833 // 00834 00835 MiInsertPageInList (MmPageLocationList[FreePageList], Page); 00836 } 00837 00838 UNLOCK_PFN (OldIrql); 00839 return; 00840 } 00841 VOID 00842 MiDumpReferencedPages ( 00843 VOID 00844 ) 00845 00846 /*++ 00847 00848 Routine Description: 00849 00850 This routine (debugging only) dumps all PFN entries which appear 00851 to be locked in memory for i/o. 00852 00853 Arguments: 00854 00855 None. 00856 00857 Return Value: 00858 00859 None. 00860 00861 --*/ 00862 00863 { 00864 KIRQL OldIrql; 00865 PMMPFN Pfn1; 00866 PMMPFN PfnLast; 00867 00868 LOCK_PFN (OldIrql); 00869 00870 Pfn1 = MI_PFN_ELEMENT (MmLowestPhysicalPage); 00871 PfnLast = MI_PFN_ELEMENT (MmHighestPhysicalPage); 00872 00873 while (Pfn1 <= PfnLast) { 00874 00875 if ((Pfn1->u2.ShareCount == 0) && (Pfn1->u3.e2.ReferenceCount != 0)) { 00876 MiFormatPfn (Pfn1); 00877 } 00878 00879 if (Pfn1->u3.e2.ReferenceCount > 1) { 00880 MiFormatPfn (Pfn1); 00881 } 00882 00883 Pfn1 += 1; 00884 } 00885 00886 UNLOCK_PFN (OldIrql); 00887 return; 00888 } 00889 00890 #endif //DBG

Generated on Sat May 15 19:39:46 2004 for test by doxygen 1.3.7