ReactOS  0.4.14-dev-1036-g3c5b10f
session.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <mm/ARM3/miarm.h>
Include dependency graph for session.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define MODULE_INVOLVED_IN_ARM3
 

Functions

VOID NTAPI MiInitializeSessionWsSupport (VOID)
 
BOOLEAN NTAPI MmIsSessionAddress (IN PVOID Address)
 
LCID NTAPI MmGetSessionLocaleId (VOID)
 
 _IRQL_requires_max_ (APC_LEVEL)
 
VOID NTAPI MiInitializeSessionIds (VOID)
 
VOID NTAPI MiSessionLeader (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionId (IN PEPROCESS Process)
 
ULONG NTAPI MmGetSessionIdEx (IN PEPROCESS Process)
 
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage (IN PMM_SESSION_SPACE SessionGlobal)
 
VOID NTAPI MiDereferenceSessionFinal (VOID)
 
VOID NTAPI MiDereferenceSession (VOID)
 
VOID NTAPI MiSessionRemoveProcess (VOID)
 
VOID NTAPI MiSessionAddProcess (IN PEPROCESS NewProcess)
 
NTSTATUS NTAPI MiSessionInitializeWorkingSetList (VOID)
 
NTSTATUS NTAPI MiSessionCreateInternal (OUT PULONG SessionId)
 
NTSTATUS NTAPI MmSessionCreate (OUT PULONG SessionId)
 
NTSTATUS NTAPI MmSessionDelete (IN ULONG SessionId)
 
VOID NTAPI MmQuitNextSession (_Inout_ PVOID SessionEntry)
 
PVOID NTAPI MmGetSessionById (_In_ ULONG SessionId)
 

Variables

PMM_SESSION_SPACE MmSessionSpace
 
PFN_NUMBER MiSessionDataPages
 
PFN_NUMBER MiSessionTagPages
 
PFN_NUMBER MiSessionTagSizePages
 
PFN_NUMBER MiSessionBigPoolPages
 
PFN_NUMBER MiSessionCreateCharge
 
KGUARDED_MUTEX MiSessionIdMutex
 
LONG MmSessionDataPages
 
PRTL_BITMAP MiSessionIdBitmap
 
volatile LONG MiSessionLeaderExists
 
LIST_ENTRY MiSessionWsList
 
LIST_ENTRY MmWorkingSetExpansionHead
 
KSPIN_LOCK MmExpansionLock
 
PETHREAD MiExpansionLockOwner
 

Macro Definition Documentation

◆ MODULE_INVOLVED_IN_ARM3

#define MODULE_INVOLVED_IN_ARM3

Definition at line 16 of file session.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file session.c.

Function Documentation

◆ _IRQL_requires_max_()

_IRQL_requires_max_ ( APC_LEVEL  )

Definition at line 90 of file session.c.

95 {
97  PAGED_CODE();
98 
99  /* Get the current process and check if it is in a session */
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 }
LCID PsDefaultThreadLocaleId
Definition: locale.c:25
#define PAGED_CODE()
Definition: video.h:57
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
ULONG CurrentProcess
Definition: shell.c:125
struct _MM_SESSION_SPACE * PMM_SESSION_SPACE

◆ MiDereferenceSession()

VOID NTAPI MiDereferenceSession ( VOID  )

Definition at line 340 of file session.c.

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 */
355 
356  /* Get the current process */
358 
359  /* Decrement the process count */
361 
362  /* Decrement the reference count and check if was the last reference */
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 }
VOID NTAPI MiDereferenceSessionFinal(VOID)
Definition: session.c:274
ULONG SessionId
Definition: miarm.h:486
LONG ReferenceCount
Definition: miarm.h:480
#define MiAddressToPde(x)
Definition: mmx86.c:20
ULONG MmSessionSize
Definition: init.c:34
ULONG SessionId
Definition: dllmain.c:28
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:272
PVOID MmSessionBase
Definition: init.c:33
#define RtlInterlockedClearBits(Flags, Flag)
Definition: rtlfuncs.h:3442
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:413
MM_SESSION_SPACE_FLAGS Flags
Definition: miarm.h:484
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:479
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define BYTES_TO_PAGES(Size)
#define InterlockedDecrement
Definition: armddk.h:52
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:210
LONG ResidentProcessCount
Definition: miarm.h:496
union _MM_SESSION_SPACE::@1772 u
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262

