ReactOS  r74006
session.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/session.c
5  * PURPOSE: Session support routines
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  * Timo Kreuzer (timo.kreuzer@reactos.org)
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 #define MODULE_INVOLVED_IN_ARM3
17 #include <mm/ARM3/miarm.h>
18 
19 /* GLOBALS ********************************************************************/
20 
28 
31 
34 
35 
36 /* PRIVATE FUNCTIONS **********************************************************/
37 
38 VOID
39 NTAPI
41 {
42  /* Initialize the list heads */
43  InitializeListHead(&MiSessionWsList);
44  InitializeListHead(&MmWorkingSetExpansionHead);
45 }
46 
47 BOOLEAN
48 NTAPI
50 {
51  /* Check if it is in range */
52  return MI_IS_SESSION_ADDRESS(Address) ? TRUE : FALSE;
53 }
54 
55 LCID
56 NTAPI
58 {
60  PAGED_CODE();
61 
62  //
63  // Get the current process
64  //
65  Process = PsGetCurrentProcess();
66 
67  //
68  // Check if it's NOT the Session Leader
69  //
70  if (!Process->Vm.Flags.SessionLeader)
71  {
72  //
73  // Make sure it has a valid Session
74  //
75  if (Process->Session)
76  {
77  //
78  // Get the Locale ID
79  //
80  return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
81  }
82  }
83 
84  //
85  // Not a session leader, return the default
86  //
88 }
89 
91 VOID
92 NTAPI
93 MmSetSessionLocaleId(
94  _In_ LCID LocaleId)
95 {
97  PAGED_CODE();
98 
99  /* Get the current process and check if it is in a session */
100  CurrentProcess = PsGetCurrentProcess();
101  if ((CurrentProcess->Vm.Flags.SessionLeader == 0) &&
102  (CurrentProcess->Session != NULL))
103  {
104  /* Set the session locale Id */
105  ((PMM_SESSION_SPACE)CurrentProcess->Session)->LocaleId = LocaleId;
106  }
107  else
108  {
109  /* Set the default locale */
110  PsDefaultThreadLocaleId = LocaleId;
111  }
112 }
113 
114 
115 VOID
116 NTAPI
118 {
119  ULONG Size, BitmapSize;
120  PFN_NUMBER TotalPages;
121 
122  /* Setup the total number of data pages needed for the structure */
123  TotalPages = MI_SESSION_DATA_PAGES_MAXIMUM;
126  TotalPages -= MiSessionDataPages;
127 
128  /* Setup the number of pages needed for session pool tags */
132  ASSERT(MiSessionTagPages <= TotalPages);
134 
135  /* Total pages needed for a session (FIXME: Probably different on PAE/x64) */
137 
138  /* Initialize the lock */
139  KeInitializeGuardedMutex(&MiSessionIdMutex);
140 
141  /* Allocate the bitmap */
142  Size = MI_INITIAL_SESSION_IDS;
143  BitmapSize = ((Size + 31) / 32) * sizeof(ULONG);
144  MiSessionIdBitmap = ExAllocatePoolWithTag(PagedPool,
145  sizeof(RTL_BITMAP) + BitmapSize,
146  TAG_MM);
147  if (MiSessionIdBitmap)
148  {
149  /* Free all the bits */
150  RtlInitializeBitMap(MiSessionIdBitmap,
151  (PVOID)(MiSessionIdBitmap + 1),
152  Size);
153  RtlClearAllBits(MiSessionIdBitmap);
154  }
155  else
156  {
157  /* Die if we couldn't allocate the bitmap */
158  KeBugCheckEx(INSTALL_MORE_MEMORY,
162  0x200);
163  }
164 }
165 
166 VOID
167 NTAPI
169 {
170  KIRQL OldIrql;
171 
172  /* Set the flag while under the expansion lock */
173  OldIrql = MiAcquireExpansionLock();
174  Process->Vm.Flags.SessionLeader = TRUE;
175  MiReleaseExpansionLock(OldIrql);
176 }
177 
178 ULONG
179 NTAPI
181 {
182  PMM_SESSION_SPACE SessionGlobal;
183 
184  /* The session leader is always session zero */
185  if (Process->Vm.Flags.SessionLeader == 1) return 0;
186 
187  /* Otherwise, get the session global, and read the session ID from it */
188  SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
189  if (!SessionGlobal) return 0;
190  return SessionGlobal->SessionId;
191 }
192 
193 ULONG
194 NTAPI
196 {
197  PMM_SESSION_SPACE SessionGlobal;
198 
199  /* The session leader is always session zero */
200  if (Process->Vm.Flags.SessionLeader == 1) return 0;
201 
202  /* Otherwise, get the session global, and read the session ID from it */
203  SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
204  if (!SessionGlobal) return -1;
205  return SessionGlobal->SessionId;
206 }
207 
208 VOID
209 NTAPI
211 {
212  ULONG i, SessionId;
213  PMMPTE PointerPte;
215  PMMPFN Pfn1;
216  KIRQL OldIrql;
217 
218  /* Is there more than just this reference? If so, bail out */
219  if (InterlockedDecrement(&SessionGlobal->ProcessReferenceToSession)) return;
220 
221  /* Get the session ID */
222  SessionId = SessionGlobal->SessionId;
223  DPRINT1("Last process in session %lu going down!!!\n", SessionId);
224 
225  /* Free the session page tables */
226 #ifndef _M_AMD64
227  ExFreePoolWithTag(SessionGlobal->PageTables, 'tHmM');
228 #endif
229  ASSERT(!MI_IS_PHYSICAL_ADDRESS(SessionGlobal));
230 
231  /* Capture the data page PFNs */
232  PointerPte = MiAddressToPte(SessionGlobal);
233  for (i = 0; i < MiSessionDataPages; i++)
234  {
235  PageFrameIndex[i] = PFN_FROM_PTE(PointerPte + i);
236  }
237 
238  /* Release them */
239  MiReleaseSystemPtes(PointerPte, MiSessionDataPages, SystemPteSpace);
240 
241  /* Mark them as deleted */
242  for (i = 0; i < MiSessionDataPages; i++)
243  {
244  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
245  MI_SET_PFN_DELETED(Pfn1);
246  }
247 
248  /* Loop every data page and drop a reference count */
250  for (i = 0; i < MiSessionDataPages; i++)
251  {
252  /* Sanity check that the page is correct, then decrement it */
253  Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
254  ASSERT(Pfn1->u2.ShareCount == 1);
255  ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
256  MiDecrementShareCount(Pfn1, PageFrameIndex[i]);
257  }
258 
259  /* Done playing with pages, release the lock */
261 
262  /* Decrement the number of data pages */
264 
265  /* Free this session ID from the session bitmap */
266  KeAcquireGuardedMutex(&MiSessionIdMutex);
267  ASSERT(RtlCheckBit(MiSessionIdBitmap, SessionId));
268  RtlClearBit(MiSessionIdBitmap, SessionId);
269  KeReleaseGuardedMutex(&MiSessionIdMutex);
270 }
271 
272 VOID
273 NTAPI
275 {
276  PMM_SESSION_SPACE SessionGlobal;
277  KIRQL OldIrql;
278 
279  /* Get the pointer to the global session address */
280  SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
281 
282  /* Acquire the expansion lock */
283  OldIrql = MiAcquireExpansionLock();
284 
285  /* Set delete pending flag, so that processes can no longer attach to this
286  session and the last process that detaches sets the AttachEvent */
287  ASSERT(SessionGlobal->u.Flags.DeletePending == 0);
288  SessionGlobal->u.Flags.DeletePending = 1;
289 
290  /* Check if we have any attached processes */
291  if (SessionGlobal->AttachCount)
292  {
293  /* Initialize the event (it's not in use yet!) */
295 
296  /* Release the expansion lock for the wait */
297  MiReleaseExpansionLock(OldIrql);
298 
299  /* Wait for the event to be set due to the last process detach */
300  KeWaitForSingleObject(&SessionGlobal->AttachEvent, WrVirtualMemory, 0, 0, 0);
301 
302  /* Reacquire the expansion lock */
303  OldIrql = MiAcquireExpansionLock();
304 
305  /* Makes sure we still have the delete flag and no attached processes */
306  ASSERT(MmSessionSpace->u.Flags.DeletePending == 1);
307  ASSERT(MmSessionSpace->AttachCount == 0);
308  }
309 
310  /* Check if the session is in the workingset expansion list */
311  if (SessionGlobal->Vm.WorkingSetExpansionLinks.Flink != NULL)
312  {
313  /* Remove the session from the list and zero the list entry */
315  SessionGlobal->Vm.WorkingSetExpansionLinks.Flink = 0;
316  }
317 
318  /* Check if the session is in the workingset list */
319  if (SessionGlobal->WsListEntry.Flink)
320  {
321  /* Remove the session from the list and zero the list entry */
322  RemoveEntryList(&SessionGlobal->WsListEntry);
323  SessionGlobal->WsListEntry.Flink = NULL;
324  }
325 
326  /* Release the expansion lock */
327  MiReleaseExpansionLock(OldIrql);
328 
329  /* Check for a win32k unload routine */
330  if (SessionGlobal->Win32KDriverUnload)
331  {
332  /* Call it */
333  SessionGlobal->Win32KDriverUnload(NULL);
334  }
335 }
336 
337 
338 VOID
339 NTAPI
341 {
342  PMM_SESSION_SPACE SessionGlobal;
344  ULONG ReferenceCount, SessionId;
345 
346  /* Sanity checks */
347  ASSERT(PsGetCurrentProcess()->ProcessInSession ||
348  ((MmSessionSpace->u.Flags.Initialized == 0) &&
349  (PsGetCurrentProcess()->Vm.Flags.SessionLeader == 1) &&
350  (MmSessionSpace->ReferenceCount == 1)));
351 
352  /* The session bit must be set */
353  SessionId = MmSessionSpace->SessionId;
354  ASSERT(RtlCheckBit(MiSessionIdBitmap, SessionId));
355 
356  /* Get the current process */
357  Process = PsGetCurrentProcess();
358 
359  /* Decrement the process count */
360  InterlockedDecrement(&MmSessionSpace->ResidentProcessCount);
361 
362  /* Decrement the reference count and check if was the last reference */
363  ReferenceCount = InterlockedDecrement(&MmSessionSpace->ReferenceCount);
364  if (ReferenceCount == 0)
365  {
366  /* No more references left, kill the session completely */
368  }
369 
370  /* Check if tis is the session leader or the last process in the session */
371  if ((Process->Vm.Flags.SessionLeader) || (ReferenceCount == 0))
372  {
373  /* Get the global session address before we kill the session mapping */
374  SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
375 
376  /* Delete all session PDEs and flush the TB */
378  BYTES_TO_PAGES(MmSessionSize) * sizeof(MMPDE));
380 
381  /* Is this the session leader? */
382  if (Process->Vm.Flags.SessionLeader)
383  {
384  /* Clean up the references here. */
385  ASSERT(Process->Session == NULL);
387  }
388  }
389 
390  /* Reset the current process' session flag */
392 }
393 
394 VOID
395 NTAPI
397 {
399  KIRQL OldIrql;
400 
401  /* If the process isn't already in a session, or if it's the leader... */
402  if (!(CurrentProcess->Flags & PSF_PROCESS_IN_SESSION_BIT) ||
403  (CurrentProcess->Vm.Flags.SessionLeader))
404  {
405  /* Then there's nothing to do */
406  return;
407  }
408 
409  /* Sanity check */
410  ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
411 
412  /* Acquire the expansion lock while touching the session */
413  OldIrql = MiAcquireExpansionLock();
414 
415  /* Remove the process from the list */
416  RemoveEntryList(&CurrentProcess->SessionProcessLinks);
417 
418  /* Release the lock again */
419  MiReleaseExpansionLock(OldIrql);
420 
421  /* Dereference the session */
423 }
424 
425 VOID
426 NTAPI
428 {
429  PMM_SESSION_SPACE SessionGlobal;
430  KIRQL OldIrql;
431 
432  /* The current process must already be in a session */
434 
435  /* Sanity check */
436  ASSERT(MmIsAddressValid(MmSessionSpace) == TRUE);
437 
438  /* Get the global session */
439  SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
440 
441  /* Increment counters */
442  InterlockedIncrement((PLONG)&SessionGlobal->ReferenceCount);
445 
446  /* Set the session pointer */
447  ASSERT(NewProcess->Session == NULL);
448  NewProcess->Session = SessionGlobal;
449 
450  /* Acquire the expansion lock while touching the session */
451  OldIrql = MiAcquireExpansionLock();
452 
453  /* Insert it into the process list */
454  InsertTailList(&SessionGlobal->ProcessList, &NewProcess->SessionProcessLinks);
455 
456  /* Release the lock again */
457  MiReleaseExpansionLock(OldIrql);
458 
459  /* Set the flag */
460  PspSetProcessFlag(NewProcess, PSF_PROCESS_IN_SESSION_BIT);
461 }
462 
463 NTSTATUS
464 NTAPI
466 {
467  KIRQL OldIrql;
468  PMMPTE PointerPte;
469  PMMPDE PointerPde;
470  MMPTE TempPte;
471  MMPDE TempPde;
472  ULONG Color, Index;
473  PFN_NUMBER PageFrameIndex;
474  PMM_SESSION_SPACE SessionGlobal;
475  BOOLEAN AllocatedPageTable;
476  PMMWSL WorkingSetList;
477 
478  /* Get pointers to session global and the session working set list */
479  SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
480  WorkingSetList = (PMMWSL)MiSessionSpaceWs;
481 
482  /* Fill out the two pointers */
483  MmSessionSpace->Vm.VmWorkingSetList = WorkingSetList;
484  MmSessionSpace->Wsle = (PMMWSLE)WorkingSetList->UsedPageTableEntries;
485 
486  /* Get the PDE for the working set, and check if it's already allocated */
487  PointerPde = MiAddressToPde(WorkingSetList);
488  if (PointerPde->u.Hard.Valid == 1)
489  {
490  /* Nope, we'll have to do it */
491 #ifndef _M_ARM
492  ASSERT(PointerPde->u.Hard.Global == 0);
493 #endif
494  AllocatedPageTable = FALSE;
495  }
496  else
497  {
498  /* Yep, that makes our job easier */
499  AllocatedPageTable = TRUE;
500  }
501 
502  /* Get the PTE for the working set */
503  PointerPte = MiAddressToPte(WorkingSetList);
504 
505  /* Initialize the working set lock, and lock the PFN database */
506  ExInitializePushLock(&SessionGlobal->Vm.WorkingSetMutex);
507  //MmLockPageableSectionByHandle(ExPageLockHandle);
509 
510  /* Check if we need a page table */
511  if (AllocatedPageTable != FALSE)
512  {
513  /* Get a zeroed colored zero page */
514  Color = MI_GET_NEXT_COLOR();
515  PageFrameIndex = MiRemoveZeroPageSafe(Color);
516  if (!PageFrameIndex)
517  {
518  /* No zero pages, grab a free one */
519  PageFrameIndex = MiRemoveAnyPage(Color);
520 
521  /* Zero it outside the PFN lock */
523  MiZeroPhysicalPage(PageFrameIndex);
525  }
526 
527  /* Write a valid PDE for it */
528  TempPde = ValidKernelPdeLocal;
529  TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
530  MI_WRITE_VALID_PDE(PointerPde, TempPde);
531 
532  /* Add this into the list */
533  Index = ((ULONG_PTR)WorkingSetList - (ULONG_PTR)MmSessionBase) >> 22;
534 #ifndef _M_AMD64
535  MmSessionSpace->PageTables[Index] = TempPde;
536 #endif
537  /* Initialize the page directory page, and now zero the working set list itself */
538  MiInitializePfnForOtherProcess(PageFrameIndex,
539  PointerPde,
540  MmSessionSpace->SessionPageDirectoryIndex);
541  KeZeroPages(PointerPte, PAGE_SIZE);
542  }
543 
544  /* Get a zeroed colored zero page */
545  Color = MI_GET_NEXT_COLOR();
546  PageFrameIndex = MiRemoveZeroPageSafe(Color);
547  if (!PageFrameIndex)
548  {
549  /* No zero pages, grab a free one */
550  PageFrameIndex = MiRemoveAnyPage(Color);
551 
552  /* Zero it outside the PFN lock */
554  MiZeroPhysicalPage(PageFrameIndex);
556  }
557 
558  /* Write a valid PTE for it */
559  TempPte = ValidKernelPteLocal;
560  MI_MAKE_DIRTY_PAGE(&TempPte);
561  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
562 
563  /* Initialize the working set list page */
564  MiInitializePfnAndMakePteValid(PageFrameIndex, PointerPte, TempPte);
565 
566  /* Now we can release the PFN database lock */
568 
569  /* Fill out the working set structure */
570  MmSessionSpace->Vm.Flags.SessionSpace = 1;
571  MmSessionSpace->Vm.MinimumWorkingSetSize = 20;
572  MmSessionSpace->Vm.MaximumWorkingSetSize = 384;
573  WorkingSetList->LastEntry = 20;
574  WorkingSetList->HashTable = NULL;
575  WorkingSetList->HashTableSize = 0;
576  WorkingSetList->Wsle = MmSessionSpace->Wsle;
577 
578  /* Acquire the expansion lock while touching the session */
579  OldIrql = MiAcquireExpansionLock();
580 
581  /* Handle list insertions */
582  ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
583  ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
584  InsertTailList(&MiSessionWsList, &SessionGlobal->WsListEntry);
585 
586  ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Flink == NULL);
587  ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Blink == NULL);
588  InsertTailList(&MmWorkingSetExpansionHead,
589  &SessionGlobal->Vm.WorkingSetExpansionLinks);
590 
591  /* Release the lock again */
592  MiReleaseExpansionLock(OldIrql);
593 
594  /* All done, return */
595  //MmUnlockPageableImageSection(ExPageLockHandle);
596  return STATUS_SUCCESS;
597 }
598 
599 NTSTATUS
600 NTAPI
602 {
604  ULONG NewFlags, Flags, Size, i, Color;
605  KIRQL OldIrql;
606  PMMPTE PointerPte, SessionPte;
607  PMMPDE PointerPde, PageTables;
608  PMM_SESSION_SPACE SessionGlobal;
609  MMPTE TempPte;
610  MMPDE TempPde;
612  BOOLEAN Result;
613  PFN_NUMBER SessionPageDirIndex;
616 
617  /* This should not exist yet */
618  ASSERT(MmIsAddressValid(MmSessionSpace) == FALSE);
619 
620  /* Loop so we can set the session-is-creating flag */
621  Flags = Process->Flags;
622  while (TRUE)
623  {
624  /* Check if it's already set */
626  {
627  /* Bail out */
628  DPRINT1("Lost session race\n");
630  }
631 
632  /* Now try to set it */
633  NewFlags = InterlockedCompareExchange((PLONG)&Process->Flags,
634  Flags | PSF_SESSION_CREATION_UNDERWAY_BIT,
635  Flags);
636  if (NewFlags == Flags) break;
637 
638  /* It changed, try again */
639  Flags = NewFlags;
640  }
641 
642  /* Now we should own the flag */
644 
645  /*
646  * Session space covers everything from 0xA0000000 to 0xC0000000.
647  * Allocate enough page tables to describe the entire region
648  */
649  Size = (0x20000000 / PDE_MAPPED_VA) * sizeof(MMPTE);
650  PageTables = ExAllocatePoolWithTag(NonPagedPool, Size, 'tHmM');
651  ASSERT(PageTables != NULL);
652  RtlZeroMemory(PageTables, Size);
653 
654  /* Lock the session ID creation mutex */
655  KeAcquireGuardedMutex(&MiSessionIdMutex);
656 
657  /* Allocate a new Session ID */
658  *SessionId = RtlFindClearBitsAndSet(MiSessionIdBitmap, 1, 0);
659  if (*SessionId == 0xFFFFFFFF)
660  {
661  /* We ran out of session IDs, we should expand */
662  DPRINT1("Too many sessions created. Expansion not yet supported\n");
663  ExFreePoolWithTag(PageTables, 'tHmM');
664  return STATUS_NO_MEMORY;
665  }
666 
667  /* Unlock the session ID creation mutex */
668  KeReleaseGuardedMutex(&MiSessionIdMutex);
669 
670  /* Reserve the global PTEs */
672  ASSERT(SessionPte != NULL);
673 
674  /* Acquire the PFN lock while we set everything up */
676 
677  /* Loop the global PTEs */
678  TempPte = ValidKernelPte;
679  for (i = 0; i < MiSessionDataPages; i++)
680  {
681  /* Get a zeroed colored zero page */
682  Color = MI_GET_NEXT_COLOR();
683  DataPage[i] = MiRemoveZeroPageSafe(Color);
684  if (!DataPage[i])
685  {
686  /* No zero pages, grab a free one */
687  DataPage[i] = MiRemoveAnyPage(Color);
688 
689  /* Zero it outside the PFN lock */
691  MiZeroPhysicalPage(DataPage[i]);
693  }
694 
695  /* Fill the PTE out */
696  TempPte.u.Hard.PageFrameNumber = DataPage[i];
697  MI_WRITE_VALID_PTE(SessionPte + i, TempPte);
698  }
699 
700  /* Set the pointer to global space */
701  SessionGlobal = MiPteToAddress(SessionPte);
702 
703  /* Get a zeroed colored zero page */
704  Color = MI_GET_NEXT_COLOR();
705  SessionPageDirIndex = MiRemoveZeroPageSafe(Color);
706  if (!SessionPageDirIndex)
707  {
708  /* No zero pages, grab a free one */
709  SessionPageDirIndex = MiRemoveAnyPage(Color);
710 
711  /* Zero it outside the PFN lock */
713  MiZeroPhysicalPage(SessionPageDirIndex);
715  }
716 
717  /* Fill the PTE out */
718  TempPde = ValidKernelPdeLocal;
719  TempPde.u.Hard.PageFrameNumber = SessionPageDirIndex;
720 
721  /* Setup, allocate, fill out the MmSessionSpace PTE */
722  PointerPde = MiAddressToPde(MmSessionSpace);
723  ASSERT(PointerPde->u.Long == 0);
724  MI_WRITE_VALID_PDE(PointerPde, TempPde);
725  MiInitializePfnForOtherProcess(SessionPageDirIndex,
726  PointerPde,
727  SessionPageDirIndex);
728  ASSERT(MI_PFN_ELEMENT(SessionPageDirIndex)->u1.WsIndex == 0);
729 
730  /* Loop all the local PTEs for it */
731  TempPte = ValidKernelPteLocal;
732  PointerPte = MiAddressToPte(MmSessionSpace);
733  for (i = 0; i < MiSessionDataPages; i++)
734  {
735  /* And fill them out */
736  TempPte.u.Hard.PageFrameNumber = DataPage[i];
737  MiInitializePfnAndMakePteValid(DataPage[i], PointerPte + i, TempPte);
738  ASSERT(MI_PFN_ELEMENT(DataPage[i])->u1.WsIndex == 0);
739  }
740 
741  /* Finally loop all of the session pool tag pages */
742  for (i = 0; i < MiSessionTagPages; i++)
743  {
744  /* Grab a zeroed colored page */
745  Color = MI_GET_NEXT_COLOR();
746  TagPage[i] = MiRemoveZeroPageSafe(Color);
747  if (!TagPage[i])
748  {
749  /* No zero pages, grab a free one */
750  TagPage[i] = MiRemoveAnyPage(Color);
751 
752  /* Zero it outside the PFN lock */
754  MiZeroPhysicalPage(TagPage[i]);
756  }
757 
758  /* Fill the PTE out */
759  TempPte.u.Hard.PageFrameNumber = TagPage[i];
761  PointerPte + MiSessionDataPages + i,
762  TempPte);
763  }
764 
765  /* PTEs have been setup, release the PFN lock */
767 
768  /* Fill out the session space structure now */
769  MmSessionSpace->GlobalVirtualAddress = SessionGlobal;
770  MmSessionSpace->ReferenceCount = 1;
771  MmSessionSpace->ResidentProcessCount = 1;
772  MmSessionSpace->u.LongFlags = 0;
773  MmSessionSpace->SessionId = *SessionId;
774  MmSessionSpace->LocaleId = PsDefaultSystemLocaleId;
775  MmSessionSpace->SessionPageDirectoryIndex = SessionPageDirIndex;
776  MmSessionSpace->Color = Color;
777  MmSessionSpace->NonPageablePages = MiSessionCreateCharge;
778  MmSessionSpace->CommittedPages = MiSessionCreateCharge;
779 #ifndef _M_AMD64
780  MmSessionSpace->PageTables = PageTables;
781  MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] = *PointerPde;
782 #endif
783  InitializeListHead(&MmSessionSpace->ImageList);
784  DPRINT1("Session %lu is ready to go: 0x%p 0x%p, %lx 0x%p\n",
785  *SessionId, MmSessionSpace, SessionGlobal, SessionPageDirIndex, PageTables);
786 
787  /* Initialize session pool */
788  //Status = MiInitializeSessionPool();
789  Status = STATUS_SUCCESS;
790  ASSERT(NT_SUCCESS(Status) == TRUE);
791 
792  /* Initialize system space */
793  Result = MiInitializeSystemSpaceMap(&SessionGlobal->Session);
794  ASSERT(Result == TRUE);
795 
796  /* Initialize the process list, make sure the workign set list is empty */
797  ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
798  ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
799  InitializeListHead(&SessionGlobal->ProcessList);
800 
801  /* We're done, clear the flag */
804 
805  /* Insert the process into the session */
806  ASSERT(Process->Session == NULL);
807  ASSERT(SessionGlobal->ProcessReferenceToSession == 0);
808  SessionGlobal->ProcessReferenceToSession = 1;
809 
810  /* We're done */
812  return STATUS_SUCCESS;
813 }
814 
815 NTSTATUS
816 NTAPI
818 {
820  ULONG SessionLeaderExists;
822 
823  /* Fail if the process is already in a session */
824  if (Process->Flags & PSF_PROCESS_IN_SESSION_BIT)
825  {
826  DPRINT1("Process already in session\n");
828  }
829 
830  /* Check if the process is already the session leader */
831  if (!Process->Vm.Flags.SessionLeader)
832  {
833  /* Atomically set it as the leader */
834  SessionLeaderExists = InterlockedCompareExchange(&MiSessionLeaderExists, 1, 0);
835  if (SessionLeaderExists)
836  {
837  DPRINT1("Session leader race\n");
839  }
840 
841  /* Do the work required to upgrade him */
842  MiSessionLeader(Process);
843  }
844 
845  /* Create the session */
847  Status = MiSessionCreateInternal(SessionId);
848  if (!NT_SUCCESS(Status))
849  {
851  return Status;
852  }
853 
854  /* Set up the session working set */
856  if (!NT_SUCCESS(Status))
857  {
858  /* Fail */
859  //MiDereferenceSession();
860  ASSERT(FALSE);
862  return Status;
863  }
864 
865  /* All done */
867 
868  /* Set and assert the flags, and return */
869  MmSessionSpace->u.Flags.Initialized = 1;
872  return Status;
873 }
874 
875 NTSTATUS
876 NTAPI
878 {
880 
881  /* Process must be in a session */
882  if (!(Process->Flags & PSF_PROCESS_IN_SESSION_BIT))
883  {
884  DPRINT1("Not in a session!\n");
886  }
887 
888  /* It must be the session leader */
889  if (!Process->Vm.Flags.SessionLeader)
890  {
891  DPRINT1("Not a session leader!\n");
893  }
894 
895  /* Remove one reference count */
897  /* FIXME: Do it */
899 
900  /* All done */
901  return STATUS_SUCCESS;
902 }
903 
905 NTSTATUS
906 NTAPI
907 MmAttachSession(
908  _Inout_ PVOID SessionEntry,
910 {
911  PEPROCESS EntryProcess;
912  PMM_SESSION_SPACE EntrySession, CurrentSession;
914  KIRQL OldIrql;
915 
916  /* The parameter is the actual process! */
917  EntryProcess = SessionEntry;
918  ASSERT(EntryProcess != NULL);
919 
920  /* Sanity checks */
922  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
923 
924  /* Get the session from the process that was passed in */
925  EntrySession = EntryProcess->Session;
926  ASSERT(EntrySession != NULL);
927 
928  /* Get the current process and it's session */
929  CurrentProcess = PsGetCurrentProcess();
930  CurrentSession = CurrentProcess->Session;
931 
932  /* Acquire the expansion lock while touching the session */
933  OldIrql = MiAcquireExpansionLock();
934 
935  /* Check if the session is about to be deleted */
936  if (EntrySession->u.Flags.DeletePending)
937  {
938  /* We cannot attach to it, so unlock and fail */
939  MiReleaseExpansionLock(OldIrql);
941  }
942 
943  /* Count the number of attaches */
944  EntrySession->AttachCount++;
945 
946  /* we can release the lock again */
947  MiReleaseExpansionLock(OldIrql);
948 
949  /* Check if we are not the session leader and we are in a session */
950  if (!CurrentProcess->Vm.Flags.SessionLeader && (CurrentSession != NULL))
951  {
952  /* Are we already in the right session? */
953  if (CurrentSession == EntrySession)
954  {
955  /* We are, so "attach" to the current process */
956  EntryProcess = CurrentProcess;
957  }
958  else
959  {
960  /* We are not, the session id should better not match! */
961  ASSERT(CurrentSession->SessionId != EntrySession->SessionId);
962  }
963  }
964 
965  /* Now attach to the process that we have */
966  KeStackAttachProcess(&EntryProcess->Pcb, ApcState);
967 
968  /* Success! */
969  return STATUS_SUCCESS;
970 }
971 
973 VOID
974 NTAPI
975 MmDetachSession(
976  _Inout_ PVOID SessionEntry,
977  _In_ PKAPC_STATE ApcState)
978 {
979  PEPROCESS EntryProcess;
980  PMM_SESSION_SPACE EntrySession;
981  KIRQL OldIrql;
982  BOOLEAN DeletePending;
983 
984  /* The parameter is the actual process! */
985  EntryProcess = SessionEntry;
986  ASSERT(EntryProcess != NULL);
987 
988  /* Sanity checks */
990  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
991 
992  /* Get the session from the process that was passed in */
993  EntrySession = EntryProcess->Session;
994  ASSERT(EntrySession != NULL);
995 
996  /* Acquire the expansion lock while touching the session */
997  OldIrql = MiAcquireExpansionLock();
998 
999  /* Make sure we have at least one attach and decrement the count */
1000  ASSERT(EntrySession->AttachCount >= 1);
1001  EntrySession->AttachCount--;
1002 
1003  /* Remember if a delete is pending and we were the last one attached */
1004  DeletePending = EntrySession->u.Flags.DeletePending &&
1005  (EntrySession->AttachCount == 0);
1006 
1007  /* Release the lock again */
1008  MiReleaseExpansionLock(OldIrql);
1009 
1010  /* Detach from the process */
1011  KeUnstackDetachProcess(ApcState);
1012 
1013  /* Check if we need to set the attach event */
1014  if (DeletePending)
1015  KeSetEvent(&EntrySession->AttachEvent, IO_NO_INCREMENT, FALSE);
1016 }
1017 
1018 VOID
1019 NTAPI
1021  _Inout_ PVOID SessionEntry)
1022 {
1023  PEPROCESS EntryProcess;
1024 
1025  /* The parameter is the actual process! */
1026  EntryProcess = SessionEntry;
1027  ASSERT(EntryProcess != NULL);
1028 
1029  /* Sanity checks */
1031  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
1032  ASSERT(EntryProcess->Session != NULL);
1033 
1034  /* Get rid of the reference we took */
1035  ObDereferenceObject(EntryProcess);
1036 }
1037 
1038 PVOID
1039 NTAPI
1042 {
1043  PLIST_ENTRY ListEntry;
1044  PMM_SESSION_SPACE Session;
1046  KIRQL OldIrql;
1047 
1048  /* Acquire the expansion lock while touching the session */
1049  OldIrql = MiAcquireExpansionLock();
1050 
1051  /* Loop all entries in the session ws list */
1052  ListEntry = MiSessionWsList.Flink;
1053  while (ListEntry != &MiSessionWsList)
1054  {
1055  Session = CONTAINING_RECORD(ListEntry, MM_SESSION_SPACE, WsListEntry);
1056  ListEntry = ListEntry->Flink;
1057 
1058  /* Check if this is the session we are looking for */
1059  if (Session->SessionId == SessionId)
1060  {
1061  /* Check if we also have a process in the process list */
1062  if (!IsListEmpty(&Session->ProcessList))
1063  {
1064  Process = CONTAINING_RECORD(Session->ProcessList.Flink,
1065  EPROCESS,
1066  SessionProcessLinks);
1067 
1068  /* Reference the process */
1069  ObReferenceObject(Process);
1070  break;
1071  }
1072  }
1073  }
1074 
1075  /* Release the lock again */
1076  MiReleaseExpansionLock(OldIrql);
1077 
1078  return Process;
1079 }
DWORD *typedef PVOID
Definition: winlogon.h:52
PFN_NUMBER MiSessionTagSizePages
Definition: session.c:22
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI MiDereferenceSessionFinal(VOID)
Definition: session.c:274
NTSYSAPI ULONG NTAPI RtlFindClearBitsAndSet(_In_ PRTL_BITMAP BitMapHeader, _In_ ULONG NumberToFind, _In_ ULONG HintIndex)
Definition: bitmap.c:645
MMSUPPORT Vm
Definition: miarm.h:477
#define STATUS_SUCCESS
Definition: contextmenu.cpp:55
ULONG SessionId
Definition: miarm.h:454
LIST_ENTRY ProcessList
Definition: miarm.h:455
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:39
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
PVOID ULONG Address
Definition: oprghdlr.h:14
SIZE_T NonPageablePages
Definition: miarm.h:458
#define MI_SESSION_TAG_PAGES_MAXIMUM
Definition: miarm.h:225
LONG ReferenceCount
Definition: miarm.h:448
#define MiAddressToPde(x)
Definition: mmx86.c:20
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1348
ULONG MmSessionSize
Definition: init.c:34
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:870
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
PMMPDE PageTables
Definition: miarm.h:484
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
LONG ProcessReferenceToSession
Definition: miarm.h:471
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:138
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
ULONG SessionId
Definition: dllmain.c:28
PMMWSL VmWorkingSetList
Definition: mmtypes.h:917
PFN_NUMBER MiSessionCreateCharge
Definition: session.c:23
#define PSF_SESSION_CREATION_UNDERWAY_BIT
Definition: pstypes.h:271
VOID NTAPI MiSessionAddProcess(IN PEPROCESS NewProcess)
Definition: session.c:427
#define TRUE
Definition: numbers.c:17
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:209
LCID NTAPI MmGetSessionLocaleId(VOID)
Definition: session.c:57
LCID PsDefaultSystemLocaleId
Definition: locale.c:20
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:77
#define InterlockedCompareExchange
Definition: interlocked.h:104
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
BOOLEAN NTAPI MmIsSessionAddress(IN PVOID Address)
Definition: session.c:49
ULONG SessionLeader
Definition: mmtypes.h:881
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
PVOID MiSessionSpaceWs
Definition: mminit.c:130
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:267
KGUARDED_MUTEX MiSessionIdMutex
Definition: session.c:24
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:915
GLdouble u1
Definition: glext.h:8308
_Must_inspect_result_ _In_ ULONG Index
Definition: fltkernel.h:1824
#define InsertTailList(ListHead, Entry)
LONG NTAPI KeSetEvent(IN PKEVENT Event, IN KPRIORITY Increment, IN BOOLEAN Wait)
Definition: eventobj.c:159
LCID PsDefaultThreadLocaleId
Definition: locale.c:25
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
VOID NTAPI MiSessionRemoveProcess(VOID)
Definition: session.c:396
ULONG64 Global
Definition: mmtypes.h:166
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:180
NTSTATUS NTAPI MmSessionDelete(IN ULONG SessionId)
Definition: session.c:877
struct Color Color
PFN_NUMBER MiSessionTagPages
Definition: session.c:22
union _MMPTE::@1889 u
LONG MmSessionDataPages
Definition: session.c:25
struct _MMPFN::@1492::@1498 e2
uint32_t ULONG_PTR
Definition: typedefs.h:64
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:256
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
NTSYSAPI VOID NTAPI RtlInitializeBitMap(_Out_ PRTL_BITMAP BitMapHeader, _In_opt_ __drv_aliasesMem PULONG BitMapBuffer, _In_opt_ ULONG SizeOfBitMap)
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MI_MAKE_DIRTY_PAGE(x)
Definition: mm.h:88
PDRIVER_UNLOAD Win32KDriverUnload
Definition: miarm.h:479
PVOID MmSessionBase
Definition: init.c:33
VOID NTAPI MiSessionLeader(IN PEPROCESS Process)
Definition: session.c:168
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
volatile LONG MiSessionLeaderExists
Definition: session.c:27
LIST_ENTRY WsListEntry
Definition: miarm.h:472
#define TAG_MM
Definition: tag.h:136
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:649
ULONG_PTR ShareCount
Definition: mm.h:322
long LONG
Definition: pedump.c:60
ULONG SessionSpace
Definition: mmtypes.h:879
_IRQL_requires_max_(APC_LEVEL)
Definition: session.c:90
#define NULL
Definition: mystdio.h:57
#define RtlInterlockedClearBits(Flags, Flag)
Definition: rtlfuncs.h:3442
NTSTATUS NTAPI MiSessionInitializeWorkingSetList(VOID)
Definition: session.c:465
#define PsGetCurrentProcess
Definition: psfuncs.h:17
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2265
union _MMPFN::@1491 u2
NTSYSAPI VOID NTAPI RtlClearAllBits(_In_ PRTL_BITMAP BitMapHeader)
Definition: bitmap.c:272
PETHREAD MiExpansionLockOwner
Definition: session.c:33
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
VOID NTAPI MiInitializeSessionIds(VOID)
Definition: session.c:117
#define _Out_
Definition: no_sal2.h:323
#define ExInitializePushLock
Definition: ex.h:943
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:969
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
NTSTATUS NTAPI MiSessionCreateInternal(OUT PULONG SessionId)
Definition: session.c:601
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:423
union _MMPFN::@1492 u3
UINTN Size
Definition: acefiex.h:550
ULONG LongFlags
Definition: miarm.h:451
PVOID Session
Definition: pstypes.h:1202
#define STATUS_UNABLE_TO_FREE_VM
Definition: ntstatus.h:249
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:907
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define PDE_MAPPED_VA
Definition: miarm.h:20
unsigned char BOOLEAN
LIST_ENTRY SessionProcessLinks
Definition: pstypes.h:1151
EX_PUSH_LOCK WorkingSetMutex
Definition: mmtypes.h:935
VOID NTAPI MiDereferenceSession(VOID)
Definition: session.c:340
MM_SESSION_SPACE_FLAGS Flags
Definition: miarm.h:452
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:447
ULONG CurrentProcess
Definition: shell.c:125
LIST_ENTRY WorkingSetExpansionLinks
Definition: mmtypes.h:899
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:82
if(!(yy_init))
Definition: macro.lex.yy.c:704
SIZE_T CommittedPages
Definition: miarm.h:459
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
BOOLEAN NTAPI MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
Definition: section.c:240
MMSESSION Session
Definition: miarm.h:474
MMPTE ValidKernelPteLocal
Definition: init.c:35
ULONG64 Valid
Definition: mmtypes.h:150
PFN_NUMBER MiSessionDataPages
Definition: session.c:22
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:488
#define MI_SESSION_DATA_PAGES_MAXIMUM
Definition: miarm.h:224
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
VOID FASTCALL KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber, IN KIRQL OldIrql)
Definition: spinlock.c:154
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
#define _Inout_
Definition: no_sal2.h:244
#define PAGED_CODE()
Definition: video.h:57
MMPTE ValidKernelPte
Definition: init.c:31
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
struct _MMWSL * PMMWSL
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define BYTES_TO_PAGES(Size)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1391
PMMWSLE Wsle
Definition: mmtypes.h:860
#define InterlockedDecrement
Definition: armddk.h:52
PMMWSLE_HASH HashTable
Definition: mmtypes.h:863
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
#define MI_INITIAL_SESSION_IDS
Definition: miarm.h:179
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Definition: mm.h:305
#define PAGE_SIZE
Definition: env_spec_w32.h:49
Definition: typedefs.h:118
KPROCESS Pcb
Definition: pstypes.h:1139
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PVOID NTAPI MmGetSessionById(_In_ ULONG SessionId)
Definition: session.c:1040
LIST_ENTRY ImageList
Definition: miarm.h:466
LIST_ENTRY MiSessionWsList
Definition: session.c:29
MMPTE ValidKernelPdeLocal
Definition: init.c:34
MMSUPPORT Vm
Definition: pstypes.h:1233
Status
Definition: gdiplustypes.h:24
ULONG_PTR Long
Definition: mmtypes.h:215
#define _In_
Definition: no_sal2.h:204
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:210
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:161
#define NT_SUCCESS(StatCode)
Definition: cmd.c:149
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
KEVENT AttachEvent
Definition: miarm.h:469
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
LONG NTSTATUS
Definition: DriverTester.h:11
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define InterlockedIncrement
Definition: armddk.h:53
ULONG NTAPI MmGetSessionIdEx(IN PEPROCESS Process)
Definition: session.c:195
#define ROUND_TO_PAGES(Size)
ULONG HashTableSize
Definition: mmtypes.h:864
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:701
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PMMWSLE Wsle
Definition: miarm.h:478
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1415
LONG ResidentProcessCount
Definition: miarm.h:464
unsigned int * PULONG
Definition: retypes.h:1
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1361
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
ULONG Flags
Definition: pstypes.h:1312
ULONG WsIndex
Definition: mm.h:310
struct _MM_SESSION_SPACE * PMM_SESSION_SPACE
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define OUT
Definition: typedefs.h:40
#define ObReferenceObject
Definition: obfuncs.h:204
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
#define FALSE
Definition: numbers.c:16
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:273
unsigned int ULONG
Definition: retypes.h:1
#define IO_NO_INCREMENT
Definition: iotypes.h:565
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:251
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
NTSTATUS NTAPI MmSessionCreate(OUT PULONG SessionId)
Definition: session.c:817
#define ULONG_PTR
Definition: config.h:101
VOID NTAPI MiInitializeSessionWsSupport(VOID)
Definition: session.c:40
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
ULONG AttachCount
Definition: miarm.h:468
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1097
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:916
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:900
DWORD LCID
Definition: nls.h:14
PFN_NUMBER MiSessionBigPoolPages
Definition: session.c:23
signed int * PLONG
Definition: retypes.h:5
ULONG LastEntry
Definition: mmtypes.h:858
VOID NTAPI MmQuitNextSession(_Inout_ PVOID SessionEntry)
Definition: session.c:1020
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:82
union _MM_SESSION_SPACE::@1519 u
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:90
* PKAPC_STATE
Definition: ketypes.h:1258
struct _MMWSLE * PMMWSLE
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:457