ReactOS 0.4.16-dev-336-gb667d82
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
38VOID
41{
42 /* Initialize the list heads */
44}
45
49{
50 /* Check if it is in range */
52}
53
54LCID
57{
59 PAGED_CODE();
60
61 //
62 // Get the current process
63 //
65
66 //
67 // Check if it's NOT the Session Leader
68 //
69 if (!Process->Vm.Flags.SessionLeader)
70 {
71 //
72 // Make sure it has a valid Session
73 //
74 if (Process->Session)
75 {
76 //
77 // Get the Locale ID
78 //
79 return ((PMM_SESSION_SPACE)Process->Session)->LocaleId;
80 }
81 }
82
83 //
84 // Not a session leader, return the default
85 //
87}
88
90VOID
92MmSetSessionLocaleId(
94{
95 PEPROCESS CurrentProcess;
96 PAGED_CODE();
97
98 /* Get the current process and check if it is in a session */
99 CurrentProcess = PsGetCurrentProcess();
100 if ((CurrentProcess->Vm.Flags.SessionLeader == 0) &&
101 (CurrentProcess->Session != NULL))
102 {
103 /* Set the session locale Id */
104 ((PMM_SESSION_SPACE)CurrentProcess->Session)->LocaleId = LocaleId;
105 }
106 else
107 {
108 /* Set the default locale */
110 }
111}
112
113
114VOID
115NTAPI
117{
118 ULONG Size, BitmapSize;
119 PFN_NUMBER TotalPages;
120
121 /* Setup the total number of data pages needed for the structure */
125 TotalPages -= MiSessionDataPages;
126
127 /* Setup the number of pages needed for session pool tags */
131 ASSERT(MiSessionTagPages <= TotalPages);
133
134 /* Total pages needed for a session (FIXME: Probably different on PAE/x64) */
136
137 /* Initialize the lock */
139
140 /* Allocate the bitmap */
142 BitmapSize = ((Size + 31) / 32) * sizeof(ULONG);
144 sizeof(RTL_BITMAP) + BitmapSize,
145 TAG_MM);
147 {
148 /* Free all the bits */
151 Size);
153 }
154 else
155 {
156 /* Die if we couldn't allocate the bitmap */
157 KeBugCheckEx(INSTALL_MORE_MEMORY,
161 0x200);
162 }
163}
164
165VOID
166NTAPI
168{
170
171 /* Set the flag while under the expansion lock */
173 Process->Vm.Flags.SessionLeader = TRUE;
175}
176
177ULONG
178NTAPI
180{
181 PMM_SESSION_SPACE SessionGlobal;
182
183 /* The session leader is always session zero */
184 if (Process->Vm.Flags.SessionLeader == 1) return 0;
185
186 /* Otherwise, get the session global, and read the session ID from it */
187 SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
188 if (!SessionGlobal) return 0;
189 return SessionGlobal->SessionId;
190}
191
192ULONG
193NTAPI
195{
196 PMM_SESSION_SPACE SessionGlobal;
197
198 /* The session leader is always session zero */
199 if (Process->Vm.Flags.SessionLeader == 1) return 0;
200
201 /* Otherwise, get the session global, and read the session ID from it */
202 SessionGlobal = (PMM_SESSION_SPACE)Process->Session;
203 if (!SessionGlobal) return -1;
204 return SessionGlobal->SessionId;
205}
206
207VOID
208NTAPI
210{
212 PMMPTE PointerPte;
214 PMMPFN Pfn1;
216
217 /* Is there more than just this reference? If so, bail out */
218 if (InterlockedDecrement(&SessionGlobal->ProcessReferenceToSession)) return;
219
220 /* Get the session ID */
221 SessionId = SessionGlobal->SessionId;
222 DPRINT1("Last process in session %lu going down!!!\n", SessionId);
223
224 /* Free the session page tables */
225#ifndef _M_AMD64
226 ExFreePoolWithTag(SessionGlobal->PageTables, 'tHmM');
227#endif
228 ASSERT(!MI_IS_PHYSICAL_ADDRESS(SessionGlobal));
229
230 /* Capture the data page PFNs */
231 PointerPte = MiAddressToPte(SessionGlobal);
232 for (i = 0; i < MiSessionDataPages; i++)
233 {
234 PageFrameIndex[i] = PFN_FROM_PTE(PointerPte + i);
235 }
236
237 /* Release them */
239
240 /* Mark them as deleted */
241 for (i = 0; i < MiSessionDataPages; i++)
242 {
243 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
244 MI_SET_PFN_DELETED(Pfn1);
245 }
246
247 /* Loop every data page and drop a reference count */
248 OldIrql = MiAcquirePfnLock();
249 for (i = 0; i < MiSessionDataPages; i++)
250 {
251 /* Sanity check that the page is correct, then decrement it */
252 Pfn1 = MI_PFN_ELEMENT(PageFrameIndex[i]);
253 ASSERT(Pfn1->u2.ShareCount == 1);
254 ASSERT(Pfn1->u3.e2.ReferenceCount == 1);
255 MiDecrementShareCount(Pfn1, PageFrameIndex[i]);
256 }
257
258 /* Done playing with pages, release the lock */
259 MiReleasePfnLock(OldIrql);
260
261 /* Decrement the number of data pages */
263
264 /* Free this session ID from the session bitmap */
269}
270
271VOID
272NTAPI
274{
275 PMM_SESSION_SPACE SessionGlobal;
277
278 /* Get the pointer to the global session address */
279 SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
280
281 /* Acquire the expansion lock */
283
284 /* Set delete pending flag, so that processes can no longer attach to this
285 session and the last process that detaches sets the AttachEvent */
286 ASSERT(SessionGlobal->u.Flags.DeletePending == 0);
287 SessionGlobal->u.Flags.DeletePending = 1;
288
289 /* Check if we have any attached processes */
290 if (SessionGlobal->AttachCount)
291 {
292 /* Initialize the event (it's not in use yet!) */
294
295 /* Release the expansion lock for the wait */
297
298 /* Wait for the event to be set due to the last process detach */
299 KeWaitForSingleObject(&SessionGlobal->AttachEvent, WrVirtualMemory, 0, 0, 0);
300
301 /* Reacquire the expansion lock */
303
304 /* Makes sure we still have the delete flag and no attached processes */
307 }
308
309 /* Check if the session is in the workingset expansion list */
310 if (SessionGlobal->Vm.WorkingSetExpansionLinks.Flink != NULL)
311 {
312 /* Remove the session from the list and zero the list entry */
314 SessionGlobal->Vm.WorkingSetExpansionLinks.Flink = 0;
315 }
316
317 /* Check if the session is in the workingset list */
318 if (SessionGlobal->WsListEntry.Flink)
319 {
320 /* Remove the session from the list and zero the list entry */
321 RemoveEntryList(&SessionGlobal->WsListEntry);
322 SessionGlobal->WsListEntry.Flink = NULL;
323 }
324
325 /* Release the expansion lock */
327
328 /* Check for a win32k unload routine */
329 if (SessionGlobal->Win32KDriverUnload)
330 {
331 /* Call it */
332 SessionGlobal->Win32KDriverUnload(NULL);
333 }
334}
335
336
337VOID
338NTAPI
340{
341 PMM_SESSION_SPACE SessionGlobal;
343 ULONG ReferenceCount, SessionId;
344
345 /* Sanity checks */
346 ASSERT(PsGetCurrentProcess()->ProcessInSession ||
348 (PsGetCurrentProcess()->Vm.Flags.SessionLeader == 1) &&
350
351 /* The session bit must be set */
354
355 /* Get the current process */
357
358 /* Decrement the process count */
360
361 /* Decrement the reference count and check if was the last reference */
363 if (ReferenceCount == 0)
364 {
365 /* No more references left, kill the session completely */
367 return;
368 }
369
370 /* Check if this is the session leader */
371 if (Process->Vm.Flags.SessionLeader)
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 */
377 //RtlZeroMemory(MiAddressToPde(MmSessionBase),
378 // BYTES_TO_PAGES(MmSessionSize) * sizeof(MMPDE));
380
381 /* Clean up the references here. */
382 ASSERT(Process->Session == NULL);
384 }
385
386 /* Reset the current process' session flag */
388}
389
390VOID
391NTAPI
393{
394 PEPROCESS CurrentProcess = PsGetCurrentProcess();
396
397 /* If the process isn't already in a session, or if it's the leader... */
398 if (!(CurrentProcess->Flags & PSF_PROCESS_IN_SESSION_BIT) ||
399 (CurrentProcess->Vm.Flags.SessionLeader))
400 {
401 /* Then there's nothing to do */
402 return;
403 }
404
405 /* Sanity check */
407
408 /* Acquire the expansion lock while touching the session */
410
411 /* Remove the process from the list */
412 RemoveEntryList(&CurrentProcess->SessionProcessLinks);
413
414 /* Release the lock again */
416
417 /* Dereference the session */
419}
420
421VOID
422NTAPI
424{
425 PMM_SESSION_SPACE SessionGlobal;
427
428 /* The current process must already be in a session */
430
431 /* Sanity check */
433
434 /* Get the global session */
435 SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
436
437 /* Increment counters */
438 InterlockedIncrement((PLONG)&SessionGlobal->ReferenceCount);
441
442 /* Set the session pointer */
443 ASSERT(NewProcess->Session == NULL);
444 NewProcess->Session = SessionGlobal;
445
446 /* Acquire the expansion lock while touching the session */
448
449 /* Insert it into the process list */
450 InsertTailList(&SessionGlobal->ProcessList, &NewProcess->SessionProcessLinks);
451
452 /* Release the lock again */
454
455 /* Set the flag */
457}
458
460NTAPI
462{
464 PMMPTE PointerPte;
465 PMMPDE PointerPde;
469 PFN_NUMBER PageFrameIndex;
470 PMM_SESSION_SPACE SessionGlobal;
471 BOOLEAN AllocatedPageTable;
472 PMMWSL WorkingSetList;
473
474 /* Get pointers to session global and the session working set list */
475 SessionGlobal = MmSessionSpace->GlobalVirtualAddress;
476 WorkingSetList = (PMMWSL)MiSessionSpaceWs;
477
478 /* Fill out the two pointers */
479 MmSessionSpace->Vm.VmWorkingSetList = WorkingSetList;
480 MmSessionSpace->Wsle = (PMMWSLE)((&WorkingSetList->VadBitMapHint) + 1);
481
482 /* Get the PDE for the working set, and check if it's already allocated */
483 PointerPde = MiAddressToPde(WorkingSetList);
484 if (PointerPde->u.Hard.Valid == 1)
485 {
486 /* Nope, we'll have to do it */
487#ifndef _M_ARM
488 ASSERT(PointerPde->u.Hard.Global == 0);
489#endif
490 AllocatedPageTable = FALSE;
491 }
492 else
493 {
494 /* Yep, that makes our job easier */
495 AllocatedPageTable = TRUE;
496 }
497
498 /* Get the PTE for the working set */
499 PointerPte = MiAddressToPte(WorkingSetList);
500
501 /* Initialize the working set lock, and lock the PFN database */
502 ExInitializePushLock(&SessionGlobal->Vm.WorkingSetMutex);
503 //MmLockPageableSectionByHandle(ExPageLockHandle);
504 OldIrql = MiAcquirePfnLock();
505
506 /* Check if we need a page table */
507 if (AllocatedPageTable != FALSE)
508 {
509 /* Get a zeroed colored zero page */
512 PageFrameIndex = MiRemoveZeroPageSafe(Color);
513 if (!PageFrameIndex)
514 {
515 /* No zero pages, grab a free one */
516 PageFrameIndex = MiRemoveAnyPage(Color);
517
518 /* Zero it outside the PFN lock */
519 MiReleasePfnLock(OldIrql);
520 MiZeroPhysicalPage(PageFrameIndex);
521 OldIrql = MiAcquirePfnLock();
522 }
523
524 /* Write a valid PDE for it */
526 TempPde.u.Hard.PageFrameNumber = PageFrameIndex;
527 MI_WRITE_VALID_PDE(PointerPde, TempPde);
528
529 /* Add this into the list */
530 Index = ((ULONG_PTR)WorkingSetList - (ULONG_PTR)MmSessionBase) >> 22;
531#ifndef _M_AMD64
533#endif
534 /* Initialize the page directory page, and now zero the working set list itself */
535 MiInitializePfnForOtherProcess(PageFrameIndex,
536 PointerPde,
538 KeZeroPages(PointerPte, PAGE_SIZE);
539 }
540
541 /* Get a zeroed colored zero page */
544 PageFrameIndex = MiRemoveZeroPageSafe(Color);
545 if (!PageFrameIndex)
546 {
547 /* No zero pages, grab a free one */
548 PageFrameIndex = MiRemoveAnyPage(Color);
549
550 /* Zero it outside the PFN lock */
551 MiReleasePfnLock(OldIrql);
552 MiZeroPhysicalPage(PageFrameIndex);
553 OldIrql = MiAcquirePfnLock();
554 }
555
556 /* Write a valid PTE for it */
559 TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
560
561 /* Initialize the working set list page */
562 MiInitializePfnAndMakePteValid(PageFrameIndex, PointerPte, TempPte);
563
564 /* Now we can release the PFN database lock */
565 MiReleasePfnLock(OldIrql);
566
567 /* Fill out the working set structure */
571 WorkingSetList->LastEntry = 20;
572 WorkingSetList->HashTable = NULL;
573 WorkingSetList->HashTableSize = 0;
574 WorkingSetList->Wsle = MmSessionSpace->Wsle;
575
576 /* Acquire the expansion lock while touching the session */
578
579 /* Handle list insertions */
580 ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
581 ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
582 InsertTailList(&MiSessionWsList, &SessionGlobal->WsListEntry);
583
584 ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Flink == NULL);
585 ASSERT(SessionGlobal->Vm.WorkingSetExpansionLinks.Blink == NULL);
587 &SessionGlobal->Vm.WorkingSetExpansionLinks);
588
589 /* Release the lock again */
591
592 /* All done, return */
593 //MmUnlockPageableImageSection(ExPageLockHandle);
594 return STATUS_SUCCESS;
595}
596
598NTAPI
600{
602 ULONG NewFlags, Flags, i, Color;
603#if (_MI_PAGING_LEVELS < 3)
604 ULONG Size;
605#endif // (_MI_PAGING_LEVELS < 3)
606 PMMPDE PageTables = NULL;
608 PMMPTE PointerPte, SessionPte;
609 PMMPDE PointerPde;
610 PMM_SESSION_SPACE SessionGlobal;
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#if (_MI_PAGING_LEVELS < 3)
648 /*
649 * Session space covers everything from 0xA0000000 to 0xC0000000.
650 * Allocate enough page tables to describe the entire region
651 */
652 Size = (0x20000000 / PDE_MAPPED_VA) * sizeof(MMPTE);
653 PageTables = ExAllocatePoolWithTag(NonPagedPool, Size, 'tHmM');
654 ASSERT(PageTables != NULL);
655 RtlZeroMemory(PageTables, Size);
656#endif // (_MI_PAGING_LEVELS < 3)
657
658 /* Lock the session ID creation mutex */
660
661 /* Allocate a new Session ID */
663 if (*SessionId == 0xFFFFFFFF)
664 {
665 /* We ran out of session IDs, we should expand */
666 DPRINT1("Too many sessions created. Expansion not yet supported\n");
667#if (_MI_PAGING_LEVELS < 3)
668 ExFreePoolWithTag(PageTables, 'tHmM');
669#endif // (_MI_PAGING_LEVELS < 3)
670 return STATUS_NO_MEMORY;
671 }
672
673 /* Unlock the session ID creation mutex */
675
676 /* Reserve the global PTEs */
678 ASSERT(SessionPte != NULL);
679
680 /* Acquire the PFN lock while we set everything up */
681 OldIrql = MiAcquirePfnLock();
682
683 /* Loop the global PTEs */
685 for (i = 0; i < MiSessionDataPages; i++)
686 {
687 /* Get a zeroed colored zero page */
690 DataPage[i] = MiRemoveZeroPageSafe(Color);
691 if (!DataPage[i])
692 {
693 /* No zero pages, grab a free one */
694 DataPage[i] = MiRemoveAnyPage(Color);
695
696 /* Zero it outside the PFN lock */
697 MiReleasePfnLock(OldIrql);
698 MiZeroPhysicalPage(DataPage[i]);
699 OldIrql = MiAcquirePfnLock();
700 }
701
702 /* Fill the PTE out */
703 TempPte.u.Hard.PageFrameNumber = DataPage[i];
704 MI_WRITE_VALID_PTE(SessionPte + i, TempPte);
705 }
706
707 /* Set the pointer to global space */
708 SessionGlobal = MiPteToAddress(SessionPte);
709
710 /* Get a zeroed colored zero page */
713 SessionPageDirIndex = MiRemoveZeroPageSafe(Color);
714 if (!SessionPageDirIndex)
715 {
716 /* No zero pages, grab a free one */
717 SessionPageDirIndex = MiRemoveAnyPage(Color);
718
719 /* Zero it outside the PFN lock */
720 MiReleasePfnLock(OldIrql);
721 MiZeroPhysicalPage(SessionPageDirIndex);
722 OldIrql = MiAcquirePfnLock();
723 }
724
725 /* Fill the PTE out */
727 TempPde.u.Hard.PageFrameNumber = SessionPageDirIndex;
728
729 /* Setup, allocate, fill out the MmSessionSpace PTE */
730 PointerPde = MiAddressToPde(MmSessionSpace);
731 ASSERT(PointerPde->u.Long == 0);
732 MI_WRITE_VALID_PDE(PointerPde, TempPde);
733 MiInitializePfnForOtherProcess(SessionPageDirIndex,
734 PointerPde,
735 SessionPageDirIndex);
736 ASSERT(MI_PFN_ELEMENT(SessionPageDirIndex)->u1.WsIndex == 0);
737
738 /* Loop all the local PTEs for it */
740 PointerPte = MiAddressToPte(MmSessionSpace);
741 for (i = 0; i < MiSessionDataPages; i++)
742 {
743 /* And fill them out */
744 TempPte.u.Hard.PageFrameNumber = DataPage[i];
745 MiInitializePfnAndMakePteValid(DataPage[i], PointerPte + i, TempPte);
746 ASSERT(MI_PFN_ELEMENT(DataPage[i])->u1.WsIndex == 0);
747 }
748
749 /* Finally loop all of the session pool tag pages */
750 for (i = 0; i < MiSessionTagPages; i++)
751 {
752 /* Grab a zeroed colored page */
755 TagPage[i] = MiRemoveZeroPageSafe(Color);
756 if (!TagPage[i])
757 {
758 /* No zero pages, grab a free one */
759 TagPage[i] = MiRemoveAnyPage(Color);
760
761 /* Zero it outside the PFN lock */
762 MiReleasePfnLock(OldIrql);
763 MiZeroPhysicalPage(TagPage[i]);
764 OldIrql = MiAcquirePfnLock();
765 }
766
767 /* Fill the PTE out */
768 TempPte.u.Hard.PageFrameNumber = TagPage[i];
770 PointerPte + MiSessionDataPages + i,
771 TempPte);
772 }
773
774 /* PTEs have been setup, release the PFN lock */
775 MiReleasePfnLock(OldIrql);
776
777 /* Fill out the session space structure now */
778 MmSessionSpace->GlobalVirtualAddress = SessionGlobal;
784 MmSessionSpace->SessionPageDirectoryIndex = SessionPageDirIndex;
788#ifndef _M_AMD64
789 MmSessionSpace->PageTables = PageTables;
790 MmSessionSpace->PageTables[PointerPde - MiAddressToPde(MmSessionBase)] = *PointerPde;
791#endif
793
794 DPRINT1("Session %lu is ready to go: 0x%p 0x%p, %lx 0x%p\n",
795 *SessionId, MmSessionSpace, SessionGlobal, SessionPageDirIndex, PageTables);
796
797 /* Initialize session pool */
798 //Status = MiInitializeSessionPool();
801
802 /* Initialize system space */
803 Result = MiInitializeSystemSpaceMap(&SessionGlobal->Session);
804 ASSERT(Result == TRUE);
805
806 /* Initialize the process list, make sure the workign set list is empty */
807 ASSERT(SessionGlobal->WsListEntry.Flink == NULL);
808 ASSERT(SessionGlobal->WsListEntry.Blink == NULL);
809 InitializeListHead(&SessionGlobal->ProcessList);
810
811 /* We're done, clear the flag */
814
815 /* Insert the process into the session */
816 ASSERT(Process->Session == NULL);
817 ASSERT(SessionGlobal->ProcessReferenceToSession == 0);
818 SessionGlobal->ProcessReferenceToSession = 1;
819
820 /* We're done */
822 return STATUS_SUCCESS;
823}
824
826NTAPI
828{
830 ULONG SessionLeaderExists;
832
833 /* Fail if the process is already in a session */
835 {
836 DPRINT1("Process already in session\n");
838 }
839
840 /* Check if the process is already the session leader */
841 if (!Process->Vm.Flags.SessionLeader)
842 {
843 /* Atomically set it as the leader */
844 SessionLeaderExists = InterlockedCompareExchange(&MiSessionLeaderExists, 1, 0);
845 if (SessionLeaderExists)
846 {
847 DPRINT1("Session leader race\n");
849 }
850
851 /* Do the work required to upgrade him */
853 }
854
855 /* Create the session */
858 if (!NT_SUCCESS(Status))
859 {
861 return Status;
862 }
863
864 /* Set up the session working set */
866 if (!NT_SUCCESS(Status))
867 {
868 /* Fail */
869 //MiDereferenceSession();
870 ASSERT(FALSE);
872 return Status;
873 }
874
875 /* All done */
877
878 /* Set and assert the flags, and return */
882 return Status;
883}
884
886NTAPI
888{
890
891 /* Process must be in a session */
892 if (!(Process->Flags & PSF_PROCESS_IN_SESSION_BIT))
893 {
894 DPRINT1("Not in a session!\n");
896 }
897
898 /* It must be the session leader */
899 if (!Process->Vm.Flags.SessionLeader)
900 {
901 DPRINT1("Not a session leader!\n");
903 }
904
905 /* Remove one reference count */
909
910 /* All done */
911 return STATUS_SUCCESS;
912}
913
916NTAPI
917MmAttachSession(
918 _Inout_ PVOID SessionEntry,
920{
921 PEPROCESS EntryProcess;
922 PMM_SESSION_SPACE EntrySession, CurrentSession;
923 PEPROCESS CurrentProcess;
925
926 /* The parameter is the actual process! */
927 EntryProcess = SessionEntry;
928 ASSERT(EntryProcess != NULL);
929
930 /* Sanity checks */
932 ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
933
934 /* Get the session from the process that was passed in */
935 EntrySession = EntryProcess->Session;
936 ASSERT(EntrySession != NULL);
937
938 /* Get the current process and it's session */
939 CurrentProcess = PsGetCurrentProcess();
940 CurrentSession = CurrentProcess->Session;
941
942 /* Acquire the expansion lock while touching the session */
944
945 /* Check if the session is about to be deleted */
946 if (EntrySession->u.Flags.DeletePending)
947 {
948 /* We cannot attach to it, so unlock and fail */
951 }
952
953 /* Count the number of attaches */
954 EntrySession->AttachCount++;
955
956 /* we can release the lock again */
958
959 /* Check if we are not the session leader and we are in a session */
960 if (!CurrentProcess->Vm.Flags.SessionLeader && (CurrentSession != NULL))
961 {
962 /* Are we already in the right session? */
963 if (CurrentSession == EntrySession)
964 {
965 /* We are, so "attach" to the current process */
966 EntryProcess = CurrentProcess;
967 }
968 else
969 {
970 /* We are not, the session id should better not match! */
971 ASSERT(CurrentSession->SessionId != EntrySession->SessionId);
972 }
973 }
974
975 /* Now attach to the process that we have */
976 KeStackAttachProcess(&EntryProcess->Pcb, ApcState);
977
978 /* Success! */
979 return STATUS_SUCCESS;
980}
981
983VOID
984NTAPI
985MmDetachSession(
986 _Inout_ PVOID SessionEntry,
988{
989 PEPROCESS EntryProcess;
990 PMM_SESSION_SPACE EntrySession;
992 BOOLEAN DeletePending;
993
994 /* The parameter is the actual process! */
995 EntryProcess = SessionEntry;
996 ASSERT(EntryProcess != NULL);
997
998 /* Sanity checks */
1000 ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
1001
1002 /* Get the session from the process that was passed in */
1003 EntrySession = EntryProcess->Session;
1004 ASSERT(EntrySession != NULL);
1005
1006 /* Acquire the expansion lock while touching the session */
1008
1009 /* Make sure we have at least one attach and decrement the count */
1010 ASSERT(EntrySession->AttachCount >= 1);
1011 EntrySession->AttachCount--;
1012
1013 /* Remember if a delete is pending and we were the last one attached */
1014 DeletePending = EntrySession->u.Flags.DeletePending &&
1015 (EntrySession->AttachCount == 0);
1016
1017 /* Release the lock again */
1019
1020 /* Detach from the process */
1022
1023 /* Check if we need to set the attach event */
1024 if (DeletePending)
1025 KeSetEvent(&EntrySession->AttachEvent, IO_NO_INCREMENT, FALSE);
1026}
1027
1028VOID
1029NTAPI
1031 _Inout_ PVOID SessionEntry)
1032{
1033 PEPROCESS EntryProcess;
1034
1035 /* The parameter is the actual process! */
1036 EntryProcess = SessionEntry;
1037 ASSERT(EntryProcess != NULL);
1038
1039 /* Sanity checks */
1041 ASSERT(EntryProcess->Vm.Flags.SessionLeader == 0);
1042 ASSERT(EntryProcess->Session != NULL);
1043
1044 /* Get rid of the reference we took */
1045 ObDereferenceObject(EntryProcess);
1046}
1047
1048PVOID
1049NTAPI
1052{
1053 PLIST_ENTRY ListEntry;
1054 PMM_SESSION_SPACE Session;
1056 KIRQL OldIrql;
1057
1058 /* Acquire the expansion lock while touching the session */
1060
1061 /* Loop all entries in the session ws list */
1062 ListEntry = MiSessionWsList.Flink;
1063 while (ListEntry != &MiSessionWsList)
1064 {
1065 Session = CONTAINING_RECORD(ListEntry, MM_SESSION_SPACE, WsListEntry);
1066 ListEntry = ListEntry->Flink;
1067
1068 /* Check if this is the session we are looking for */
1069 if (Session->SessionId == SessionId)
1070 {
1071 /* Check if we also have a process in the process list */
1072 if (!IsListEmpty(&Session->ProcessList))
1073 {
1075 EPROCESS,
1076 SessionProcessLinks);
1077
1078 /* Reference the process */
1080 break;
1081 }
1082 }
1083 }
1084
1085 /* Release the lock again */
1087
1088 return Process;
1089}
#define PAGED_CODE()
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
HARDWARE_PDE_ARMV6 TempPde
Definition: winldr.c:78
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define RtlInitializeBitMap
Definition: dbgbitmap.h:326
#define RtlClearAllBits
Definition: dbgbitmap.h:329
#define RtlClearBit
Definition: dbgbitmap.h:330
#define RtlFindClearBitsAndSet
Definition: dbgbitmap.h:333
#define RtlCheckBit
Definition: dbgbitmap.h:349
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
ULONG SessionId
Definition: dllmain.c:28
#define ULONG_PTR
Definition: config.h:101
#define _IRQL_requires_max_(irql)
Definition: driverspecs.h:230
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG KSPIN_LOCK
Definition: env_spec_w32.h:72
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define APC_LEVEL
Definition: env_spec_w32.h:695
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define KeSetEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:476
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define ExInitializePushLock
Definition: ex.h:1013
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLdouble u1
Definition: glext.h:8308
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
#define PSF_PROCESS_IN_SESSION_BIT
Definition: pstypes.h:289
#define PSF_SESSION_CREATION_UNDERWAY_BIT
Definition: pstypes.h:287
#define InterlockedCompareExchange
Definition: interlocked.h:104
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
if(dx< 0)
Definition: linetemp.h:194
PFN_NUMBER MmLowestPhysicalPage
Definition: meminit.c:30
PFN_NUMBER MmHighestPhysicalPage
Definition: meminit.c:31
@ SystemPteSpace
Definition: miarm.h:417
FORCEINLINE KIRQL MiAcquireExpansionLock(VOID)
Definition: miarm.h:1544
FORCEINLINE BOOLEAN MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
Definition: miarm.h:959
#define MI_SESSION_TAG_PAGES_MAXIMUM
Definition: miarm.h:262
struct _MM_SESSION_SPACE * PMM_SESSION_SPACE
#define MI_SET_PFN_DELETED(x)
Definition: miarm.h:208
#define MI_IS_SESSION_ADDRESS(Address)
Definition: miarm.h:185
#define MI_GET_NEXT_COLOR()
Definition: miarm.h:246
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
VOID NTAPI MiInitializePfnAndMakePteValid(IN PFN_NUMBER PageFrameIndex, IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: pfnlist.c:1041
FORCEINLINE VOID MiReleaseExpansionLock(KIRQL OldIrql)
Definition: miarm.h:1557
VOID NTAPI MiInitializePfnForOtherProcess(IN PFN_NUMBER PageFrameIndex, IN PVOID PteAddress, IN PFN_NUMBER PteFrame)
Definition: pfnlist.c:1301
#define MI_INITIAL_SESSION_IDS
Definition: miarm.h:221
FORCEINLINE VOID MI_WRITE_VALID_PDE(IN PMMPDE PointerPde, IN MMPDE TempPde)
Definition: miarm.h:1031
VOID NTAPI MiDecrementShareCount(IN PMMPFN Pfn1, IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:1141
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
BOOLEAN NTAPI MiInitializeSystemSpaceMap(IN PMMSESSION InputSession OPTIONAL)
Definition: section.c:222
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:973
PVOID MiSessionSpaceWs
Definition: mminit.c:130
FORCEINLINE PMMPFN MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
Definition: miarm.h:1587
#define MI_SESSION_DATA_PAGES_MAXIMUM
Definition: miarm.h:261
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2413
BOOLEAN NTAPI MmIsAddressValid(IN PVOID VirtualAddress)
Definition: mmsup.c:174
#define MiAddressToPte(x)
Definition: mmx86.c:19
#define MiAddressToPde(x)
Definition: mmx86.c:20
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _MMWSL * PMMWSL
struct _MMWSLE * PMMWSLE
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
@ NotificationEvent
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
LCID PsDefaultSystemLocaleId
Definition: locale.c:20
LCID PsDefaultThreadLocaleId
Definition: locale.c:24
#define MI_MAKE_DIRTY_PAGE(x)
Definition: mm.h:98
#define PDE_MAPPED_VA
Definition: mm.h:39
#define PFN_FROM_PTE(v)
Definition: mm.h:92
#define MiPteToAddress(_Pte)
Definition: mm.h:116
VOID FASTCALL KeZeroPages(IN PVOID Address, IN ULONG Size)
Definition: cpu.c:56
@ MI_USAGE_INIT_MEMORY
Definition: mm.h:345
PFN_COUNT MmNumberOfPhysicalPages
Definition: init.c:48
#define MI_SET_USAGE(x)
Definition: mm.h:317
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
VOID NTAPI KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors)
Definition: cpu.c:652
PVOID MmSessionBase
Definition: init.c:33
PETHREAD MiExpansionLockOwner
Definition: session.c:33
PFN_NUMBER MiSessionTagPages
Definition: session.c:22
NTSTATUS NTAPI MmSessionCreate(OUT PULONG SessionId)
Definition: session.c:827
BOOLEAN NTAPI MmIsSessionAddress(IN PVOID Address)
Definition: session.c:48
ULONG NTAPI MmGetSessionId(IN PEPROCESS Process)
Definition: session.c:179
VOID NTAPI MiReleaseProcessReferenceToSessionDataPage(IN PMM_SESSION_SPACE SessionGlobal)
Definition: session.c:209
VOID NTAPI MiSessionAddProcess(IN PEPROCESS NewProcess)
Definition: session.c:423
PFN_NUMBER MiSessionCreateCharge
Definition: session.c:23
PMM_SESSION_SPACE MmSessionSpace
Definition: session.c:21
NTSTATUS NTAPI MiSessionCreateInternal(OUT PULONG SessionId)
Definition: session.c:599
VOID NTAPI MiDereferenceSessionFinal(VOID)
Definition: session.c:273
ULONG NTAPI MmGetSessionIdEx(IN PEPROCESS Process)
Definition: session.c:194
PFN_NUMBER MiSessionBigPoolPages
Definition: session.c:23
PRTL_BITMAP MiSessionIdBitmap
Definition: session.c:26
VOID NTAPI MiInitializeSessionIds(VOID)
Definition: session.c:116
KGUARDED_MUTEX MiSessionIdMutex
Definition: session.c:24
KSPIN_LOCK MmExpansionLock
Definition: session.c:32
VOID NTAPI MmQuitNextSession(_Inout_ PVOID SessionEntry)
Definition: session.c:1030
VOID NTAPI MiSessionLeader(IN PEPROCESS Process)
Definition: session.c:167
NTSTATUS NTAPI MmSessionDelete(IN ULONG SessionId)
Definition: session.c:887
LONG MmSessionDataPages
Definition: session.c:25
PVOID NTAPI MmGetSessionById(_In_ ULONG SessionId)
Definition: session.c:1050
NTSTATUS NTAPI MiSessionInitializeWorkingSetList(VOID)
Definition: session.c:461
VOID NTAPI MiSessionRemoveProcess(VOID)
Definition: session.c:392
LCID NTAPI MmGetSessionLocaleId(VOID)
Definition: session.c:56
VOID NTAPI MiDereferenceSession(VOID)
Definition: session.c:339
volatile LONG MiSessionLeaderExists
Definition: session.c:27
PFN_NUMBER MiSessionTagSizePages
Definition: session.c:22
LIST_ENTRY MmWorkingSetExpansionHead
Definition: session.c:30
LIST_ENTRY MiSessionWsList
Definition: session.c:29
PFN_NUMBER MiSessionDataPages
Definition: session.c:22
VOID NTAPI MiInitializeSessionWsSupport(VOID)
Definition: session.c:40
MMPTE ValidKernelPte
Definition: init.c:29
MMPTE ValidKernelPteLocal
Definition: init.c:33
MMPTE ValidKernelPdeLocal
Definition: init.c:32
#define STATUS_UNABLE_TO_FREE_VM
Definition: ntstatus.h:263
#define STATUS_ALREADY_COMMITTED
Definition: ntstatus.h:270
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define STATUS_INVALID_SYSTEM_SERVICE
Definition: ntstatus.h:265
long LONG
Definition: pedump.c:60
static WCHAR Address[46]
Definition: ping.c:68
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
#define PspClearProcessFlag(Process, Flag)
Definition: ps_x.h:35
#define PspSetProcessFlag(Process, Flag)
Definition: ps_x.h:33
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:108
DWORD LCID
Definition: nls.h:13
ULONG PFN_NUMBER
Definition: ke.h:9
#define STATUS_SUCCESS
Definition: shellext.h:65
PVOID Session
Definition: pstypes.h:1326
KPROCESS Pcb
Definition: pstypes.h:1263
MMSUPPORT Vm
Definition: pstypes.h:1357
ULONG Flags
Definition: pstypes.h:1436
LIST_ENTRY SessionProcessLinks
Definition: pstypes.h:1275
ULONG PageFrameNumber
Definition: mmtypes.h:74
ULONG PageFrameNumber
Definition: mmtypes.h:109
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
Definition: mm.h:374
struct _MMPFN::@1805::@1811 e2
union _MMPFN::@1804 u2
ULONG WsIndex
Definition: mm.h:378
ULONG_PTR ShareCount
Definition: mm.h:390
union _MMPFN::@1805 u3
ULONG64 Valid
Definition: mmtypes.h:150
ULONG64 Global
Definition: mmtypes.h:166
union _MMPTE::@2339 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
ULONG_PTR Long
Definition: mmtypes.h:215
ULONG SessionLeader
Definition: mmtypes.h:907
ULONG SessionSpace
Definition: mmtypes.h:905
PMMWSL VmWorkingSetList
Definition: mmtypes.h:943
EX_PUSH_LOCK WorkingSetMutex
Definition: mmtypes.h:961
MMSUPPORT_FLAGS Flags
Definition: mmtypes.h:933
ULONG MinimumWorkingSetSize
Definition: mmtypes.h:941
ULONG MaximumWorkingSetSize
Definition: mmtypes.h:942
LIST_ENTRY WorkingSetExpansionLinks
Definition: mmtypes.h:925
PMMWSLE_HASH HashTable
Definition: mmtypes.h:878
ULONG LastEntry
Definition: mmtypes.h:873
ULONG VadBitMapHint
Definition: mmtypes.h:884
PMMWSLE Wsle
Definition: mmtypes.h:875
ULONG HashTableSize
Definition: mmtypes.h:879
ULONG SessionId
Definition: miarm.h:491
ULONG LongFlags
Definition: miarm.h:488
PFN_NUMBER SessionPageDirectoryIndex
Definition: miarm.h:494
PMMPDE PageTables
Definition: miarm.h:521
LONG ResidentProcessCount
Definition: miarm.h:501
struct _MM_SESSION_SPACE * GlobalVirtualAddress
Definition: miarm.h:484
MM_SESSION_SPACE_FLAGS Flags
Definition: miarm.h:489
MMSESSION Session
Definition: miarm.h:511
union _MM_SESSION_SPACE::@1842 u
LONG ProcessReferenceToSession
Definition: miarm.h:508
ULONG AttachCount
Definition: miarm.h:505
KEVENT AttachEvent
Definition: miarm.h:506
MMSUPPORT Vm
Definition: miarm.h:514
SIZE_T CommittedPages
Definition: miarm.h:496
LIST_ENTRY WsListEntry
Definition: miarm.h:509
LIST_ENTRY ProcessList
Definition: miarm.h:492
SIZE_T NonPageablePages
Definition: miarm.h:495
LONG ReferenceCount
Definition: miarm.h:485
PMMWSLE Wsle
Definition: miarm.h:515
PDRIVER_UNLOAD Win32KDriverUnload
Definition: miarm.h:516
LIST_ENTRY ImageList
Definition: miarm.h:503
#define TAG_MM
Definition: tag.h:113
uint32_t * PULONG
Definition: typedefs.h:59
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
int32_t * PLONG
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING _In_ PCUNICODE_STRING _In_ LCID LocaleId
Definition: wdfpdo.h:437
_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:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define IO_NO_INCREMENT
Definition: iotypes.h:598
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
@ WrVirtualMemory
Definition: ketypes.h:433
* PKAPC_STATE
Definition: ketypes.h:1409
#define ROUND_TO_PAGES(Size)
#define ObDereferenceObject
Definition: obfuncs.h:203
#define ObReferenceObject
Definition: obfuncs.h:204
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define RtlInterlockedClearBits(Flags, Flag)
Definition: rtlfuncs.h:3457