Referenced by MiSessionRemoveProcess().

◆ MiDereferenceSessionFinal()

VOID NTAPI MiDereferenceSessionFinal ( VOID  )

Definition at line 274 of file session.c.

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 */
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 */
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 */
304 
305  /* Makes sure we still have the delete flag and no attached processes */
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 */
328 
329  /* Check for a win32k unload routine */
330  if (SessionGlobal->Win32KDriverUnload)
331  {
332  /* Call it */
333  SessionGlobal->Win32KDriverUnload(NULL);
334  }
335 }
MMSUPPORT Vm
Definition: miarm.h:509
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
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
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
PDRIVER_UNLOAD Win32KDriverUnload
Definition: miarm.h:511
LIST_ENTRY WsListEntry
Definition: miarm.h:504
smooth NULL
Definition: ftsmooth.c:416
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
MM_SESSION_SPACE_FLAGS Flags
Definition: miarm.h:484
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:479
LIST_ENTRY WorkingSetExpansionLinks
Definition: mmtypes.h:898
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
KEVENT AttachEvent
Definition: miarm.h:501
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393
union _MM_SESSION_SPACE::@1772 u
ULONG AttachCount
Definition: miarm.h:500

Referenced by MiDereferenceSession().

◆ MiInitializeSessionIds()

VOID NTAPI MiInitializeSessionIds ( VOID  )

Definition at line 117 of file session.c.

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 */
140 
141  /* Allocate the bitmap */
143  BitmapSize = ((Size + 31) / 32) * sizeof(ULONG);
145  sizeof(RTL_BITMAP) + BitmapSize,
146  TAG_MM);
147  if (MiSessionIdBitmap)
148  {
149  /* Free all the bits */
151  (PVOID)(MiSessionIdBitmap + 1),
152  Size);
154  }
155  else
156  {
157  /* Die if we couldn't allocate the bitmap */
158  KeBugCheckEx(INSTALL_MORE_MEMORY,
162  0x200);
163  }
164 }
PFN_NUMBER MiSessionTagSizePages
Definition: session.c:22
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define MI_SESSION_TAG_PAGES_MAXIMUM
Definition: miarm.h:257
PFN_NUMBER MiSessionCreateCharge
Definition: session.c:23
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
KGUARDED_MUTEX MiSessionIdMutex
Definition: session.c:24
PFN_NUMBER MiSessionTagPages
Definition: session.c:22
ULONG PFN_NUMBER
Definition: ke.h:8
#define TAG_MM
Definition: tag.h:136
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
PFN_NUMBER MiSessionDataPages
Definition: session.c:22
#define MI_SESSION_DATA_PAGES_MAXIMUM
Definition: miarm.h:256
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define MI_INITIAL_SESSION_IDS
Definition: miarm.h:211
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define ROUND_TO_PAGES(Size)
NTSYSAPI void WINAPI RtlClearAllBits(PRTL_BITMAP)
unsigned int ULONG
Definition: retypes.h:1
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
PFN_NUMBER MiSessionBigPoolPages
Definition: session.c:23
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:107

Referenced by MmInitSystem().

◆ MiInitializeSessionWsSupport()

VOID NTAPI MiInitializeSessionWsSupport ( VOID  )

Definition at line 40 of file session.c.

41 {
42  /* Initialize the list heads */
45 }
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
LIST_ENTRY MiSessionWsList
Definition: session.c:29
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

Referenced by MmInitSystem().

◆ MiReleaseProcessReferenceToSessionDataPage()

VOID NTAPI MiReleaseProcessReferenceToSessionDataPage ( IN PMM_SESSION_SPACE  SessionGlobal)

Definition at line 210 of file session.c.

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 */
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 */
270 }
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
ULONG SessionId
Definition: dllmain.c:28
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define RtlCheckBit(BMH, BP)
Definition: rtlfuncs.h:3154
KGUARDED_MUTEX MiSessionIdMutex
Definition: session.c:24
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
struct _MMPFN::@1744::@1750 e2
LONG MmSessionDataPages
Definition: session.c:25
UCHAR KIRQL
Definition: env_spec_w32.h:591
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
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
ULONG_PTR ShareCount
Definition: mm.h:322
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1133
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:275
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
PFN_NUMBER MiSessionDataPages
Definition: session.c:22
#define MI_SESSION_DATA_PAGES_MAXIMUM
Definition: miarm.h:256
VOID NTAPI RtlClearBit(_In_ PRTL_BITMAP BitMapHeader, _In_ BITMAP_INDEX BitNumber)
Definition: bitmap.c:294
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1423
#define InterlockedDecrement
Definition: armddk.h:52
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: mm.h:305
union _MMPFN::@1743 u2
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:193
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
union _MMPFN::@1744 u3
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:932
#define PFN_FROM_PTE(v)
Definition: mm.h:89

