mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 12:52:58 +00:00
[NTOS:EX]
- Use all handles enumeration in system instead of enumeration for each process See issue 11906 for more details. svn path=/trunk/; revision=72530
This commit is contained in:
parent
27e451c99f
commit
125c4571ad
1 changed files with 99 additions and 104 deletions
|
@ -17,6 +17,9 @@
|
||||||
/* The maximum size of an environment value (in bytes) */
|
/* The maximum size of an environment value (in bytes) */
|
||||||
#define MAX_ENVVAL_SIZE 1024
|
#define MAX_ENVVAL_SIZE 1024
|
||||||
|
|
||||||
|
extern LIST_ENTRY HandleTableListHead;
|
||||||
|
extern EX_PUSH_LOCK HandleTableListLock;
|
||||||
|
|
||||||
FAST_MUTEX ExpEnvironmentLock;
|
FAST_MUTEX ExpEnvironmentLock;
|
||||||
ERESOURCE ExpFirmwareTableResource;
|
ERESOURCE ExpFirmwareTableResource;
|
||||||
LIST_ENTRY ExpFirmwareTableProviderListHead;
|
LIST_ENTRY ExpFirmwareTableProviderListHead;
|
||||||
|
@ -1168,53 +1171,25 @@ QSI_DEF(SystemNonPagedPoolInformation)
|
||||||
QSI_DEF(SystemHandleInformation)
|
QSI_DEF(SystemHandleInformation)
|
||||||
{
|
{
|
||||||
PSYSTEM_HANDLE_INFORMATION HandleInformation;
|
PSYSTEM_HANDLE_INFORMATION HandleInformation;
|
||||||
KPROCESSOR_MODE PreviousMode;
|
ULONG Index = 0;
|
||||||
PEPROCESS Process;
|
|
||||||
PEPROCESS SystemProcess;
|
|
||||||
ULONG CurrentSize;
|
|
||||||
ULONG NumberOfHandles = 0;
|
|
||||||
ULONG Index;
|
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PMDL Mdl;
|
PMDL Mdl;
|
||||||
|
|
||||||
DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
|
DPRINT("NtQuerySystemInformation - SystemHandleInformation\n");
|
||||||
|
|
||||||
|
/* Set initial required buffer size */
|
||||||
|
*ReqSize = sizeof(SYSTEM_HANDLE_INFORMATION);
|
||||||
|
|
||||||
/* Check user's buffer size */
|
/* Check user's buffer size */
|
||||||
if (Size < sizeof(SYSTEM_HANDLE_INFORMATION))
|
if (Size < *ReqSize)
|
||||||
{
|
{
|
||||||
*ReqSize = sizeof(SYSTEM_HANDLE_INFORMATION);
|
|
||||||
return STATUS_INFO_LENGTH_MISMATCH;
|
return STATUS_INFO_LENGTH_MISMATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve needed buffer size to hold the list of handles */
|
|
||||||
SystemProcess = PsGetNextProcess(NULL);
|
|
||||||
Process = SystemProcess;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
NumberOfHandles += ObGetProcessHandleCount(Process);
|
|
||||||
Process = PsGetNextProcess(Process);
|
|
||||||
}
|
|
||||||
while ((Process != SystemProcess) && (Process != NULL));
|
|
||||||
|
|
||||||
/* Dereference the process which was referenced by PsGetNextProcess */
|
|
||||||
if (Process != NULL) ObDereferenceObject(Process);
|
|
||||||
|
|
||||||
/* Calculate the current size of all handles */
|
|
||||||
CurrentSize = sizeof(SYSTEM_HANDLE_INFORMATION) +
|
|
||||||
((sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO) * NumberOfHandles) -
|
|
||||||
(sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO)));
|
|
||||||
|
|
||||||
*ReqSize = CurrentSize;
|
|
||||||
|
|
||||||
/* Check user's buffer size */
|
|
||||||
if (CurrentSize > Size) return STATUS_INFO_LENGTH_MISMATCH;
|
|
||||||
|
|
||||||
/* We need to lock down the memory */
|
/* We need to lock down the memory */
|
||||||
PreviousMode = ExGetPreviousMode();
|
|
||||||
Status = ExLockUserBuffer(Buffer,
|
Status = ExLockUserBuffer(Buffer,
|
||||||
Size,
|
Size,
|
||||||
PreviousMode,
|
ExGetPreviousMode(),
|
||||||
IoWriteAccess,
|
IoWriteAccess,
|
||||||
(PVOID*)&HandleInformation,
|
(PVOID*)&HandleInformation,
|
||||||
&Mdl);
|
&Mdl);
|
||||||
|
@ -1224,91 +1199,111 @@ QSI_DEF(SystemHandleInformation)
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialization of count of handles */
|
_SEH2_TRY
|
||||||
HandleInformation->NumberOfHandles = NumberOfHandles;
|
|
||||||
|
|
||||||
/* Now get handles from all processes. */
|
|
||||||
SystemProcess = PsGetNextProcess(NULL);
|
|
||||||
Process = SystemProcess;
|
|
||||||
|
|
||||||
Index = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
PLIST_ENTRY NextTableEntry;
|
||||||
EXHANDLE Handle;
|
|
||||||
|
|
||||||
/* Enter a critical region */
|
/* Enumerate all system handles */
|
||||||
KeEnterCriticalRegion();
|
for (NextTableEntry = HandleTableListHead.Flink;
|
||||||
|
NextTableEntry != &HandleTableListHead;
|
||||||
_SEH2_TRY
|
NextTableEntry = NextTableEntry->Flink)
|
||||||
{
|
{
|
||||||
/* Set the initial value and loop the entries */
|
PHANDLE_TABLE HandleTable;
|
||||||
Handle.Value = 0;
|
|
||||||
while ((HandleTableEntry = ExpLookupHandleTableEntry(Process->ObjectTable, Handle)))
|
/* Enter a critical region */
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
/* Acquire the handle table lock */
|
||||||
|
ExAcquirePushLockExclusive(&HandleTableListLock);
|
||||||
|
|
||||||
|
/* Get current handle table */
|
||||||
|
HandleTable = CONTAINING_RECORD(NextTableEntry, HANDLE_TABLE, HandleTableList);
|
||||||
|
|
||||||
|
_SEH2_TRY
|
||||||
{
|
{
|
||||||
/* Validate the entry */
|
PHANDLE_TABLE_ENTRY HandleTableEntry;
|
||||||
if ((HandleTableEntry->Object) &&
|
EXHANDLE Handle;
|
||||||
(HandleTableEntry->NextFreeTableEntry != -2))
|
|
||||||
|
/* Set the initial value and loop the entries */
|
||||||
|
Handle.Value = 0;
|
||||||
|
while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle)))
|
||||||
{
|
{
|
||||||
/* Lock the entry */
|
/* Validate the entry */
|
||||||
if (ExpLockHandleTableEntry(Process->ObjectTable, HandleTableEntry))
|
if ((HandleTableEntry->Object) &&
|
||||||
|
(HandleTableEntry->NextFreeTableEntry != -2))
|
||||||
{
|
{
|
||||||
_SEH2_TRY
|
/* Increase of count of handles */
|
||||||
|
++HandleInformation->NumberOfHandles;
|
||||||
|
|
||||||
|
/* Increase required buffer size */
|
||||||
|
*ReqSize += sizeof(SYSTEM_HANDLE_TABLE_ENTRY_INFO);
|
||||||
|
|
||||||
|
/* Check user's buffer size */
|
||||||
|
if (*ReqSize > Size)
|
||||||
{
|
{
|
||||||
POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
|
/* It is correct? How it is correct to leave the enclosed SEH blocks? */
|
||||||
|
_SEH2_YIELD(return STATUS_INFO_LENGTH_MISMATCH);
|
||||||
/* Filling handle information */
|
|
||||||
HandleInformation->Handles[Index].UniqueProcessId =
|
|
||||||
(USHORT)(ULONG_PTR) Process->UniqueProcessId;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].ObjectTypeIndex =
|
|
||||||
(UCHAR) ObjectHeader->Type->Index;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].HandleAttributes =
|
|
||||||
HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].HandleValue =
|
|
||||||
(USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
|
|
||||||
|
|
||||||
HandleInformation->Handles[Index].GrantedAccess =
|
|
||||||
HandleTableEntry->GrantedAccess;
|
|
||||||
|
|
||||||
++Index;
|
|
||||||
}
|
}
|
||||||
_SEH2_FINALLY
|
|
||||||
|
/* Lock the entry */
|
||||||
|
if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry))
|
||||||
{
|
{
|
||||||
/* Unlock it */
|
_SEH2_TRY
|
||||||
ExUnlockHandleTableEntry(Process->ObjectTable, HandleTableEntry);
|
{
|
||||||
|
POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
|
||||||
|
|
||||||
|
/* Filling handle information */
|
||||||
|
HandleInformation->Handles[Index].UniqueProcessId =
|
||||||
|
(USHORT)(ULONG_PTR) HandleTable->UniqueProcessId;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].CreatorBackTraceIndex = 0;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].ObjectTypeIndex =
|
||||||
|
(UCHAR) ObjectHeader->Type->Index;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].HandleAttributes =
|
||||||
|
HandleTableEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].HandleValue =
|
||||||
|
(USHORT)(ULONG_PTR) Handle.GenericHandleOverlay;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].Object = &ObjectHeader->Body;
|
||||||
|
|
||||||
|
HandleInformation->Handles[Index].GrantedAccess =
|
||||||
|
HandleTableEntry->GrantedAccess;
|
||||||
|
|
||||||
|
++Index;
|
||||||
|
}
|
||||||
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
|
/* Unlock it */
|
||||||
|
ExUnlockHandleTableEntry(HandleTable, HandleTableEntry);
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
}
|
}
|
||||||
_SEH2_END;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
Handle.Value += sizeof(HANDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to the next entry */
|
|
||||||
Handle.Value += sizeof(HANDLE);
|
|
||||||
}
|
}
|
||||||
}
|
_SEH2_FINALLY
|
||||||
_SEH2_FINALLY
|
{
|
||||||
{
|
/* Release the lock */
|
||||||
/* Leave the critical region */
|
ExReleasePushLockExclusive(&HandleTableListLock);
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
}
|
|
||||||
_SEH2_END;
|
|
||||||
|
|
||||||
Process = PsGetNextProcess(Process);
|
/* Leave the critical region */
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
}
|
||||||
|
_SEH2_END;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while ((Process != SystemProcess) && (Process != NULL));
|
_SEH2_FINALLY
|
||||||
|
{
|
||||||
/* Dereference the process which was referenced by PsGetNextProcess */
|
/* Release the locked user buffer */
|
||||||
if (Process != NULL) ObDereferenceObject(Process);
|
ExUnlockUserBuffer(Mdl);
|
||||||
|
}
|
||||||
/* Release the locked user buffer */
|
_SEH2_END;
|
||||||
ExUnlockUserBuffer(Mdl);
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue