ReactOS 0.4.15-dev-7906-g1b85a5f
procsup.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/procsup.c
5 * PURPOSE: ARM Memory Manager Process Related Management
6 * PROGRAMMERS: ReactOS Portable Systems Group
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <ntoskrnl.h>
12#define NDEBUG
13#include <debug.h>
14
15#define MODULE_INVOLVED_IN_ARM3
16#include <mm/ARM3/miarm.h>
17
18/* GLOBALS ********************************************************************/
19
23
24/* PRIVATE FUNCTIONS **********************************************************/
25
31{
32 PMMVAD_LONG Vad;
34 ULONG_PTR HighestAddress, RandomBase;
35 ULONG AlignedSize;
36 LARGE_INTEGER CurrentTime;
37
39 if (!NT_SUCCESS(Status))
40 return Status;
41
42 /* Allocate a VAD */
43 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
44 if (!Vad)
45 {
47 goto FailPath;
48 }
49
50 /* Setup the primary flags with the size, and make it commited, private, RW */
51 Vad->u.LongFlags = 0;
53 Vad->u.VadFlags.MemCommit = TRUE;
56 Vad->u.VadFlags.NoChange = TRUE;
57 Vad->u1.Parent = NULL;
58
59 /* Setup the secondary flags to make it a secured, writable, long VAD */
60 Vad->u2.LongFlags2 = 0;
62 Vad->u2.VadFlags2.LongVad = TRUE;
64
65 Vad->ControlArea = NULL; // For Memory-Area hack
67
68 /* Check if this is a PEB creation */
69 ASSERT(sizeof(TEB) != sizeof(PEB));
70 if (Size == sizeof(PEB))
71 {
72 /* Create a random value to select one page in a 64k region */
73 KeQueryTickCount(&CurrentTime);
74 CurrentTime.LowPart &= (_64K / PAGE_SIZE) - 1;
75
76 /* Calculate a random base address */
77 RandomBase = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1;
78 RandomBase -= CurrentTime.LowPart << PAGE_SHIFT;
79
80 /* Make sure the base address is not too high */
81 AlignedSize = ROUND_TO_PAGES(Size);
82 if ((RandomBase + AlignedSize) > (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1)
83 {
84 RandomBase = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS + 1 - AlignedSize;
85 }
86
87 /* Calculate the highest allowed address */
88 HighestAddress = RandomBase + AlignedSize - 1;
89 }
90 else
91 {
92 HighestAddress = (ULONG_PTR)MM_HIGHEST_VAD_ADDRESS;
93 }
94
95 *BaseAddress = 0;
98 Size,
99 HighestAddress,
100 PAGE_SIZE,
102 if (!NT_SUCCESS(Status))
103 {
104 ExFreePoolWithTag(Vad, 'ldaV');
106 goto FailPath;
107 }
108
109
110 /* Success */
111 return STATUS_SUCCESS;
112
113FailPath:
115
116 return Status;
117}
118
119VOID
120NTAPI
122 IN PTEB Teb)
123{
124 ULONG_PTR TebEnd;
126 PMMVAD Vad;
127 PMM_AVL_TABLE VadTree = &Process->VadRoot;
128 DPRINT("Deleting TEB: %p in %16s\n", Teb, Process->ImageFileName);
129
130 /* TEB is one page */
131 TebEnd = (ULONG_PTR)Teb + ROUND_TO_PAGES(sizeof(TEB)) - 1;
132
133 /* Attach to the process */
135
136 /* Lock the process address space */
137 KeAcquireGuardedMutex(&Process->AddressCreationLock);
138
139 /* Find the VAD, make sure it's a TEB VAD */
140 Vad = MiLocateAddress(Teb);
141 DPRINT("Removing node for VAD: %lx %lx\n", Vad->StartingVpn, Vad->EndingVpn);
142 ASSERT(Vad != NULL);
143 if (Vad->StartingVpn != ((ULONG_PTR)Teb >> PAGE_SHIFT))
144 {
145 /* Bug in the AVL code? */
146 DPRINT1("Corrupted VAD!\n");
147 }
148 else
149 {
150 /* Sanity checks for a valid TEB VAD */
151 ASSERT((Vad->StartingVpn == ((ULONG_PTR)Teb >> PAGE_SHIFT) &&
152 (Vad->EndingVpn == (TebEnd >> PAGE_SHIFT))));
153 ASSERT(Vad->u.VadFlags.NoChange == TRUE);
156
157 /* Lock the working set */
159
160 /* Remove this VAD from the tree */
161 ASSERT(VadTree->NumberGenericTableElements >= 1);
162 MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
163
164 /* Delete the pages */
166
167 /* Release the working set */
169
170 /* Remove the VAD */
171 ExFreePool(Vad);
172
173 /* Return the quota the VAD used */
175 }
176
177 /* Release the address space lock */
178 KeReleaseGuardedMutex(&Process->AddressCreationLock);
179
180 /* Detach */
182}
183
184VOID
185NTAPI
187 IN BOOLEAN GuiStack)
188{
189 PMMPTE PointerPte;
190 PFN_NUMBER PageFrameNumber, PageTableFrameNumber;
191 PFN_COUNT StackPages;
192 PMMPFN Pfn1, Pfn2;
193 ULONG i;
195 PSLIST_ENTRY SListEntry;
196
197 //
198 // This should be the guard page, so decrement by one
199 //
200 PointerPte = MiAddressToPte(StackBase);
201 PointerPte--;
202
203 //
204 // If this is a small stack, just push the stack onto the dead stack S-LIST
205 //
206 if (!GuiStack)
207 {
209 {
210 SListEntry = ((PSLIST_ENTRY)StackBase) - 1;
212 return;
213 }
214 }
215
216 //
217 // Calculate pages used
218 //
219 StackPages = BYTES_TO_PAGES(GuiStack ?
221
222 /* Acquire the PFN lock */
223 OldIrql = MiAcquirePfnLock();
224
225 //
226 // Loop them
227 //
228 for (i = 0; i < StackPages; i++)
229 {
230 //
231 // Check if this is a valid PTE
232 //
233 if (PointerPte->u.Hard.Valid == 1)
234 {
235 /* Get the PTE's page */
236 PageFrameNumber = PFN_FROM_PTE(PointerPte);
237 Pfn1 = MiGetPfnEntry(PageFrameNumber);
238
239 /* Now get the page of the page table mapping it */
240 PageTableFrameNumber = Pfn1->u4.PteFrame;
241 Pfn2 = MiGetPfnEntry(PageTableFrameNumber);
242
243 /* Remove a shared reference, since the page is going away */
244 MiDecrementShareCount(Pfn2, PageTableFrameNumber);
245
246 /* Set the special pending delete marker */
247 MI_SET_PFN_DELETED(Pfn1);
248
249 /* And now delete the actual stack page */
250 MiDecrementShareCount(Pfn1, PageFrameNumber);
251 }
252
253 //
254 // Next one
255 //
256 PointerPte--;
257 }
258
259 //
260 // We should be at the guard page now
261 //
262 ASSERT(PointerPte->u.Hard.Valid == 0);
263
264 /* Release the PFN lock */
265 MiReleasePfnLock(OldIrql);
266
267 //
268 // Release the PTEs
269 //
270 MiReleaseSystemPtes(PointerPte, StackPages + 1, SystemPteSpace);
271}
272
273PVOID
274NTAPI
276 IN UCHAR Node)
277{
278 PFN_COUNT StackPtes, StackPages;
279 PMMPTE PointerPte, StackPte;
281 MMPTE TempPte, InvalidPte;
283 PFN_NUMBER PageFrameIndex;
284 ULONG i;
285 PSLIST_ENTRY SListEntry;
286
287 //
288 // Calculate pages needed
289 //
290 if (GuiStack)
291 {
292 //
293 // We'll allocate 64KB stack, but only commit 12K
294 //
295 StackPtes = BYTES_TO_PAGES(MmLargeStackSize);
297 }
298 else
299 {
300 //
301 // If the dead stack S-LIST has a stack on it, use it instead of allocating
302 // new system PTEs for this stack
303 //
305 {
307 if (SListEntry != NULL)
308 {
309 BaseAddress = (SListEntry + 1);
310 return BaseAddress;
311 }
312 }
313
314 //
315 // We'll allocate 12K and that's it
316 //
318 StackPages = StackPtes;
319 }
320
321 //
322 // Reserve stack pages, plus a guard page
323 //
324 StackPte = MiReserveSystemPtes(StackPtes + 1, SystemPteSpace);
325 if (!StackPte) return NULL;
326
327 //
328 // Get the stack address
329 //
330 BaseAddress = MiPteToAddress(StackPte + StackPtes + 1);
331
332 //
333 // Select the right PTE address where we actually start committing pages
334 //
335 PointerPte = StackPte;
336 if (GuiStack) PointerPte += BYTES_TO_PAGES(MmLargeStackSize -
338
339
340 /* Setup the temporary invalid PTE */
341 MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
342
343 /* Setup the template stack PTE */
345
346 //
347 // Acquire the PFN DB lock
348 //
349 OldIrql = MiAcquirePfnLock();
350
351 //
352 // Loop each stack page
353 //
354 for (i = 0; i < StackPages; i++)
355 {
356 //
357 // Next PTE
358 //
359 PointerPte++;
360
361 /* Get a page and write the current invalid PTE */
363 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
364 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
365 MI_WRITE_INVALID_PTE(PointerPte, InvalidPte);
366
367 /* Initialize the PFN entry for this page */
368 MiInitializePfn(PageFrameIndex, PointerPte, 1);
369
370 /* Write the valid PTE */
371 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
372 MI_WRITE_VALID_PTE(PointerPte, TempPte);
373 }
374
375 //
376 // Release the PFN lock
377 //
378 MiReleasePfnLock(OldIrql);
379
380 //
381 // Return the stack address
382 //
383 return BaseAddress;
384}
385
387NTAPI
389 IN ULONG GrowSize)
390{
392 PMMPTE LimitPte, NewLimitPte, LastPte;
394 MMPTE TempPte, InvalidPte;
395 PFN_NUMBER PageFrameIndex;
396
397 //
398 // Make sure the stack did not overflow
399 //
400 ASSERT(((ULONG_PTR)Thread->StackBase - (ULONG_PTR)Thread->StackLimit) <=
402
403 //
404 // Get the current stack limit
405 //
406 LimitPte = MiAddressToPte(Thread->StackLimit);
407 ASSERT(LimitPte->u.Hard.Valid == 1);
408
409 //
410 // Get the new one and make sure this isn't a retarded request
411 //
412 NewLimitPte = MiAddressToPte((PVOID)((ULONG_PTR)StackPointer - GrowSize));
413 if (NewLimitPte == LimitPte) return STATUS_SUCCESS;
414
415 //
416 // Now make sure you're not going past the reserved space
417 //
418 LastPte = MiAddressToPte((PVOID)((ULONG_PTR)Thread->StackBase -
420 if (NewLimitPte < LastPte)
421 {
422 //
423 // Sorry!
424 //
426 }
427
428 //
429 // Calculate the number of new pages
430 //
431 LimitPte--;
432
433 /* Setup the temporary invalid PTE */
434 MI_MAKE_SOFTWARE_PTE(&InvalidPte, MM_NOACCESS);
435
436 //
437 // Acquire the PFN DB lock
438 //
439 OldIrql = MiAcquirePfnLock();
440
441 //
442 // Loop each stack page
443 //
444 while (LimitPte >= NewLimitPte)
445 {
446 /* Get a page and write the current invalid PTE */
448 MI_SET_PROCESS2(PsGetCurrentProcess()->ImageFileName);
449 PageFrameIndex = MiRemoveAnyPage(MI_GET_NEXT_COLOR());
450 MI_WRITE_INVALID_PTE(LimitPte, InvalidPte);
451
452 /* Initialize the PFN entry for this page */
453 MiInitializePfn(PageFrameIndex, LimitPte, 1);
454
455 /* Setup the template stack PTE */
456 MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, LimitPte, MM_READWRITE, PageFrameIndex);
457
458 /* Write the valid PTE */
459 MI_WRITE_VALID_PTE(LimitPte--, TempPte);
460 }
461
462 //
463 // Release the PFN lock
464 //
465 MiReleasePfnLock(OldIrql);
466
467 //
468 // Set the new limit
469 //
470 Thread->StackLimit = (ULONG_PTR)MiPteToAddress(NewLimitPte);
471 return STATUS_SUCCESS;
472}
473
475NTAPI
477{
478 //
479 // Call the extended version
480 //
482}
483
485NTAPI
487 IN UCHAR MemoryPriority)
488{
489 UCHAR OldPriority;
490
491 //
492 // Check if we have less then 16MB of Physical Memory
493 //
494 if ((MmSystemSize == MmSmallSystem) &&
495 (MmNumberOfPhysicalPages < ((15 * 1024 * 1024) / PAGE_SIZE)))
496 {
497 //
498 // Always use background priority
499 //
500 MemoryPriority = MEMORY_PRIORITY_BACKGROUND;
501 }
502
503 //
504 // Save the old priority and update it
505 //
506 OldPriority = (UCHAR)Process->Vm.Flags.MemoryPriority;
507 Process->Vm.Flags.MemoryPriority = MemoryPriority;
508
509 //
510 // Return the old priority
511 //
512 return OldPriority;
513}
514
516NTAPI
518 IN PINITIAL_PEB InitialPeb,
519 OUT PPEB *BasePeb)
520{
521 PPEB Peb = NULL;
523 SIZE_T ViewSize = 0;
524 PVOID TableBase = NULL;
525 PIMAGE_NT_HEADERS NtHeaders;
526 PIMAGE_LOAD_CONFIG_DIRECTORY ImageConfigData;
528 USHORT Characteristics;
530 SectionOffset.QuadPart = (ULONGLONG)0;
531 *BasePeb = NULL;
532
533 //
534 // Attach to Process
535 //
537
538 //
539 // Map NLS Tables
540 //
543 &TableBase,
544 0,
545 0,
547 &ViewSize,
548 ViewShare,
551 DPRINT("NLS Tables at: %p\n", TableBase);
552 if (!NT_SUCCESS(Status))
553 {
554 /* Cleanup and exit */
556 return Status;
557 }
558
559 //
560 // Allocate the PEB
561 //
563 DPRINT("PEB at: %p\n", Peb);
564 if (!NT_SUCCESS(Status))
565 {
566 /* Cleanup and exit */
568 return Status;
569 }
570
571 //
572 // Use SEH in case we can't load the PEB
573 //
575 {
576 //
577 // Initialize the PEB
578 //
579 RtlZeroMemory(Peb, sizeof(PEB));
580
581 //
582 // Set up data
583 //
584 Peb->ImageBaseAddress = Process->SectionBaseAddress;
585 Peb->InheritedAddressSpace = InitialPeb->InheritedAddressSpace;
586 Peb->Mutant = InitialPeb->Mutant;
587 Peb->ImageUsesLargePages = InitialPeb->ImageUsesLargePages;
588
589 //
590 // NLS
591 //
595
596 //
597 // Default Version Data (could get changed below)
598 //
601 Peb->OSBuildNumber = (USHORT)(NtBuildNumber & 0x3FFF);
603 Peb->OSCSDVersion = (USHORT)CmNtCSDVersion;
604
605 //
606 // Heap and Debug Data
607 //
609 Peb->BeingDebugged = (BOOLEAN)(Process->DebugPort != NULL);
617 Peb->MaximumNumberOfHeaps = (PAGE_SIZE - sizeof(PEB)) / sizeof(PVOID);
618 Peb->ProcessHeaps = (PVOID*)(Peb + 1);
619
620 //
621 // Session ID
622 //
623 if (Process->Session) Peb->SessionId = MmGetSessionId(Process);
624 }
626 {
627 //
628 // Fail
629 //
632 }
633 _SEH2_END;
634
635 //
636 // Use SEH in case we can't load the image
637 //
639 {
640 //
641 // Get NT Headers
642 //
644 Characteristics = NtHeaders->FileHeader.Characteristics;
645 }
647 {
648 //
649 // Fail
650 //
653 }
654 _SEH2_END;
655
656 //
657 // Parse the headers
658 //
659 if (NtHeaders)
660 {
661 //
662 // Use SEH in case we can't load the headers
663 //
665 {
666 //
667 // Get the Image Config Data too
668 //
670 TRUE,
672 (PULONG)&ViewSize);
673 if (ImageConfigData)
674 {
675 //
676 // Probe it
677 //
678 ProbeForRead(ImageConfigData,
680 sizeof(ULONG));
681 }
682
683 //
684 // Write subsystem data
685 //
689
690 //
691 // Check for version data
692 //
693 if (NtHeaders->OptionalHeader.Win32VersionValue)
694 {
695 //
696 // Extract values and write them
697 //
699 Peb->OSMinorVersion = (NtHeaders->OptionalHeader.Win32VersionValue >> 8) & 0xFF;
700 Peb->OSBuildNumber = (NtHeaders->OptionalHeader.Win32VersionValue >> 16) & 0x3FFF;
701 Peb->OSPlatformId = (NtHeaders->OptionalHeader.Win32VersionValue >> 30) ^ 2;
702
703 /* Process CSD version override */
704 if ((ImageConfigData) && (ImageConfigData->CSDVersion))
705 {
706 /* Take the value from the image configuration directory */
707 Peb->OSCSDVersion = ImageConfigData->CSDVersion;
708 }
709 }
710
711 /* Process optional process affinity mask override */
712 if ((ImageConfigData) && (ImageConfigData->ProcessAffinityMask))
713 {
714 /* Take the value from the image configuration directory */
715 ProcessAffinityMask = ImageConfigData->ProcessAffinityMask;
716 }
717
718 //
719 // Check if this is a UP image
720 if (Characteristics & IMAGE_FILE_UP_SYSTEM_ONLY)
721 {
722 //
723 // Force it to use CPU 0
724 //
725 /* FIXME: this should use the MmRotatingUniprocessorNumber */
727 }
728 else
729 {
730 //
731 // Whatever was configured
732 //
734 }
735 }
737 {
738 //
739 // Fail
740 //
743 }
744 _SEH2_END;
745 }
746
747 //
748 // Detach from the Process
749 //
751 *BasePeb = Peb;
752 return STATUS_SUCCESS;
753}
754
756NTAPI
759 IN PINITIAL_TEB InitialTeb,
760 OUT PTEB *BaseTeb)
761{
762 PTEB Teb;
764 *BaseTeb = NULL;
765
766 //
767 // Attach to Target
768 //
770
771 //
772 // Allocate the TEB
773 //
774 Status = MiCreatePebOrTeb(Process, sizeof(TEB), (PULONG_PTR)&Teb);
775 if (!NT_SUCCESS(Status))
776 {
777 /* Cleanup and exit */
779 return Status;
780 }
781
782 //
783 // Use SEH in case we can't load the TEB
784 //
786 {
787 //
788 // Initialize the PEB
789 //
790 RtlZeroMemory(Teb, sizeof(TEB));
791
792 //
793 // Set TIB Data
794 //
795#ifdef _M_AMD64
796 Teb->NtTib.ExceptionList = NULL;
797#else
799#endif
800 Teb->NtTib.Self = (PNT_TIB)Teb;
801
802 //
803 // Identify this as an OS/2 V3.0 ("Cruiser") TIB
804 //
805 Teb->NtTib.Version = 30 << 8;
806
807 //
808 // Set TEB Data
809 //
810 Teb->ClientId = *ClientId;
811 Teb->RealClientId = *ClientId;
814
815 //
816 // Check if we have a grandparent TEB
817 //
818 if ((InitialTeb->PreviousStackBase == NULL) &&
819 (InitialTeb->PreviousStackLimit == NULL))
820 {
821 //
822 // Use initial TEB values
823 //
824 Teb->NtTib.StackBase = InitialTeb->StackBase;
825 Teb->NtTib.StackLimit = InitialTeb->StackLimit;
826 Teb->DeallocationStack = InitialTeb->AllocatedStackBase;
827 }
828 else
829 {
830 //
831 // Use grandparent TEB values
832 //
833 Teb->NtTib.StackBase = InitialTeb->PreviousStackBase;
834 Teb->NtTib.StackLimit = InitialTeb->PreviousStackLimit;
835 }
836
837 //
838 // Initialize the static unicode string
839 //
842 }
844 {
845 //
846 // Get error code
847 //
849 }
850 _SEH2_END;
851
852 //
853 // Return
854 //
856 *BaseTeb = Teb;
857 return Status;
858}
859
860#ifdef _M_AMD64
861static
863MiInsertSharedUserPageVad(
865{
866 PMMVAD_LONG Vad;
869
870 if (Process->QuotaBlock != NULL)
871 {
873 if (!NT_SUCCESS(Status))
874 {
875 DPRINT1("Ran out of quota.\n");
876 return Status;
877 }
878 }
879
880 /* Allocate a VAD */
881 Vad = ExAllocatePoolWithTag(NonPagedPool, sizeof(MMVAD_LONG), 'ldaV');
882 if (Vad == NULL)
883 {
884 DPRINT1("Failed to allocate VAD for shared user page\n");
886 goto FailPath;
887 }
888
889 /* Setup the primary flags with the size, and make it private, RO */
890 Vad->u.LongFlags = 0;
891 Vad->u.VadFlags.CommitCharge = 0;
892 Vad->u.VadFlags.NoChange = TRUE;
893 Vad->u.VadFlags.VadType = VadNone;
894 Vad->u.VadFlags.MemCommit = FALSE;
897 Vad->u1.Parent = NULL;
898
899 /* Setup the secondary flags to make it a secured, readonly, long VAD */
900 Vad->u2.LongFlags2 = 0;
902 Vad->u2.VadFlags2.LongVad = TRUE;
903 Vad->u2.VadFlags2.ReadOnly = FALSE;
904
905 Vad->ControlArea = NULL; // For Memory-Area hack
906 Vad->FirstPrototypePte = NULL;
907
908 /* Insert it into the process VAD table */
912 PAGE_SIZE,
914 PAGE_SIZE,
916 if (!NT_SUCCESS(Status))
917 {
918 DPRINT1("Failed to insert shared user VAD\n");
919 ExFreePoolWithTag(Vad, 'ldaV');
920 goto FailPath;
921 }
922
923 /* Success */
924 return STATUS_SUCCESS;
925
926FailPath:
927 if (Process->QuotaBlock != NULL)
929
930 return Status;
931}
932#endif
933
935NTAPI
937 IN PEPROCESS ProcessClone OPTIONAL,
938 IN PVOID Section OPTIONAL,
941{
943 SIZE_T ViewSize = 0;
944 PVOID ImageBase = 0;
945 PMMPTE PointerPte;
947 PMMPDE PointerPde;
948 PMMPFN Pfn;
949 PFN_NUMBER PageFrameNumber;
953 USHORT Length = 0;
954
955#if (_MI_PAGING_LEVELS >= 3)
956 PMMPPE PointerPpe;
957#endif
958#if (_MI_PAGING_LEVELS == 4)
959 PMMPXE PointerPxe;
960#endif
961
962 /* We should have a PDE */
963 ASSERT(Process->Pcb.DirectoryTableBase[0] != 0);
964 ASSERT(Process->PdeUpdateNeeded == FALSE);
965
966 /* Attach to the process */
968
969 /* The address space should now been in phase 1 or 0 */
970 ASSERT(Process->AddressSpaceInitialized <= 1);
971 Process->AddressSpaceInitialized = 2;
972
973 /* Initialize the Addresss Space lock */
974 KeInitializeGuardedMutex(&Process->AddressCreationLock);
975 Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
976
977 /* Initialize AVL tree */
978 ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
979 Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
980
981 /* Lock our working set */
983
984 /* Lock PFN database */
985 OldIrql = MiAcquirePfnLock();
986
987 /* Setup the PFN for the PDE base of this process */
988#if (_MI_PAGING_LEVELS == 4)
989 PointerPte = MiAddressToPte(PXE_BASE);
990#elif (_MI_PAGING_LEVELS == 3)
991 PointerPte = MiAddressToPte(PPE_BASE);
992#else
993 PointerPte = MiAddressToPte(PDE_BASE);
994#endif
995 PageFrameNumber = PFN_FROM_PTE(PointerPte);
996 ASSERT(Process->Pcb.DirectoryTableBase[0] == PageFrameNumber * PAGE_SIZE);
997 MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
998
999 /* Do the same for hyperspace */
1000 PointerPde = MiAddressToPde(HYPER_SPACE);
1001 PageFrameNumber = PFN_FROM_PTE(PointerPde);
1002 MiInitializePfn(PageFrameNumber, (PMMPTE)PointerPde, TRUE);
1003#if (_MI_PAGING_LEVELS == 2)
1004 ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
1005#endif
1006
1007#if (_MI_PAGING_LEVELS >= 3)
1008 PointerPpe = MiAddressToPpe((PVOID)HYPER_SPACE);
1009 PageFrameNumber = PFN_FROM_PTE(PointerPpe);
1010 MiInitializePfn(PageFrameNumber, PointerPpe, TRUE);
1011#if (_MI_PAGING_LEVELS == 3)
1012 ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
1013#endif
1014#endif
1015#if (_MI_PAGING_LEVELS == 4)
1016 PointerPxe = MiAddressToPxe((PVOID)HYPER_SPACE);
1017 PageFrameNumber = PFN_FROM_PTE(PointerPxe);
1018 MiInitializePfn(PageFrameNumber, PointerPxe, TRUE);
1019 ASSERT(Process->Pcb.DirectoryTableBase[1] == PageFrameNumber * PAGE_SIZE);
1020#endif
1021
1022 /* Do the same for the Working set list */
1023 PointerPte = MiAddressToPte(MmWorkingSetList);
1024 PageFrameNumber = PFN_FROM_PTE(PointerPte);
1025 MiInitializePfn(PageFrameNumber, PointerPte, TRUE);
1026
1027 /* All our pages are now active & valid. Release the lock. */
1028 MiReleasePfnLock(OldIrql);
1029
1030 /* This should be in hyper space, but not in the mapping range */
1031 Process->Vm.VmWorkingSetList = MmWorkingSetList;
1033
1034 /* Now initialize the working set list */
1036
1037 /* The rule is that the owner process is always in the FLINK of the PDE's PFN entry */
1038 Pfn = MiGetPfnEntry(Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT);
1039 ASSERT(Pfn->u4.PteFrame == MiGetPfnEntryIndex(Pfn));
1040 ASSERT(Pfn->u1.WsIndex == 0);
1041 Pfn->u1.Event = (PKEVENT)Process;
1042
1043 /* Sanity check */
1044 ASSERT(Process->PhysicalVadRoot == NULL);
1045
1046 /* Release the process working set */
1048
1049#ifdef _M_AMD64
1050 /* On x64 we need a VAD for the shared user page */
1051 Status = MiInsertSharedUserPageVad(Process);
1052 if (!NT_SUCCESS(Status))
1053 {
1054 DPRINT1("MiCreateSharedUserPageVad() failed: 0x%lx\n", Status);
1055 return Status;
1056 }
1057#endif
1058
1059 /* Check if there's a Section Object */
1060 if (Section)
1061 {
1062 /* Determine the image file name and save it to EPROCESS */
1064 FileName = FileObject->FileName;
1065 Source = (PWCHAR)((PCHAR)FileName.Buffer + FileName.Length);
1066 if (FileName.Buffer)
1067 {
1068 /* Loop the file name*/
1069 while (Source > FileName.Buffer)
1070 {
1071 /* Make sure this isn't a backslash */
1073 {
1074 /* If so, stop it here */
1075 Source++;
1076 break;
1077 }
1078 else
1079 {
1080 /* Otherwise, keep going */
1081 Length++;
1082 }
1083 }
1084 }
1085
1086 /* Copy the to the process and truncate it to 15 characters if necessary */
1087 Destination = Process->ImageFileName;
1088 Length = min(Length, sizeof(Process->ImageFileName) - 1);
1089 while (Length--) *Destination++ = (UCHAR)*Source++;
1091
1092 /* Check if caller wants an audit name */
1093 if (AuditName)
1094 {
1095 /* Setup the audit name */
1097 if (!NT_SUCCESS(Status))
1098 {
1099 /* Fail */
1101 return Status;
1102 }
1103 }
1104
1105 /* Map the section */
1106 Status = MmMapViewOfSection(Section,
1107 Process,
1108 (PVOID*)&ImageBase,
1109 0,
1110 0,
1111 NULL,
1112 &ViewSize,
1113 ViewUnmap,
1114 MEM_COMMIT,
1116
1117 /* Save the pointer */
1118 Process->SectionBaseAddress = ImageBase;
1119 }
1120
1121 /* Be nice and detach */
1123
1124 /* Return status to caller */
1125 return Status;
1126}
1127
1128CODE_SEG("INIT")
1130NTAPI
1132 IN PULONG_PTR DirectoryTableBase)
1133{
1134 /* Share the directory base with the idle process */
1135 DirectoryTableBase[0] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[0];
1136 DirectoryTableBase[1] = PsGetCurrentProcess()->Pcb.DirectoryTableBase[1];
1137
1138 /* Initialize the Addresss Space */
1139 KeInitializeGuardedMutex(&Process->AddressCreationLock);
1140 KeInitializeSpinLock(&Process->HyperSpaceLock);
1141 Process->Vm.WorkingSetExpansionLinks.Flink = NULL;
1142 ASSERT(Process->VadRoot.NumberGenericTableElements == 0);
1143 Process->VadRoot.BalancedRoot.u1.Parent = &Process->VadRoot.BalancedRoot;
1144
1145 /* Use idle process Working set */
1146 Process->Vm.VmWorkingSetList = PsGetCurrentProcess()->Vm.VmWorkingSetList;
1147 Process->WorkingSetPage = PsGetCurrentProcess()->WorkingSetPage;
1148
1149 /* Done */
1150 Process->HasAddressSpace = TRUE;//??
1151 return STATUS_SUCCESS;
1152}
1153
1154CODE_SEG("INIT")
1156NTAPI
1158{
1159 /* Lock the VAD, ARM3-owned ranges away */
1160 return STATUS_SUCCESS;
1161}
1162
1163BOOLEAN
1164NTAPI
1167 OUT PULONG_PTR DirectoryTableBase)
1168{
1169 KIRQL OldIrql;
1170 PFN_NUMBER TableBaseIndex, HyperIndex, WsListIndex;
1171 ULONG Color;
1172
1173 /* Make sure we don't already have a page directory setup */
1174 ASSERT(Process->Pcb.DirectoryTableBase[0] == 0);
1175 ASSERT(Process->Pcb.DirectoryTableBase[1] == 0);
1176 ASSERT(Process->WorkingSetPage == 0);
1177
1178 /* Choose a process color */
1179 Process->NextPageColor = (USHORT)RtlRandom(&MmProcessColorSeed);
1180
1181 /* Setup the hyperspace lock */
1182 KeInitializeSpinLock(&Process->HyperSpaceLock);
1183
1184 /* Lock PFN database */
1185 OldIrql = MiAcquirePfnLock();
1186
1187 /*
1188 * Get a page for the table base, one for hyper space & one for the working set list.
1189 * The PFNs for these pages will be initialized in MmInitializeProcessAddressSpace,
1190 * when we are already attached to the process.
1191 * The other pages (if any) are allocated in the arch-specific part.
1192 */
1195 TableBaseIndex = MiRemoveZeroPageSafe(Color);
1196 if (!TableBaseIndex)
1197 {
1198 /* No zero pages, grab a free one */
1199 TableBaseIndex = MiRemoveAnyPage(Color);
1200
1201 /* Zero it outside the PFN lock */
1202 MiReleasePfnLock(OldIrql);
1203 MiZeroPhysicalPage(TableBaseIndex);
1204 OldIrql = MiAcquirePfnLock();
1205 }
1208 HyperIndex = MiRemoveZeroPageSafe(Color);
1209 if (!HyperIndex)
1210 {
1211 /* No zero pages, grab a free one */
1212 HyperIndex = MiRemoveAnyPage(Color);
1213
1214 /* Zero it outside the PFN lock */
1215 MiReleasePfnLock(OldIrql);
1216 MiZeroPhysicalPage(HyperIndex);
1217 OldIrql = MiAcquirePfnLock();
1218 }
1221 WsListIndex = MiRemoveZeroPageSafe(Color);
1222 if (!WsListIndex)
1223 {
1224 /* No zero pages, grab a free one */
1225 WsListIndex = MiRemoveAnyPage(Color);
1226
1227 /* Zero it outside the PFN lock */
1228 MiReleasePfnLock(OldIrql);
1229 MiZeroPhysicalPage(WsListIndex);
1230 }
1231 else
1232 {
1233 /* Release the PFN lock */
1234 MiReleasePfnLock(OldIrql);
1235 }
1236
1237 /* Set the base directory pointers */
1238 Process->WorkingSetPage = WsListIndex;
1239 DirectoryTableBase[0] = TableBaseIndex << PAGE_SHIFT;
1240 DirectoryTableBase[1] = HyperIndex << PAGE_SHIFT;
1241
1242 /* Perform the arch-specific parts */
1243 if (!MiArchCreateProcessAddressSpace(Process, DirectoryTableBase))
1244 {
1245 OldIrql = MiAcquirePfnLock();
1246 MiInsertPageInFreeList(WsListIndex);
1247 MiInsertPageInFreeList(HyperIndex);
1248 MiInsertPageInFreeList(TableBaseIndex);
1249 MiReleasePfnLock(OldIrql);
1250 Process->WorkingSetPage = 0;
1251 DirectoryTableBase[0] = 0;
1252 DirectoryTableBase[1] = 0;
1253 return FALSE;
1254 }
1255
1256 /* Switch to phase 1 initialization */
1257 ASSERT(Process->AddressSpaceInitialized == 0);
1258 Process->AddressSpaceInitialized = 1;
1259
1260 /* Add the process to the session */
1262 return TRUE;
1263}
1264
1265VOID
1266NTAPI
1268{
1269 PMMVAD Vad;
1270 PMM_AVL_TABLE VadTree;
1272
1273 /* Remove from the session */
1275
1276 /* Abort early, when the address space wasn't fully initialized */
1277 if (Process->AddressSpaceInitialized < 2)
1278 {
1279 DPRINT1("Incomplete address space for Process %p. Might leak resources.\n",
1280 Process);
1281 return;
1282 }
1283
1284 /* Lock the process address space from changes */
1287
1288 /* VM is deleted now */
1289 Process->VmDeleted = TRUE;
1291
1292 /* Enumerate the VADs */
1293 VadTree = &Process->VadRoot;
1294 while (VadTree->NumberGenericTableElements)
1295 {
1296 /* Grab the current VAD */
1297 Vad = (PMMVAD)VadTree->BalancedRoot.RightChild;
1298
1299 /* Check for old-style memory areas */
1300 if (Vad->u.VadFlags.Spare == 1)
1301 {
1302 /* Let RosMm handle this */
1304 continue;
1305 }
1306
1307 /* Lock the working set */
1309
1310 /* Remove this VAD from the tree */
1311 ASSERT(VadTree->NumberGenericTableElements >= 1);
1312 MiRemoveNode((PMMADDRESS_NODE)Vad, VadTree);
1313
1314 /* Only regular VADs supported for now */
1315 ASSERT(Vad->u.VadFlags.VadType == VadNone);
1316
1317 /* Check if this is a section VAD */
1318 if (!(Vad->u.VadFlags.PrivateMemory) && (Vad->ControlArea))
1319 {
1320 /* Remove the view */
1322 }
1323 else
1324 {
1325 /* Delete the addresses */
1327 (Vad->EndingVpn << PAGE_SHIFT) | (PAGE_SIZE - 1),
1328 Vad);
1329
1330 /* Release the working set */
1332 }
1333
1334 /* Skip ARM3 fake VADs, they'll be freed by MmDeleteProcessAddresSpace */
1335 if (Vad->u.VadFlags.Spare == 1)
1336 {
1337 /* Set a flag so MmDeleteMemoryArea knows to free, but not to remove */
1338 Vad->u.VadFlags.Spare = 2;
1339 continue;
1340 }
1341
1342 /* Free the VAD memory */
1343 ExFreePool(Vad);
1344
1345 /* Return the quota the VAD used */
1347 }
1348
1349 /* Lock the working set */
1351 ASSERT(Process->CloneRoot == NULL);
1352 ASSERT(Process->PhysicalVadRoot == NULL);
1353
1354 /* Delete the shared user data section */
1356
1357 /* Release the working set */
1359
1360 /* Release the address space */
1362}
1363
1364VOID
1365NTAPI
1367{
1368 PMMPFN Pfn1, Pfn2;
1369 KIRQL OldIrql;
1370 PFN_NUMBER PageFrameIndex;
1371
1372#ifndef _M_AMD64
1374 RemoveEntryList(&Process->MmProcessLinks);
1376#endif
1377
1378 //ASSERT(Process->CommitCharge == 0);
1379
1380 /* Remove us from the list */
1382 if (Process->Vm.WorkingSetExpansionLinks.Flink != NULL)
1383 RemoveEntryList(&Process->Vm.WorkingSetExpansionLinks);
1385
1386 /* Acquire the PFN lock */
1387 OldIrql = MiAcquirePfnLock();
1388
1389 /* Check for fully initialized process */
1390 if (Process->AddressSpaceInitialized == 2)
1391 {
1392 /* Map the working set page and its page table */
1393 Pfn1 = MiGetPfnEntry(Process->WorkingSetPage);
1394 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1395
1396 /* Nuke it */
1397 MI_SET_PFN_DELETED(Pfn1);
1398 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1399 MiDecrementShareCount(Pfn1, Process->WorkingSetPage);
1400 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1401
1402 /* Now map hyperspace and its page table */
1403 PageFrameIndex = Process->Pcb.DirectoryTableBase[1] >> PAGE_SHIFT;
1404 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1405 Pfn2 = MiGetPfnEntry(Pfn1->u4.PteFrame);
1406
1407 /* Nuke it */
1408 MI_SET_PFN_DELETED(Pfn1);
1409 MiDecrementShareCount(Pfn2, Pfn1->u4.PteFrame);
1410 MiDecrementShareCount(Pfn1, PageFrameIndex);
1411 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1412
1413 /* Finally, nuke the PDE itself */
1414 PageFrameIndex = Process->Pcb.DirectoryTableBase[0] >> PAGE_SHIFT;
1415 Pfn1 = MiGetPfnEntry(PageFrameIndex);
1416 MI_SET_PFN_DELETED(Pfn1);
1417 MiDecrementShareCount(Pfn1, PageFrameIndex);
1418 MiDecrementShareCount(Pfn1, PageFrameIndex);
1419
1420 /* Page table is now dead. Bye bye... */
1421 ASSERT((Pfn1->u3.e2.ReferenceCount == 0) || (Pfn1->u3.e1.WriteInProgress));
1422 }
1423 else
1424 {
1425 DPRINT1("Deleting partially initialized address space of Process %p. Might leak resources.\n",
1426 Process);
1427 }
1428
1429 /* Release the PFN lock */
1430 MiReleasePfnLock(OldIrql);
1431
1432 /* Drop a reference on the session */
1434
1435 /* Clear out the PDE pages */
1436 Process->Pcb.DirectoryTableBase[0] = 0;
1437 Process->Pcb.DirectoryTableBase[1] = 0;
1438}
1439
1440
1441/* SYSTEM CALLS ***************************************************************/
1442
1444NTAPI
1446 IN OUT PULONG_PTR NumberOfPages,
1447 IN OUT PULONG_PTR UserPfnArray)
1448{
1451}
1452
1454NTAPI
1456 IN ULONG_PTR NumberOfPages,
1457 IN OUT PULONG_PTR UserPfnArray)
1458{
1461}
1462
1464NTAPI
1466 IN ULONG_PTR NumberOfPages,
1467 IN OUT PULONG_PTR UserPfnArray)
1468{
1471}
1472
1474NTAPI
1476 IN OUT PULONG_PTR NumberOfPages,
1477 IN OUT PULONG_PTR UserPfnArray)
1478{
1481}
1482
1483/* EOF */
SIZE_T MmHeapSegmentReserve
Definition: mminit.c:366
SIZE_T MmHeapDeCommitFreeBlockThreshold
Definition: mminit.c:369
SIZE_T MmHeapDeCommitTotalFreeThreshold
Definition: mminit.c:368
SIZE_T MmHeapSegmentCommit
Definition: mminit.c:367
#define CODE_SEG(...)
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define PDE_BASE
Definition: winldr.c:21
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define UNIMPLEMENTED
Definition: debug.h:115
#define MM_READWRITE
Definition: bootanim.c:19
#define MM_READONLY
Definition: bootanim.c:18
struct _PEB PEB
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define PAGE_READONLY
Definition: compat.h:138
ULONG_PTR KAFFINITY
Definition: compat.h:85
#define RtlImageDirectoryEntryToData
Definition: compat.h:809
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG
Definition: compat.h:153
#define RtlImageNtHeader
Definition: compat.h:806
struct _NT_TIB * PNT_TIB
PPEB Peb
Definition: dllmain.c:27
#define ULONG_PTR
Definition: config.h:101
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define PKEVENT
Definition: env_spec_w32.h:70
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
struct _FileName FileName
Definition: fatprocs.h:896
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_In_opt_ PFILE_OBJECT _In_opt_ PETHREAD Thread
Definition: fltkernel.h:2653
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define KeGetCurrentThread
Definition: hal.h:55
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define USER_SHARED_DATA
Definition: pstypes.h:51
#define MEMORY_PRIORITY_BACKGROUND
Definition: pstypes.h:124
@ ProcessAffinityMask
Definition: winternl.h:877
CCHAR KeNumberProcessors
Definition: krnlinit.c:35
if(dx< 0)
Definition: linetemp.h:194
PMMVAD NTAPI MiLocateAddress(IN PVOID VirtualAddress)
Definition: vadnode.c:116
@ SystemPteSpace
Definition: miarm.h:403
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1531
VOID NTAPI MiDeleteVirtualAddresses(IN ULONG_PTR Va, IN ULONG_PTR EndingAddress, IN PMMVAD Vad)
Definition: virtual.c:530
SIZE_T MmMinimumStackCommitInBytes
Definition: mminit.c:370
VOID NTAPI MiRemoveNode(IN PMMADDRESS_NODE Node, IN PMM_AVL_TABLE Table)
Definition: vadnode.c:440
MM_SYSTEMSIZE MmSystemSize
Definition: mminit.c:326
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:209
VOID NTAPI MiSessionAddProcess(IN PEPROCESS NewProcess)
Definition: session.c:423
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:194
VOID NTAPI MiInsertPageInFreeList(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:611
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:232
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
VOID NTAPI MiRemoveMappedView(IN PEPROCESS CurrentProcess, IN PMMVAD Vad)
Definition: section.c:766
#define MI_MAKE_SOFTWARE_PTE(p, x)
Definition: miarm.h:189
#define _64K
Definition: miarm.h:23
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:773
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1544
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
FORCEINLINE VOID MiUnlockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1194
FORCEINLINE VOID MiUnlockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1239
FORCEINLINE VOID MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte, IN MMPTE InvalidPte)
Definition: miarm.h:992
VOID NTAPI MiSessionRemoveProcess(VOID)
Definition: session.c:392
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
#define MM_NOACCESS
Definition: miarm.h:65
NTSTATUS NTAPI MiInsertVadEx(_Inout_ PMMVAD Vad, _In_ ULONG_PTR *BaseAddress, _In_ SIZE_T ViewSize, _In_ ULONG_PTR HighestAddress, _In_ ULONG_PTR Alignment, _In_ ULONG AllocationType)
Definition: vadnode.c:282
ULONG MmLargeStackSize
Definition: mminit.c:262
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
VOID NTAPI MiInitializePfn(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN BOOLEAN Modified)
Definition: pfnlist.c:970
LARGE_INTEGER MmCriticalSectionTimeout
Definition: mminit.c:388
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:233
FORCEINLINE VOID MiLockProcessWorkingSet(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1124
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2415
FORCEINLINE VOID MiLockProcessWorkingSetUnsafe(IN PEPROCESS Process, IN PETHREAD Thread)
Definition: miarm.h:1169
#define PCHAR
Definition: match.c:90
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define min(a, b)
Definition: monoChain.cc:55
#define _In_
Definition: ms_sal.h:308
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define MM_SHARED_USER_DATA_VA
Definition: mmtypes.h:48
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER SectionOffset
Definition: mmfuncs.h:407
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
@ VadNone
Definition: mmtypes.h:204
struct _MMVAD * PMMVAD
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3004
NTSYSAPI ULONG NTAPI RtlRandom(_Inout_ PULONG Seed)
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
#define EXCEPTION_CHAIN_END
Definition: rtltypes.h:63
#define MEM_TOP_DOWN
Definition: nt_native.h:1321
#define PAGE_READWRITE
Definition: nt_native.h:1304
@ ViewUnmap
Definition: nt_native.h:1279
@ ViewShare
Definition: nt_native.h:1278
#define MEM_COMMIT
Definition: nt_native.h:1313
#define ANSI_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
ULONG ExpOemCodePageDataOffset
Definition: init.c:86
ULONG NtMajorVersion
Definition: init.c:45
ULONG ExpUnicodeCaseTableDataOffset
Definition: init.c:87
ULONG NtGlobalFlag
Definition: init.c:54
PVOID ExpNlsSectionPointer
Definition: init.c:90
ULONG ExpAnsiCodePageDataOffset
Definition: init.c:86
ULONG NtMinorVersion
Definition: init.c:46
ULONG CmNtCSDVersion
Definition: init.c:59
LCID PsDefaultThreadLocaleId
Definition: locale.c:24
#define HYPER_SPACE
Definition: mm.h:14
#define MI_MAPPING_RANGE_END
Definition: mm.h:48
#define MM_HIGHEST_VAD_ADDRESS
Definition: mm.h:46
#define HYPER_SPACE_END
Definition: mm.h:15
FORCEINLINE PMMPTE MiAddressToPpe(PVOID Address)
Definition: mm.h:161
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToAddress(_Pte)
Definition: mm.h:116
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:1047
#define MI_SET_PROCESS2(x)
Definition: mm.h:319
@ MI_USAGE_PAGE_TABLE
Definition: mm.h:334
@ MI_USAGE_PAGE_DIRECTORY
Definition: mm.h:335
@ MI_USAGE_KERNEL_STACK_EXPANSION
Definition: mm.h:329
@ MI_USAGE_KERNEL_STACK
Definition: mm.h:328
FORCEINLINE VOID MmLockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1691
PFILE_OBJECT NTAPI MmGetFileObjectForSection(IN PVOID Section)
Definition: section.c:1737
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:1067
VOID NTAPI MiRosCleanupMemoryArea(PEPROCESS Process, PMMVAD Vad)
Definition: marea.c:521
FORCEINLINE VOID MmUnlockAddressSpace(PMMSUPPORT AddressSpace)
Definition: mm.h:1704
#define MI_SET_USAGE(x)
Definition: mm.h:317
NTSTATUS NTAPI SeInitializeProcessAuditName(_In_ PFILE_OBJECT FileObject, _In_ BOOLEAN DoAudit, _Out_ POBJECT_NAME_INFORMATION *AuditInfo)
Initializes a process audit name and returns it to the caller.
Definition: audit.c:105
NTSTATUS NTAPI MmInitializeHandBuiltProcess2(IN PEPROCESS Process)
Definition: procsup.c:1157
NTSTATUS NTAPI NtFreeUserPhysicalPages(IN HANDLE ProcessHandle, IN OUT PULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1475
ULONG MmProcessColorSeed
Definition: procsup.c:20
SLIST_HEADER MmDeadStackSListHead
Definition: procsup.c:22
VOID NTAPI MmCleanProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1267
PVOID NTAPI MmCreateKernelStack(IN BOOLEAN GuiStack, IN UCHAR Node)
Definition: procsup.c:275
NTSTATUS NTAPI MmCreateTeb(IN PEPROCESS Process, IN PCLIENT_ID ClientId, IN PINITIAL_TEB InitialTeb, OUT PTEB *BaseTeb)
Definition: procsup.c:757
VOID NTAPI MmDeleteTeb(IN PEPROCESS Process, IN PTEB Teb)
Definition: procsup.c:121
VOID NTAPI MmDeleteProcessAddressSpace(IN PEPROCESS Process)
Definition: procsup.c:1366
VOID NTAPI MmDeleteKernelStack(IN PVOID StackBase, IN BOOLEAN GuiStack)
Definition: procsup.c:186
NTSTATUS NTAPI MmCreatePeb(IN PEPROCESS Process, IN PINITIAL_PEB InitialPeb, OUT PPEB *BasePeb)
Definition: procsup.c:517
BOOLEAN NTAPI MmCreateProcessAddressSpace(IN ULONG MinWs, IN PEPROCESS Process, OUT PULONG_PTR DirectoryTableBase)
Definition: procsup.c:1165
NTSTATUS NTAPI MmInitializeProcessAddressSpace(IN PEPROCESS Process, IN PEPROCESS ProcessClone OPTIONAL, IN PVOID Section OPTIONAL, IN OUT PULONG Flags, IN POBJECT_NAME_INFORMATION *AuditName OPTIONAL)
Definition: procsup.c:936
NTSTATUS NTAPI MmInitializeHandBuiltProcess(IN PEPROCESS Process, IN PULONG_PTR DirectoryTableBase)
Definition: procsup.c:1131
NTSTATUS NTAPI NtMapUserPhysicalPages(IN PVOID VirtualAddresses, IN ULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1455
NTSTATUS NTAPI MmGrowKernelStack(IN PVOID StackPointer)
Definition: procsup.c:476
NTSTATUS NTAPI MmSetMemoryPriorityProcess(IN PEPROCESS Process, IN UCHAR MemoryPriority)
Definition: procsup.c:486
NTSTATUS NTAPI NtAllocateUserPhysicalPages(IN HANDLE ProcessHandle, IN OUT PULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1445
NTSTATUS NTAPI MiCreatePebOrTeb(IN PEPROCESS Process, IN ULONG Size, OUT PULONG_PTR BaseAddress)
Definition: procsup.c:28
NTSTATUS NTAPI NtMapUserPhysicalPagesScatter(IN PVOID *VirtualAddresses, IN ULONG_PTR NumberOfPages, IN OUT PULONG_PTR UserPfnArray)
Definition: procsup.c:1465
NTSTATUS NTAPI MmGrowKernelStackEx(IN PVOID StackPointer, IN ULONG GrowSize)
Definition: procsup.c:388
ULONG MmMaximumDeadKernelStacks
Definition: procsup.c:21
BOOLEAN MiArchCreateProcessAddressSpace(_In_ PEPROCESS Process, _In_ PULONG_PTR DirectoryTableBase)
Definition: procsup.c:21
#define STATUS_STACK_OVERFLOW
Definition: ntstatus.h:489
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:540
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define BOOLEAN
Definition: pedump.c:73
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_FILE_UP_SYSTEM_ONLY
Definition: pedump.c:170
VOID NTAPI KeDetachProcess(VOID)
Definition: procobj.c:621
VOID NTAPI KeAttachProcess(IN PKPROCESS Process)
Definition: procobj.c:582
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
NTSTATUS NTAPI PsChargeProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Charges the non paged pool quota of a given process.
Definition: quota.c:811
VOID NTAPI PsReturnProcessNonPagedPoolQuota(_In_ PEPROCESS Process, _In_ SIZE_T Amount)
Returns the non paged quota pool that the process was taking up.
Definition: quota.c:938
#define KeQueryTickCount(CurrentCount)
Definition: ke.h:43
#define KERNEL_STACK_SIZE
#define KERNEL_LARGE_STACK_COMMIT
#define PXE_BASE
#define PPE_BASE
ULONG PFN_NUMBER
Definition: ke.h:9
NTSTATUS NTAPI MmMapViewOfSection(IN PVOID SectionObject, IN PEPROCESS Process, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3996
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
ULONG NtBuildNumber
Definition: init.c:50
ULONG PageFrameNumber
Definition: mmtypes.h:109
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
IMAGE_FILE_HEADER FileHeader
Definition: ntddk_ex.h:183
ULONG_PTR StartingVpn
Definition: mmtypes.h:653
struct _MMADDRESS_NODE * RightChild
Definition: mmtypes.h:652
ULONG_PTR EndingVpn
Definition: mmtypes.h:654
USHORT WriteInProgress
Definition: mm.h:362
Definition: mm.h:374
union _MMPFN::@1795 u3
struct _MMPFN::@1795::@1801 e2
ULONG WsIndex
Definition: mm.h:378
MMPFNENTRY e1
Definition: mm.h:397
union _MMPFN::@1793 u1
union _MMPFN::@1798 u4
PKEVENT Event
Definition: mm.h:379
ULONG_PTR PteFrame
Definition: mm.h:418
ULONG64 Valid
Definition: mmtypes.h:150
union _MMPTE::@2330 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG ReadOnly
Definition: mmtypes.h:710
ULONG MultipleSecured
Definition: mmtypes.h:709
ULONG OneSecured
Definition: mmtypes.h:708
ULONG LongVad
Definition: mmtypes.h:711
ULONG_PTR NoChange
Definition: mmtypes.h:693
ULONG_PTR MemCommit
Definition: mmtypes.h:695
ULONG_PTR Protection
Definition: mmtypes.h:696
ULONG_PTR CommitCharge
Definition: mmtypes.h:691
ULONG_PTR Spare
Definition: mmtypes.h:697
ULONG_PTR VadType
Definition: mmtypes.h:694
ULONG_PTR PrivateMemory
Definition: mmtypes.h:698
union _MMVAD_LONG::@2614 u
union _MMVAD_LONG::@2613 u1
PMMPTE FirstPrototypePte
Definition: mmtypes.h:766
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:763
ULONG_PTR LongFlags
Definition: mmtypes.h:762
union _MMVAD_LONG::@2615 u2
PCONTROL_AREA ControlArea
Definition: mmtypes.h:765
PMMVAD Parent
Definition: mmtypes.h:754
ULONG LongFlags2
Definition: mmtypes.h:770
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:771
ULONG_PTR EndingVpn
Definition: mmtypes.h:730
ULONG_PTR StartingVpn
Definition: mmtypes.h:729
MMVAD_FLAGS2 VadFlags2
Definition: mmtypes.h:742
MMVAD_FLAGS VadFlags
Definition: mmtypes.h:734
union _MMVAD::@2612 u2
union _MMVAD::@2611 u
ULONG_PTR NumberGenericTableElements
Definition: mmtypes.h:668
MMADDRESS_NODE BalancedRoot
Definition: mmtypes.h:662
struct _NT_TIB * Self
Definition: compat.h:720
PVOID StackLimit
Definition: compat.h:713
DWORD Version
Definition: compat.h:717
PVOID StackBase
Definition: compat.h:712
struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList
Definition: compat.h:711
ULONG HeapDeCommitTotalFreeThreshold
Definition: ntddk_ex.h:277
ULONG HeapSegmentCommit
Definition: ntddk_ex.h:276
ULONG ImageSubsystem
Definition: ntddk_ex.h:304
ULONG NumberOfProcessors
Definition: ntddk_ex.h:269
ULONG ImageProcessAffinityMask
Definition: ntddk_ex.h:307
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
ULONG SessionId
Definition: btrfs_drv.h:1919
LARGE_INTEGER CriticalSectionTimeout
Definition: ntddk_ex.h:274
ULONG MaximumNumberOfHeaps
Definition: ntddk_ex.h:287
ULONG OSMinorVersion
Definition: ntddk_ex.h:301
PVOID * ProcessHeaps
Definition: ntddk_ex.h:288
ULONG HeapSegmentReserve
Definition: ntddk_ex.h:275
PVOID AnsiCodePageData
Definition: ntddk_ex.h:264
ULONG ImageSubsystemMinorVersion
Definition: ntddk_ex.h:306
BYTE BeingDebugged
Definition: btrfs_drv.h:1909
SIZE_T MinimumStackCommit
Definition: winternl.h:358
HANDLE Mutant
Definition: ntddk_ex.h:243
ULONG OSMajorVersion
Definition: ntddk_ex.h:300
ULONG OSBuildNumber
Definition: ntddk_ex.h:302
PVOID OemCodePageData
Definition: ntddk_ex.h:265
ULONG NtGlobalFlag
Definition: ntddk_ex.h:270
BOOLEAN InheritedAddressSpace
Definition: ntddk_ex.h:239
ULONG ImageSubsystemMajorVersion
Definition: ntddk_ex.h:305
ULONG OSPlatformId
Definition: ntddk_ex.h:303
ULONG HeapDeCommitFreeBlockThreshold
Definition: ntddk_ex.h:278
PVOID UnicodeCaseTableData
Definition: ntddk_ex.h:266
Definition: compat.h:836
WCHAR StaticUnicodeBuffer[261]
Definition: compat.h:877
ULONG CurrentLocale
Definition: compat.h:849
NT_TIB NtTib
Definition: ntddk_ex.h:332
UNICODE_STRING StaticUnicodeString
Definition: compat.h:876
CLIENT_ID ClientId
Definition: compat.h:839
CLIENT_ID RealClientId
Definition: compat.h:861
PPEB ProcessEnvironmentBlock
Definition: ntddk_ex.h:337
PVOID DeallocationStack
Definition: compat.h:878
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
ULONG LowPart
Definition: typedefs.h:106
Definition: dlist.c:348
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Use_decl_annotations_ VOID NTAPI MiInitializeWorkingSetList(_Inout_ PMMSUPPORT WorkingSet)
Definition: wslist.cpp:369
FORCEINLINE USHORT ExQueryDepthSList(_In_ PSLIST_HEADER SListHead)
Definition: exfuncs.h:153
* PFILE_OBJECT
Definition: iotypes.h:1998
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
#define ROUND_TO_PAGES(Size)
#define BYTES_TO_PAGES(Size)
@ MmSmallSystem
Definition: mmtypes.h:145
ULONG PFN_COUNT
Definition: mmtypes.h:102
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define InterlockedPushEntrySList(SListHead, SListEntry)
Definition: rtlfuncs.h:3389
#define InterlockedPopEntrySList(SListHead)
Definition: rtlfuncs.h:3392
#define PSLIST_ENTRY
Definition: rtltypes.h:134
unsigned char UCHAR
Definition: xmlstorage.h:181