Author: pschweitzer
Date: Sun Jun 11 17:32:56 2017
New Revision: 75006
URL:
http://svn.reactos.org/svn/reactos?rev=75006&view=rev
Log:
[NTOSKRNL]
Implement SystemExtendedHandleInformation based on SystemHandleInformation.
To be improved...
Passes ntdll_winetest:info.
CORE-13368
Modified:
trunk/reactos/ntoskrnl/ex/sysinfo.c
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 Jun 11 17:32:56 2017
@@ -2375,24 +2375,133 @@
/* Class 64 - Extended handle information */
QSI_DEF(SystemExtendedHandleInformation)
{
- PSYSTEM_HANDLE_INFORMATION_EX HandleInformation =
(PSYSTEM_HANDLE_INFORMATION_EX)Buffer;
-
- DPRINT1("NtQuerySystemInformation - SystemExtendedHandleInformation not
implemented\n");
+ 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();
+
+ 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