Referenced by MiDereferenceSession(), and MmDeleteProcessAddressSpace2().

◆ MiSessionAddProcess()

VOID NTAPI MiSessionAddProcess ( IN PEPROCESS  NewProcess)

Definition at line 427 of file session.c.

428 {
429  PMM_SESSION_SPACE SessionGlobal;
430  KIRQL OldIrql;
431 
432  /* The current process must already be in a session */
434 
435  /* Sanity check */
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 */
452 
453  /* Insert it into the process list */
454  InsertTailList(&SessionGlobal->ProcessList, &NewProcess->SessionProcessLinks);
455 
456  /* Release the lock again */
458 
459  /* Set the flag */
461 }
LIST_ENTRY ProcessList
Definition: miarm.h:487
#define TRUE
Definition: types.h:120
LONG ReferenceCount
Definition: miarm.h:480
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
LONG ProcessReferenceToSession
Definition: miarm.h:503
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:272
#define InsertTailList(ListHead, Entry)
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define PsGetCurrentProcess
Definition: psfuncs.h:17
smooth NULL
Definition: ftsmooth.c:416
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:479
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define InterlockedIncrement
Definition: armddk.h:53
LONG ResidentProcessCount
Definition: miarm.h:496
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
signed int * PLONG
Definition: retypes.h:5

◆ MiSessionCreateInternal()

NTSTATUS NTAPI MiSessionCreateInternal ( OUT PULONG  SessionId)

Definition at line 603 of file session.c.

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 */
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,
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 */
658 
659  /* Allocate a new Session ID */
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 */
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 */
681  for (i = 0; i < MiSessionDataPages; i++)
682  {
683  /* Get a zeroed colored zero page */
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 */
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 */
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 */
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 */
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;
780  MmSessionSpace->SessionPageDirectoryIndex = SessionPageDirIndex;
784 #ifndef _M_AMD64
785  MmSessionSpace->PageTables = PageTables;
786  MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] = *PointerPde;
787 #endif
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();
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 }
ULONG SessionId
Definition: miarm.h:486
LIST_ENTRY ProcessList
Definition: miarm.h:487
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
#define TRUE
Definition: types.h:120
SIZE_T NonPageablePages
Definition: miarm.h:490
#define MI_SESSION_TAG_PAGES_MAXIMUM
Definition: miarm.h:257
LONG ReferenceCount
Definition: miarm.h:480
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define PSF_SESSION_CREATION_UNDERWAY_BIT
Definition: pstypes.h:270
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
PMMPDE PageTables
Definition: miarm.h:516
LONG ProcessReferenceToSession
Definition: miarm.h:503
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
ULONG SessionId
Definition: dllmain.c:28
PFN_NUMBER MiSessionCreateCharge
Definition: session.c:23
LONG NTSTATUS
Definition: precomp.h:26
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:241
LCID PsDefaultSystemLocaleId
Definition: locale.c:20
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
#define InterlockedCompareExchange
Definition: interlocked.h:104
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1280
KGUARDED_MUTEX MiSessionIdMutex
Definition: session.c:24
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
GLdouble u1
Definition: glext.h:8308
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
struct Color Color
PFN_NUMBER MiSessionTagPages
Definition: session.c:22
LONG MmSessionDataPages
Definition: session.c:25
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:256
UCHAR KIRQL
Definition: env_spec_w32.h:591
PVOID MmSessionBase
Definition: init.c:33
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
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
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
LIST_ENTRY WsListEntry
Definition: miarm.h:504
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:946
#define PsGetCurrentProcess
Definition: psfuncs.h:17
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2310
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_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
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1001
#define MI_SET_USAGE(x)
Definition: mm.h:253
ULONG LongFlags
Definition: miarm.h:483
ULONG PageFrameNumber
Definition: mmtypes.h:74
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
#define PDE_MAPPED_VA
Definition: miarm.h:22
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:479
SIZE_T CommittedPages
Definition: miarm.h:491
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
MMSESSION Session
Definition: miarm.h:506
BOOLEAN NTAPI MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
Definition: section.c:240
MMPTE ValidKernelPteLocal
Definition: init.c:33
PFN_NUMBER MiSessionDataPages
Definition: session.c:22
#define MI_SESSION_DATA_PAGES_MAXIMUM
Definition: miarm.h:256
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
MMPTE ValidKernelPte
Definition: init.c:29
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1423
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
union _MMPTE::@2251 u
IN PVOID IN PVOID IN USHORT IN USHORT Size
Definition: pci.h:359
LIST_ENTRY ImageList
Definition: miarm.h:498
MMPTE ValidKernelPdeLocal
Definition: init.c:32
Status
Definition: gdiplustypes.h:24
ULONG_PTR Long
Definition: mmtypes.h:215
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
#define InterlockedIncrement
Definition: armddk.h:53
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
LONG ResidentProcessCount
Definition: miarm.h:496
union _MM_SESSION_SPACE::@1772 u
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
#define DPRINT1
Definition: precomp.h:8
ULONG WsIndex
Definition: mm.h:310
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
FORCEINLINE PVOID MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:198
return STATUS_SUCCESS
Definition: btrfs.c:2938
signed int * PLONG
Definition: retypes.h:5
ULONG PageFrameNumber
Definition: mmtypes.h:109
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:489

