[NTOSKRNL]
authorPierre Schweitzer <pierre@reactos.org>
Sun, 11 Jun 2017 17:32:56 +0000 (17:32 +0000)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 11 Jun 2017 17:32:56 +0000 (17:32 +0000)
Implement SystemExtendedHandleInformation based on SystemHandleInformation.
To be improved...
Passes ntdll_winetest:info.

CORE-13368

svn path=/trunk/; revision=75006

reactos/ntoskrnl/ex/sysinfo.c

index 8d7e37c..bfdab89 100644 (file)
@@ -2375,24 +2375,133 @@ QSI_DEF(SystemNumaAvailableMemory)
 /* Class 64 - Extended handle information  */
 QSI_DEF(SystemExtendedHandleInformation)
 {
-    PSYSTEM_HANDLE_INFORMATION_EX HandleInformation = (PSYSTEM_HANDLE_INFORMATION_EX)Buffer;
+    PSYSTEM_HANDLE_INFORMATION_EX HandleInformation;
+    PLIST_ENTRY NextTableEntry;
+    PHANDLE_TABLE HandleTable;
+    PHANDLE_TABLE_ENTRY HandleTableEntry;
+    EXHANDLE Handle;
+    ULONG Index = 0;
+    NTSTATUS Status;
+    PMDL Mdl;
+    PAGED_CODE();
 
-    DPRINT1("NtQuerySystemInformation - SystemExtendedHandleInformation not implemented\n");
+    DPRINT("NtQuerySystemInformation - SystemExtendedHandleInformation\n");
 
     /* Set initial required buffer size */
     *ReqSize = FIELD_OFFSET(SYSTEM_HANDLE_INFORMATION_EX, Handle);
 
-    /* Validate input size */
+    /* Check user's buffer size */
     if (Size < *ReqSize)
     {
         return STATUS_INFO_LENGTH_MISMATCH;
     }
 
-    /* FIXME */
+    /* We need to lock down the memory */
+    Status = ExLockUserBuffer(Buffer,
+                              Size,
+                              ExGetPreviousMode(),
+                              IoWriteAccess,
+                              (PVOID*)&HandleInformation,
+                              &Mdl);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to lock the user buffer: 0x%lx\n", Status);
+        return Status;
+    }
+
+    /* Reset of count of handles */
     HandleInformation->Count = 0;
-    return STATUS_SUCCESS;
-}
 
+    /* Enter a critical region */
+    KeEnterCriticalRegion();
+
+    /* Acquire the handle table lock */
+    ExAcquirePushLockShared(&HandleTableListLock);
+
+    /* Enumerate all system handles */
+    for (NextTableEntry = HandleTableListHead.Flink;
+         NextTableEntry != &HandleTableListHead;
+         NextTableEntry = NextTableEntry->Flink)
+    {
+        /* Get current handle table */
+        HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
+
+        /* Set the initial value and loop the entries */
+        Handle.Value = 0;
+        while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
+        {
+            /* Validate the entry */
+            if ((HandleTableEntry->Object) &&
+                (HandleTableEntry->NextFreeTableEntry != -2))
+            {
+                /* Increase of count of handles */
+                ++HandleInformation->Count;
+
+                /* Lock the entry */
+                if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
+                {
+                    /* Increase required buffer size */
+                    *ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO_EX);
+
+                    /* Check user's buffer size */
+                    if (*ReqSize > Size)
+                    {
+                        Status = STATUS_INFO_LENGTH_MISMATCH;
+                    }
+                    else
+                    {
+                        POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
+
+                        /* Filling handle information */
+                        HandleInformation->Handle[Index].UniqueProcessId =
+                            (USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
+
+                        HandleInformation->Handle[Index].CreatorBackTraceIndex = 0;
+
+#if 0 /* FIXME!!! Type field currupted */
+                        HandleInformation->Handles[Index].ObjectTypeIndex =
+                            (UCHAR) ObjectHeader->Type->Index;
+#else
+                        HandleInformation->Handle[Index].ObjectTypeIndex = 0;
+#endif
+
+                        HandleInformation->Handle[Index].HandleAttributes =
+                            HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
+
+                        HandleInformation->Handle[Index].HandleValue =
+                            (USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
+
+                        HandleInformation->Handle[Index].Object = &ObjectHeader->Body;
+
+                        HandleInformation->Handle[Index].GrantedAccess =
+                            HandleTableEntry->GrantedAccess;
+
+                        HandleInformation->Handle[Index].Reserved = 0;
+
+                        ++Index;
+                    }
+
+                    /* Unlock it */
+                    ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
+                }
+            }
+
+            /* Go to the next entry */
+            Handle.Value += sizeof(HANDLE);
+        }
+    }
+
+    /* Release the lock */
+    ExReleasePushLockShared(&HandleTableListLock);
+
+    /* Leave the critical region */
+    KeLeaveCriticalRegion();
+
+    /* Release the locked user buffer */
+    ExUnlockUserBuffer(Mdl);
+
+    return Status;
+}
 
 /* Query/Set Calls Table */
 typedef