ReactOS  r75384
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 */
515  Color = MI_GET_NEXT_COLOR();
516  PageFrameIndex = MiRemoveZeroPageSafe(Color);
517  if (!PageFrameIndex)
518  {
519  /* No zero pages, grab a free one */
520  PageFrameIndex = MiRemoveAnyPage(Color);
521 
522  /* Zero it outside the PFN lock */
524  MiZeroPhysicalPage(PageFrameIndex);
526  }
527 
528  /* Write a valid PDE for it */
529  TempPde = ValidKernelPdeLocal;
530  TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
531  MI_WRITE_VALID_PDE(PointerPde, TempPde);
532 
533  /* Add this into the list */
534  Index = ((ULONG_PTR)WorkingSetList - (ULONG_PTR)MmSessionBase) >> 22;
535 #ifndef _M_AMD64
536  MmSessionSpace->PageTables[Index] = TempPde;
537 #endif
538  /* Initialize the page directory page, and now zero the working set list itself */
539  MiInitializePfnForOtherProcess(PageFrameIndex,
540  PointerPde,
541  MmSessionSpace->SessionPageDirectoryIndex);
542  KeZeroPages(PointerPte, PAGE_SIZE);
543  }
544 
545  /* Get a zeroed colored zero page */
547  Color = MI_GET_NEXT_COLOR();
548  PageFrameIndex = MiRemoveZeroPageSafe(Color);
549  if (!PageFrameIndex)
550  {
551  /* No zero pages, grab a free one */
552  PageFrameIndex = MiRemoveAnyPage(Color);
553 
554  /* Zero it outside the PFN lock */
556  MiZeroPhysicalPage(PageFrameIndex);
558  }
559 
560  /* Write a valid PTE for it */
561  TempPte = ValidKernelPteLocal;
562  MI_MAKE_DIRTY_PAGE(&TempPte);
563  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
564 
565  /* Initialize the working set list page */
566  MiInitializePfnAndMakePteValid(PageFrameIndex, PointerPte, TempPte);
567 
568  /* Now we can release the PFN database lock */
570 
571  /* Fill out the working set structure */
572  MmSessionSpace->Vm.Flags.SessionSpace = 1;
573  MmSessionSpace->Vm.MinimumWorkingSetSize = 20;
574  MmSessionSpace->Vm.MaximumWorkingSetSize = 384;
575  WorkingSetList->LastEntry = 20;
576  WorkingSetList->HashTable = NULL;
577  WorkingSetList->HashTableSize = 0;
578  WorkingSetList->Wsle = MmSessionSpace->Wsle;
579 
580  /* Acquire the expansion lock while touching the session */
581  OldIrql = MiAcquireExpansionLock();
582 
583  /* Handle list insertions */
584  ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
585  ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
586  InsertTailList(&MiSessionWsList, &SessionGlobal->WsListEntry);
587 
588  ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Flink == NULL);
589  ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Blink == NULL);
590  InsertTailList(&MmWorkingSetExpansionHead,
591  &SessionGlobal->Vm.WorkingSetExpansionLinks);
592 
593  /* Release the lock again */
594  MiReleaseExpansionLock(OldIrql);
595 
596  /* All done, return */
597  //MmUnlockPageableImageSection(ExPageLockHandle);
598  return STATUS_SUCCESS;
599 }
600 
601 NTSTATUS
602 NTAPI
604 {
606  ULONG NewFlags, Flags, Size, i, Color;
607  KIRQL OldIrql;
608  PMMPTE PointerPte, SessionPte;
609  PMMPDE PointerPde, PageTables;
610  PMM_SESSION_SPACE SessionGlobal;
611  MMPTE TempPte;
612  MMPDE TempPde;
614  BOOLEAN Result;
615  PFN_NUMBER SessionPageDirIndex;
618 
619  /* This should not exist yet */
620  ASSERT(MmIsAddressValid(MmSessionSpace) == FALSE);
621 
622  /* Loop so we can set the session-is-creating flag */
623  Flags = Process->Flags;
624  while (TRUE)
625  {
626  /* Check if it's already set */
628  {
629  /* Bail out */
630  DPRINT1("Lost session race\n");
632  }
633 
634  /* Now try to set it */
635  NewFlags = InterlockedCompareExchange((PLONG)&Process->Flags,
636  Flags | PSF_SESSION_CREATION_UNDERWAY_BIT,
637  Flags);
638  if (NewFlags == Flags) break;
639 
640  /* It changed, try again */
641  Flags = NewFlags;
642  }
643 
644  /* Now we should own the flag */
646 
647  /*
648  * Session space covers everything from 0xA0000000 to 0xC0000000.
649  * Allocate enough page tables to describe the entire region
650  */
651  Size = (0x20000000 / PDE_MAPPED_VA) * sizeof(MMPTE);
652  PageTables = ExAllocatePoolWithTag(NonPagedPool, Size, 'tHmM');
653  ASSERT(PageTables != NULL);
654  RtlZeroMemory(PageTables, Size);
655 
656  /* Lock the session ID creation mutex */
657  KeAcquireGuardedMutex(&MiSessionIdMutex);
658 
659  /* Allocate a new Session ID */
660  *SessionId = RtlFindClearBitsAndSet(MiSessionIdBitmap, 1, 0);
661  if (*SessionId == 0xFFFFFFFF)
662  {
663  /* We ran out of session IDs, we should expand */
664  DPRINT1("Too many sessions created. Expansion not yet supported\n");
665  ExFreePoolWithTag(PageTables, 'tHmM');
666  return STATUS_NO_MEMORY;
667  }
668 
669  /* Unlock the session ID creation mutex */
670  KeReleaseGuardedMutex(&MiSessionIdMutex);
671 
672  /* Reserve the global PTEs */
674  ASSERT(SessionPte != NULL);
675 
676  /* Acquire the PFN lock while we set everything up */
678 
679  /* Loop the global PTEs */
680  TempPte = ValidKernelPte;
681  for (i = 0; i < MiSessionDataPages; i++)
682  {
683  /* Get a zeroed colored zero page */
685  Color = MI_GET_NEXT_COLOR();
686  DataPage[i] = MiRemoveZeroPageSafe(Color);
687  if (!DataPage[i])
688  {
689  /* No zero pages, grab a free one */
690  DataPage[i] = MiRemoveAnyPage(Color);
691 
692  /* Zero it outside the PFN lock */
694  MiZeroPhysicalPage(DataPage[i]);
696  }
697 
698  /* Fill the PTE out */
699  TempPte.u.Hard.PageFrameNumber = DataPage[i];
700  MI_WRITE_VALID_PTE(SessionPte + i, TempPte);
701  }
702 
703  /* Set the pointer to global space */
704  SessionGlobal = MiPteToAddress(SessionPte);
705 
706  /* Get a zeroed colored zero page */
708  Color = MI_GET_NEXT_COLOR();
709  SessionPageDirIndex = MiRemoveZeroPageSafe(Color);
710  if (!SessionPageDirIndex)
711  {
712  /* No zero pages, grab a free one */
713  SessionPageDirIndex = MiRemoveAnyPage(Color);
714 
715  /* Zero it outside the PFN lock */
717  MiZeroPhysicalPage(SessionPageDirIndex);
719  }
720 
721  /* Fill the PTE out */
722  TempPde = ValidKernelPdeLocal;
723  TempPde.u.Hard.PageFrameNumber = SessionPageDirIndex;
724 
725  /* Setup, allocate, fill out the MmSessionSpace PTE */
726  PointerPde = MiAddressToPde(MmSessionSpace);
727  ASSERT(PointerPde->u.Long == 0);
728  MI_WRITE_VALID_PDE(PointerPde, TempPde);
729  MiInitializePfnForOtherProcess(SessionPageDirIndex,
730  PointerPde,
731  SessionPageDirIndex);
732  ASSERT(MI_PFN_ELEMENT(SessionPageDirIndex)->u1.WsIndex == 0);
733 
734  /* Loop all the local PTEs for it */
735  TempPte = ValidKernelPteLocal;
736  PointerPte = MiAddressToPte(MmSessionSpace);
737  for (i = 0; i < MiSessionDataPages; i++)
738  {
739  /* And fill them out */
740  TempPte.u.Hard.PageFrameNumber = DataPage[i];
741  MiInitializePfnAndMakePteValid(DataPage[i], PointerPte + i, TempPte);
742  ASSERT(MI_PFN_ELEMENT(DataPage[i])->u1.WsIndex == 0);
743  }
744 
745  /* Finally loop all of the session pool tag pages */
746  for (i = 0; i < MiSessionTagPages; i++)
747  {
748  /* Grab a zeroed colored page */
750  Color = MI_GET_NEXT_COLOR();
751  TagPage[i] = MiRemoveZeroPageSafe(Color);
752  if (!TagPage[i])
753  {
754  /* No zero pages, grab a free one */
755  TagPage[i] = MiRemoveAnyPage(Color);
756 
757  /* Zero it outside the PFN lock */
759  MiZeroPhysicalPage(TagPage[i]);
761  }
762 
763  /* Fill the PTE out */
764  TempPte.u.Hard.PageFrameNumber = TagPage[i];
766  PointerPte + MiSessionDataPages + i,
767  TempPte);
768  }
769 
770  /* PTEs have been setup, release the PFN lock */
772 
773  /* Fill out the session space structure now */
774  MmSessionSpace->GlobalVirtualAddress = SessionGlobal;
775  MmSessionSpace->ReferenceCount = 1;
776  MmSessionSpace->ResidentProcessCount = 1;
777  MmSessionSpace->u.LongFlags = 0;
778  MmSessionSpace->SessionId = *SessionId;
779  MmSessionSpace->LocaleId = PsDefaultSystemLocaleId;
780  MmSessionSpace->SessionPageDirectoryIndex = SessionPageDirIndex;
781  MmSessionSpace->Color = Color;
782  MmSessionSpace->NonPageablePages = MiSessionCreateCharge;
783  MmSessionSpace->CommittedPages = MiSessionCreateCharge;
784 #ifndef _M_AMD64
785  MmSessionSpace->PageTables = PageTables;
786  MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] = *PointerPde;
787 #endif
788  InitializeListHead(&MmSessionSpace->ImageList);
789  DPRINT1("Session %lu is ready to go: 0x%p 0x%p, %lx 0x%p\n",
790  *SessionId, MmSessionSpace, SessionGlobal, SessionPageDirIndex, PageTables);
791 
792  /* Initialize session pool */
793  //Status = MiInitializeSessionPool();
794  Status = STATUS_SUCCESS;
795  ASSERT(NT_SUCCESS(Status) == TRUE);
796 
797  /* Initialize system space */
798  Result = MiInitializeSystemSpaceMap(&SessionGlobal->Session);
799  ASSERT(Result == TRUE);
800 
801  /* Initialize the process list, make sure the workign set list is empty */
802  ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
803  ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
804  InitializeListHead(&SessionGlobal->ProcessList);
805 
806  /* We're done, clear the flag */
809 
810  /* Insert the process into the session */
811  ASSERT(Process->Session == NULL);
812  ASSERT(SessionGlobal->ProcessReferenceToSession == 0);
813  SessionGlobal->ProcessReferenceToSession = 1;
814 
815  /* We're done */
817  return STATUS_SUCCESS;
818 }
819 
820 NTSTATUS
821 NTAPI
823 {
825  ULONG SessionLeaderExists;
827 
828  /* Fail if the process is already in a session */
829  if (Process->Flags & PSF_PROCESS_IN_SESSION_BIT)
830  {
831  DPRINT1("Process already in session\n");
833  }
834 
835  /* Check if the process is already the session leader */
836  if (!Process->Vm.Flags.SessionLeader)
837  {
838  /* Atomically set it as the leader */
839  SessionLeaderExists = InterlockedCompareExchange(&MiSessionLeaderExists, 1, 0);
840  if (SessionLeaderExists)
841  {
842  DPRINT1("Session leader race\n");
844  }
845 
846  /* Do the work required to upgrade him */
847  MiSessionLeader(Process);
848  }
849 
850  /* Create the session */
852  Status = MiSessionCreateInternal(SessionId);
853  if (!NT_SUCCESS(Status))
854  {
856  return Status;
857  }
858 
859  /* Set up the session working set */
861  if (!NT_SUCCESS(Status))
862  {
863  /* Fail */
864  //MiDereferenceSession();
865  ASSERT(FALSE);
867  return Status;
868  }
869 
870  /* All done */
872 
873  /* Set and assert the flags, and return */
874  MmSessionSpace->u.Flags.Initialized = 1;
877  return Status;
878 }
879 
880 NTSTATUS
881 NTAPI
883 {
885 
886  /* Process must be in a session */
887  if (!(Process->Flags & PSF_PROCESS_IN_SESSION_BIT))
888  {
889  DPRINT1("Not in a session!\n");
891  }
892 
893  /* It must be the session leader */
894  if (!Process->Vm.Flags.SessionLeader)
895  {
896  DPRINT1("Not a session leader!\n");
898  }
899 
900  /* Remove one reference count */
902  /* FIXME: Do it */
904 
905  /* All done */
906  return STATUS_SUCCESS;
907 }
908 
910 NTSTATUS
911 NTAPI
912 MmAttachSession(
913  _Inout_ PVOID SessionEntry,
915 {
916  PEPROCESS EntryProcess;
917  PMM_SESSION_SPACE EntrySession, CurrentSession;
919  KIRQL OldIrql;
920 
921  /* The parameter is the actual process! */
922  EntryProcess = SessionEntry;
923  ASSERT(EntryProcess != NULL);
924 
925  /* Sanity checks */
927  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
928 
929  /* Get the session from the process that was passed in */
930  EntrySession = EntryProcess->Session;
931  ASSERT(EntrySession != NULL);
932 
933  /* Get the current process and it's session */
934  CurrentProcess = PsGetCurrentProcess();
935  CurrentSession = CurrentProcess->Session;
936 
937  /* Acquire the expansion lock while touching the session */
938  OldIrql = MiAcquireExpansionLock();
939 
940  /* Check if the session is about to be deleted */
941  if (EntrySession->u.Flags.DeletePending)
942  {
943  /* We cannot attach to it, so unlock and fail */
944  MiReleaseExpansionLock(OldIrql);
946  }
947 
948  /* Count the number of attaches */
949  EntrySession->AttachCount++;
950 
951  /* we can release the lock again */
952  MiReleaseExpansionLock(OldIrql);
953 
954  /* Check if we are not the session leader and we are in a session */
955  if (!CurrentProcess->Vm.Flags.SessionLeader && (CurrentSession != NULL))
956  {
957  /* Are we already in the right session? */
958  if (CurrentSession == EntrySession)
959  {
960  /* We are, so "attach" to the current process */
961  EntryProcess = CurrentProcess;
962  }
963  else
964  {
965  /* We are not, the session id should better not match! */
966  ASSERT(CurrentSession->SessionId != EntrySession->SessionId);
967  }
968  }
969 
970  /* Now attach to the process that we have */
971  KeStackAttachProcess(&EntryProcess->Pcb, ApcState);
972 
973  /* Success! */
974  return STATUS_SUCCESS;
975 }
976 
978 VOID
979 NTAPI
980 MmDetachSession(
981  _Inout_ PVOID SessionEntry,
982  _In_ PKAPC_STATE ApcState)
983 {
984  PEPROCESS EntryProcess;
985  PMM_SESSION_SPACE EntrySession;
986  KIRQL OldIrql;
987  BOOLEAN DeletePending;
988 
989  /* The parameter is the actual process! */
990  EntryProcess = SessionEntry;
991  ASSERT(EntryProcess != NULL);
992 
993  /* Sanity checks */
995  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
996 
997  /* Get the session from the process that was passed in */
998  EntrySession = EntryProcess->Session;
999  ASSERT(EntrySession != NULL);
1000 
1001  /* Acquire the expansion lock while touching the session */
1002  OldIrql = MiAcquireExpansionLock();
1003 
1004  /* Make sure we have at least one attach and decrement the count */
1005  ASSERT(EntrySession->AttachCount >= 1);
1006  EntrySession->AttachCount--;
1007 
1008  /* Remember if a delete is pending and we were the last one attached */
1009  DeletePending = EntrySession->u.Flags.DeletePending &&
1010  (EntrySession->AttachCount == 0);
1011 
1012  /* Release the lock again */
1013  MiReleaseExpansionLock(OldIrql);
1014 
1015  /* Detach from the process */
1016  KeUnstackDetachProcess(ApcState);
1017 
1018  /* Check if we need to set the attach event */
1019  if (DeletePending)
1020  KeSetEvent(&EntrySession->AttachEvent, IO_NO_INCREMENT, FALSE);
1021 }
1022 
1023 VOID
1024 NTAPI
1026  _Inout_ PVOID SessionEntry)
1027 {
1028  PEPROCESS EntryProcess;
1029 
1030  /* The parameter is the actual process! */
1031  EntryProcess = SessionEntry;
1032  ASSERT(EntryProcess != NULL);
1033 
1034  /* Sanity checks */
1036  ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
1037  ASSERT(EntryProcess->Session != NULL);
1038 
1039  /* Get rid of the reference we took */
1040  ObDereferenceObject(EntryProcess);
1041 }
1042 
1043 PVOID
1044 NTAPI
1047 {
1048  PLIST_ENTRY ListEntry;
1049  PMM_SESSION_SPACE Session;
1051  KIRQL OldIrql;
1052 
1053  /* Acquire the expansion lock while touching the session */
1054  OldIrql = MiAcquireExpansionLock();
1055 
1056  /* Loop all entries in the session ws list */
1057  ListEntry = MiSessionWsList.Flink;
1058  while (ListEntry != &MiSessionWsList)
1059  {
1060  Session = CONTAINING_RECORD(ListEntry, MM_SESSION_SPACE, WsListEntry);
1061  ListEntry = ListEntry->Flink;
1062 
1063  /* Check if this is the session we are looking for */
1064  if (Session->SessionId == SessionId)
1065  {
1066  /* Check if we also have a process in the process list */
1067  if (!IsListEmpty(&Session->ProcessList))
1068  {
1069  Process = CONTAINING_RECORD(Session->ProcessList.Flink,
1070  EPROCESS,
1071  SessionProcessLinks);
1072 
1073  /* Reference the process */
1074  ObReferenceObject(Process);
1075  break;
1076  }
1077  }
1078  }
1079 
1080  /* Release the lock again */
1081  MiReleaseExpansionLock(OldIrql);
1082 
1083  return Process;
1084 }
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
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
union _MM_SESSION_SPACE::@1605 u
#define TRUE
Definition: types.h:120
PVOID ULONG Address
Definition: oprghdlr.h:14
SIZE_T NonPageablePages
Definition: miarm.h:458
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#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
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:882
struct Color Color
PFN_NUMBER MiSessionTagPages
Definition: session.c:22
LONG MmSessionDataPages
Definition: session.c:25
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
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
#define FALSE
Definition: types.h: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 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:2255
PETHREAD MiExpansionLockOwner
Definition: session.c:33
smooth NULL
Definition: ftsmooth.c:513
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
#define MI_SET_USAGE(x)
Definition: mm.h:253
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
struct _MMPFN::@1578::@1584 e2
NTSTATUS NTAPI MiSessionCreateInternal(OUT PULONG SessionId)
Definition: session.c:603
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:423
UINTN Size
Definition: acefiex.h:550
ULONG LongFlags
Definition: miarm.h:451
PVOID Session
Definition: pstypes.h:1257
#define STATUS_UNABLE_TO_FREE_VM
Definition: ntstatus.h:249
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
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:1206
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
union _MMPFN::@1577 u2
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:1194
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
KIRQL FASTCALL KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
Definition: spinlock.c:108
PVOID NTAPI MmGetSessionById(_In_ ULONG SessionId)
Definition: session.c:1045
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:1288
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:1367
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
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
union _MMPFN::@1578 u3
#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:822
#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
union _MMPTE::@2063 u
#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:1025
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PFN_FROM_PTE(v)
Definition: mm.h:82
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