Referenced by MmSessionCreate().

◆ MiSessionInitializeWorkingSetList()

NTSTATUS NTAPI MiSessionInitializeWorkingSetList ( VOID  )

Definition at line 465 of file session.c.

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 */
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 */
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
537 #endif
538  /* Initialize the page directory page, and now zero the working set list itself */
539  MiInitializePfnForOtherProcess(PageFrameIndex,
540  PointerPde,
542  KeZeroPages(PointerPte, PAGE_SIZE);
543  }
544 
545  /* Get a zeroed colored zero page */
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 */
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 */
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 */
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);
591  &SessionGlobal->Vm.WorkingSetExpansionLinks);
592 
593  /* Release the lock again */
595 
596  /* All done, return */
597  //MmUnlockPageableImageSection(ExPageLockHandle);
598  return STATUS_SUCCESS;
599 }
MMSUPPORT Vm
Definition: miarm.h:509
#define TRUE
Definition: types.h:120
#define MiAddressToPde(x)
Definition: mmx86.c:20
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
USHORT UsedPageTableEntries[768]
Definition: mmtypes.h:869
PMMPDE PageTables
Definition: miarm.h:516
struct _LIST_ENTRY * Blink
Definition: typedefs.h:121
PMMWSL VmWorkingSetList
Definition: mmtypes.h:916
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:241
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
FORCEINLINE KIRQL MiAcquirePfnLock(VOID)
Definition: mm.h:901
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 MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:914
#define InsertTailList(ListHead, Entry)
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
ULONG64 Global
Definition: mmtypes.h:166
FORCEINLINE VOID MiReleasePfnLock(_In_ KIRQL OldIrql)
Definition: mm.h:908
struct Color Color
uint32_t ULONG_PTR
Definition: typedefs.h:64
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MI_MAKE_DIRTY_PAGE(x)
Definition: mm.h:95
PVOID MmSessionBase
Definition: init.c:33
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
LIST_ENTRY WsListEntry
Definition: miarm.h:504
ULONG SessionSpace
Definition: mmtypes.h:878
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2310
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define ExInitializePushLock
Definition: ex.h:999
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1001
#define MI_SET_USAGE(x)
Definition: mm.h:253
ULONG PageFrameNumber
Definition: mmtypes.h:74
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:906
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
EX_PUSH_LOCK WorkingSetMutex
Definition: mmtypes.h:934
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:479
LIST_ENTRY WorkingSetExpansionLinks
Definition: mmtypes.h:898
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: stubs.c:82
MMPTE ValidKernelPteLocal
Definition: init.c:33
ULONG64 Valid
Definition: mmtypes.h:150
static const UCHAR Index[8]
Definition: usbohci.c:18
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
struct _MMWSL * PMMWSL
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
PMMWSLE Wsle
Definition: mmtypes.h:859
PMMWSLE_HASH HashTable
Definition: mmtypes.h:862
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
union _MMPTE::@2251 u
#define PAGE_SIZE
Definition: env_spec_w32.h:49
LIST_ENTRY MiSessionWsList
Definition: session.c:29
MMPTE ValidKernelPdeLocal
Definition: init.c:32
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:475
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG HashTableSize
Definition: mmtypes.h:863
PMMWSLE Wsle
Definition: miarm.h:510
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1036
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:915
return STATUS_SUCCESS
Definition: btrfs.c:2938
ULONG LastEntry
Definition: mmtypes.h:857
struct _MMWSLE * PMMWSLE
ULONG PageFrameNumber
Definition: mmtypes.h:109
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:489

