Author: tkreuzer
Date: Sun Feb 16 09:27:01 2014
New Revision: 62208
URL:
http://svn.reactos.org/svn/reactos?rev=62208&view=rev
Log:
[NTOSKRNL]
Implement SystemLookasideInformation case in NtQuerySystemInformation
Modified:
trunk/reactos/ntoskrnl/ex/sysinfo.c
trunk/reactos/ntoskrnl/include/internal/ex.h
Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/sysinfo.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ex/sysinfo.c [iso-8859-1] Sun Feb 16 09:27:01 2014
@@ -178,6 +178,62 @@
/* Done */
return Status;
+}
+
+VOID
+NTAPI
+ExUnlockUserBuffer(PMDL Mdl)
+{
+ MmUnlockPages(Mdl);
+ ExFreePoolWithTag(Mdl, TAG_MDL);
+}
+
+NTSTATUS
+NTAPI
+ExLockUserBuffer(
+ PVOID BaseAddress,
+ ULONG Length,
+ KPROCESSOR_MODE AccessMode,
+ LOCK_OPERATION Operation,
+ PVOID *MappedSystemVa,
+ PMDL *OutMdl)
+{
+ PMDL Mdl;
+ PAGED_CODE();
+
+ *MappedSystemVa = NULL;
+ *OutMdl = NULL;
+
+ /* Allocate an MDL for the buffer */
+ Mdl = IoAllocateMdl(BaseAddress, Length, FALSE, TRUE, NULL);
+ if (Mdl == NULL)
+ {
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Enter SEH for probing */
+ _SEH2_TRY
+ {
+ MmProbeAndLockPages(Mdl, AccessMode, Operation);
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ ExFreePoolWithTag(Mdl, TAG_MDL);
+ return _SEH2_GetExceptionCode();
+ }
+ _SEH2_END;
+
+ /* Return the safe kernel mode buffer */
+ *MappedSystemVa = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority);
+ if (*MappedSystemVa == NULL)
+ {
+ ExUnlockUserBuffer(Mdl);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* Return the MDL */
+ *OutMdl = Mdl;
+ return STATUS_SUCCESS;
}
/* FUNCTIONS *****************************************************************/
@@ -1799,13 +1855,151 @@
return ExpSetTimeZoneInformation((PTIME_ZONE_INFORMATION)Buffer);
}
+static
+VOID
+ExpCopyLookasideInformation(
+ PSYSTEM_LOOKASIDE_INFORMATION *InfoPointer,
+ PULONG RemainingPointer,
+ PLIST_ENTRY ListHead,
+ BOOLEAN ListUsesMisses)
+
+{
+ PSYSTEM_LOOKASIDE_INFORMATION Info;
+ PGENERAL_LOOKASIDE LookasideList;
+ PLIST_ENTRY ListEntry;
+ ULONG Remaining;
+
+ /* Get info pointer and remaining count of free array element */
+ Info = *InfoPointer;
+ Remaining = *RemainingPointer;
+
+ /* Loop as long as we have lookaside lists and free array elements */
+ for (ListEntry = ListHead->Flink;
+ (ListEntry != ListHead) && (Remaining > 0);
+ ListEntry = ListEntry->Flink, Remaining--)
+ {
+ LookasideList = CONTAINING_RECORD(ListEntry, GENERAL_LOOKASIDE, ListEntry);
+
+ /* Fill the next array element */
+ Info->CurrentDepth = LookasideList->Depth;
+ Info->MaximumDepth = LookasideList->MaximumDepth;
+ Info->TotalAllocates = LookasideList->TotalAllocates;
+ Info->TotalFrees = LookasideList->TotalFrees;
+ Info->Type = LookasideList->Type;
+ Info->Tag = LookasideList->Tag;
+ Info->Size = LookasideList->Size;
+
+ /* Check how the lists track misses/hits */
+ if (ListUsesMisses)
+ {
+ /* Copy misses */
+ Info->AllocateMisses = LookasideList->AllocateMisses;
+ Info->FreeMisses = LookasideList->FreeMisses;
+ }
+ else
+ {
+ /* Calculate misses */
+ Info->AllocateMisses = LookasideList->TotalAllocates
+ - LookasideList->AllocateHits;
+ Info->FreeMisses = LookasideList->TotalFrees
+ - LookasideList->FreeHits;
+ }
+ }
+
+ /* Return the updated pointer and remaining count */
+ *InfoPointer = Info;
+ *RemainingPointer = Remaining;
+}
/* Class 45 - Lookaside Information */
QSI_DEF(SystemLookasideInformation)
{
- /* FIXME */
- DPRINT1("NtQuerySystemInformation - SystemLookasideInformation not
implemented\n");
- return STATUS_NOT_IMPLEMENTED;
+ KPROCESSOR_MODE PreviousMode;
+ PSYSTEM_LOOKASIDE_INFORMATION Info;
+ PMDL Mdl;
+ ULONG MaxCount, Remaining;
+ KIRQL OldIrql;
+ NTSTATUS Status;
+
+ /* First we need to lock down the memory, since we are going to access it
+ at high IRQL */
+ PreviousMode = ExGetPreviousMode();
+ Status = ExLockUserBuffer(Buffer,
+ Size,
+ PreviousMode,
+ IoWriteAccess,
+ (PVOID*)&Info,
+ &Mdl);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+ return Status;
+ }
+
+ /* Calculate how many items we can store */
+ Remaining = MaxCount = Size / sizeof(SYSTEM_LOOKASIDE_INFORMATION);
+ if (Remaining == 0)
+ {
+ goto Leave;
+ }
+
+ /* Copy info from pool lookaside lists */
+ ExpCopyLookasideInformation(&Info,
+ &Remaining,
+ &ExPoolLookasideListHead,
+ FALSE);
+ if (Remaining == 0)
+ {
+ goto Leave;
+ }
+
+ /* Copy info from system lookaside lists */
+ ExpCopyLookasideInformation(&Info,
+ &Remaining,
+ &ExSystemLookasideListHead,
+ TRUE);
+ if (Remaining == 0)
+ {
+ goto Leave;
+ }
+
+ /* Acquire spinlock for ExpNonPagedLookasideListHead */
+ OldIrql = KfAcquireSpinLock(&ExpNonPagedLookasideListLock);
+
+ /* Copy info from non-paged lookaside lists */
+ ExpCopyLookasideInformation(&Info,
+ &Remaining,
+ &ExpNonPagedLookasideListHead,
+ TRUE);
+
+ /* Release spinlock for ExpNonPagedLookasideListHead */
+ KfReleaseSpinLock(&ExpNonPagedLookasideListLock, OldIrql);
+
+ if (Remaining == 0)
+ {
+ goto Leave;
+ }
+
+ /* Acquire spinlock for ExpPagedLookasideListHead */
+ OldIrql = KfAcquireSpinLock(&ExpPagedLookasideListLock);
+
+ /* Copy info from paged lookaside lists */
+ ExpCopyLookasideInformation(&Info,
+ &Remaining,
+ &ExpPagedLookasideListHead,
+ TRUE);
+
+ /* Release spinlock for ExpPagedLookasideListHead */
+ KfReleaseSpinLock(&ExpPagedLookasideListLock, OldIrql);
+
+Leave:
+
+ /* Release the locked user buffer */
+ ExUnlockUserBuffer(Mdl);
+
+ /* Return the size of the actually written data */
+ *ReqSize = (MaxCount - Remaining) * sizeof(SYSTEM_LOOKASIDE_INFORMATION);
+ return STATUS_SUCCESS;
}
Modified: trunk/reactos/ntoskrnl/include/internal/ex.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/ex.h [iso-8859-1] Sun Feb 16 09:27:01 2014
@@ -27,6 +27,11 @@
extern ULONG ExpAltTimeZoneBias;
extern LIST_ENTRY ExSystemLookasideListHead;
extern PCALLBACK_OBJECT PowerStateCallback;
+extern LIST_ENTRY ExPoolLookasideListHead;
+extern LIST_ENTRY ExpNonPagedLookasideListHead;
+extern LIST_ENTRY ExpPagedLookasideListHead;
+extern KSPIN_LOCK ExpNonPagedLookasideListLock;
+extern KSPIN_LOCK ExpPagedLookasideListLock;
typedef struct _EXHANDLE
{