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