Referenced by MmSessionCreate().

◆ MiSessionLeader()

VOID NTAPI MiSessionLeader ( IN PEPROCESS  Process)

Definition at line 168 of file session.c.

169 {
170  KIRQL OldIrql;
171 
172  /* Set the flag while under the expansion lock */
174  Process->Vm.Flags.SessionLeader = TRUE;
176 }
#define TRUE
Definition: types.h:120
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
UCHAR KIRQL
Definition: env_spec_w32.h:591
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by MmSessionCreate().

◆ MiSessionRemoveProcess()

VOID NTAPI MiSessionRemoveProcess ( VOID  )

Definition at line 396 of file session.c.

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 */
411 
412  /* Acquire the expansion lock while touching the session */
414 
415  /* Remove the process from the list */
416  RemoveEntryList(&CurrentProcess->SessionProcessLinks);
417 
418  /* Release the lock again */
420 
421  /* Dereference the session */
423 }
#define TRUE
Definition: types.h:120
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:272
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PsGetCurrentProcess
Definition: psfuncs.h:17
VOID NTAPI MiDereferenceSession(VOID)
Definition: session.c:340
ULONG CurrentProcess
Definition: shell.c:125
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393

Referenced by MmCleanProcessAddressSpace().

◆ MmGetSessionById()

PVOID NTAPI MmGetSessionById ( _In_ ULONG  SessionId)

Definition at line 1045 of file session.c.

1047 {
1048  PLIST_ENTRY ListEntry;
1049  PMM_SESSION_SPACE Session;
1051  KIRQL OldIrql;
1052 
1053  /* Acquire the expansion lock while touching the session */
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  {
1070  EPROCESS,
1071  SessionProcessLinks);
1072 
1073  /* Reference the process */
1075  break;
1076  }
1077  }
1078  }
1079 
1080  /* Release the lock again */
1082 
1083  return Process;
1084 }
ULONG SessionId
Definition: miarm.h:486
LIST_ENTRY ProcessList
Definition: miarm.h:487
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1380
ULONG SessionId
Definition: dllmain.c:28
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
UCHAR KIRQL
Definition: env_spec_w32.h:591
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
Definition: typedefs.h:118
LIST_ENTRY MiSessionWsList
Definition: session.c:29
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1393
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by ExpWin32SessionCallout().

◆ MmGetSessionId()

ULONG NTAPI MmGetSessionId ( IN PEPROCESS  Process)

Definition at line 180 of file session.c.

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 }
ULONG SessionId
Definition: miarm.h:486
if(!(yy_init))
Definition: macro.lex.yy.c:714
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

Referenced by IoGetRequestorSessionId(), MmCreatePeb(), PsGetCurrentProcessSessionId(), PsGetProcessSessionId(), PsGetThreadSessionId(), and PspInitializeProcessSecurity().

◆ MmGetSessionIdEx()

ULONG NTAPI MmGetSessionIdEx ( IN PEPROCESS  Process)

Definition at line 195 of file session.c.

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 }
ULONG SessionId
Definition: miarm.h:486
if(!(yy_init))
Definition: macro.lex.yy.c:714
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

Referenced by PsGetProcessSessionIdEx().

◆ MmGetSessionLocaleId()

LCID NTAPI MmGetSessionLocaleId ( VOID  )

Definition at line 57 of file session.c.

58 {
60  PAGED_CODE();
61 
62  //
63  // Get the current process
64  //
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 }
LCID PsDefaultThreadLocaleId
Definition: locale.c:25
#define PAGED_CODE()
Definition: video.h:57
#define PsGetCurrentProcess
Definition: psfuncs.h:17
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219

Referenced by NtQueryDefaultLocale(), and PspUserThreadStartup().

◆ MmIsSessionAddress()

BOOLEAN NTAPI MmIsSessionAddress ( IN PVOID  Address)

Definition at line 49 of file session.c.

50 {
51  /* Check if it is in range */
53 }
#define TRUE
Definition: types.h:120
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:170
static WCHAR Address[46]
Definition: ping.c:68

Referenced by MmDbgCopyMemory().

◆ MmQuitNextSession()

VOID NTAPI MmQuitNextSession ( _Inout_ PVOID  SessionEntry)

Definition at line 1025 of file session.c.

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 }
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
ULONG SessionLeader
Definition: mmtypes.h:880
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
smooth NULL
Definition: ftsmooth.c:416
PVOID Session
Definition: pstypes.h:1256
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:906
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
MMSUPPORT Vm
Definition: pstypes.h:1287
#define APC_LEVEL
Definition: env_spec_w32.h:695

Referenced by ExpWin32SessionCallout().

◆ MmSessionCreate()

NTSTATUS NTAPI MmSessionCreate ( OUT PULONG  SessionId)

Definition at line 822 of file session.c.

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 */
848  }
849 
850  /* Create the session */
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 */
877  return Status;
878 }
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:272
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:256
VOID NTAPI MiSessionLeader(IN PEPROCESS Process)
Definition: session.c:168
volatile LONG MiSessionLeaderExists
Definition: session.c:27
NTSTATUS NTAPI MiSessionInitializeWorkingSetList(VOID)
Definition: session.c:465
#define PsGetCurrentProcess
Definition: psfuncs.h:17
NTSTATUS NTAPI MiSessionCreateInternal(OUT PULONG SessionId)
Definition: session.c:603
MM_SESSION_SPACE_FLAGS Flags
Definition: miarm.h:484
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
Status
Definition: gdiplustypes.h:24
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
union _MM_SESSION_SPACE::@1772 u
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
unsigned int ULONG
Definition: retypes.h:1
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:251

Referenced by SSI_DEF().

◆ MmSessionDelete()

NTSTATUS NTAPI MmSessionDelete ( IN ULONG  SessionId)

Definition at line 882 of file session.c.

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 }
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:272
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define STATUS_UNABLE_TO_FREE_VM
Definition: ntstatus.h:249
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define DPRINT1
Definition: precomp.h:8
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
return STATUS_SUCCESS
Definition: btrfs.c:2938

Referenced by SSI_DEF().

Variable Documentation

◆ MiExpansionLockOwner

PETHREAD MiExpansionLockOwner

Definition at line 33 of file session.c.

Referenced by MiAcquireExpansionLock(), and MiReleaseExpansionLock().

◆ MiSessionBigPoolPages

PFN_NUMBER MiSessionBigPoolPages

Definition at line 23 of file session.c.

Referenced by MiInitializeSessionIds().

◆ MiSessionCreateCharge

PFN_NUMBER MiSessionCreateCharge

Definition at line 23 of file session.c.

Referenced by MiInitializeSessionIds(), and MiSessionCreateInternal().

◆ MiSessionDataPages

◆ MiSessionIdBitmap

◆ MiSessionIdMutex

◆ MiSessionLeaderExists

volatile LONG MiSessionLeaderExists

Definition at line 27 of file session.c.

Referenced by MmSessionCreate().

◆ MiSessionTagPages

PFN_NUMBER MiSessionTagPages

Definition at line 22 of file session.c.

Referenced by MiInitializeSessionIds(), and MiSessionCreateInternal().

◆ MiSessionTagSizePages

PFN_NUMBER MiSessionTagSizePages

Definition at line 22 of file session.c.

Referenced by MiInitializeSessionIds().

◆ MiSessionWsList

LIST_ENTRY MiSessionWsList

◆ MmExpansionLock

KSPIN_LOCK MmExpansionLock

Definition at line 32 of file session.c.

Referenced by MiAcquireExpansionLock(), and MiReleaseExpansionLock().

◆ MmSessionDataPages

LONG MmSessionDataPages

◆ MmSessionSpace

◆ MmWorkingSetExpansionHead

LIST_ENTRY MmWorkingSetExpansionHead

Definition at line 30 of file session.c.

Referenced by MiInitializeSessionWsSupport(), and MiSessionInitializeWorkingSetList().