mirror of
https://github.com/reactos/reactos.git
synced 2024-07-06 04:35:07 +00:00
- Documented ObpDeleteNameCheck and ObpSetPermanentObject
- Added function documentation header for ObpDecrementHandleCount and ObpSetHandleAttributes - Modified ObpDecrementHandleCount to accept Process and GrantedAccess paraemters since the definition for the Close Procedure Callback requires them (and we were currently sending NULL). Also send 0 for process handle count, since we don't yet parse/support per-process handle databases. - Minor optimization: All objects have an object type, don't actually check if the object has one when decrementing a handle. - Minor accounting fix: Decrement the total number of handles for the object type whose handle count is being decreased. svn path=/trunk/; revision=22245
This commit is contained in:
parent
afea80bbe4
commit
18ed42b8a4
|
@ -19,8 +19,64 @@
|
||||||
|
|
||||||
PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
||||||
|
|
||||||
|
/* UGLY FUNCTIONS ************************************************************/
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable)
|
||||||
|
{
|
||||||
|
return HandleTable->HandleCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
|
||||||
|
PEPROCESS Process,
|
||||||
|
int Count)
|
||||||
|
{
|
||||||
|
ULONG P;
|
||||||
|
// KIRQL oldIrql;
|
||||||
|
|
||||||
|
// pshi->HandleValue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
This will never work with ROS! M$, I guess uses 0 -> 65535.
|
||||||
|
Ros uses 0 -> 4294967295!
|
||||||
|
*/
|
||||||
|
|
||||||
|
P = (ULONG) Process->UniqueProcessId;
|
||||||
|
pshi->UniqueProcessId = (USHORT) P;
|
||||||
|
|
||||||
|
// KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
|
||||||
|
|
||||||
|
// pshi->GrantedAccess;
|
||||||
|
// pshi->Object;
|
||||||
|
// pshi->TypeIndex;
|
||||||
|
// pshi->HandleAttributes;
|
||||||
|
|
||||||
|
// KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
/*++
|
||||||
|
* @name ObpDeleteNameCheck
|
||||||
|
*
|
||||||
|
* The ObpDeleteNameCheck routine checks if a named object should be
|
||||||
|
* removed from the object directory namespace.
|
||||||
|
*
|
||||||
|
* @param Object
|
||||||
|
* Pointer to the object to check for possible removal.
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
* @remarks An object is removed if the following 4 criteria are met:
|
||||||
|
* 1) The object has 0 handles open
|
||||||
|
* 2) The object is in the directory namespace and has a name
|
||||||
|
* 3) The object is not permanent
|
||||||
|
*
|
||||||
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpDeleteNameCheck(IN PVOID Object)
|
ObpDeleteNameCheck(IN PVOID Object)
|
||||||
|
@ -88,17 +144,19 @@ ObpDeleteNameCheck(IN PVOID Object)
|
||||||
/*++
|
/*++
|
||||||
* @name ObpSetPermanentObject
|
* @name ObpSetPermanentObject
|
||||||
*
|
*
|
||||||
* The ObpSetPermanentObject routine <FILLMEIN>
|
* The ObpSetPermanentObject routine makes an sets or clears the permanent
|
||||||
|
* flag of an object, thus making it either permanent or temporary.
|
||||||
*
|
*
|
||||||
* @param ObjectBody
|
* @param ObjectBody
|
||||||
* <FILLMEIN>
|
* Pointer to the object to make permanent or temporary.
|
||||||
*
|
*
|
||||||
* @param Permanent
|
* @param Permanent
|
||||||
* <FILLMEIN>
|
* Flag specifying which operation to perform.
|
||||||
*
|
*
|
||||||
* @return None.
|
* @return None.
|
||||||
*
|
*
|
||||||
* @remarks None.
|
* @remarks If the object is being made temporary, then it will be checked
|
||||||
|
* as a candidate for immediate removal from the namespace.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
|
@ -125,63 +183,133 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
/*++
|
||||||
NTAPI
|
* @name ObpDecrementHandleCount
|
||||||
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable)
|
*
|
||||||
{
|
* The ObpDecrementHandleCount routine <FILLMEIN>
|
||||||
return HandleTable->HandleCount;
|
*
|
||||||
}
|
* @param ObjectBody
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @param Process
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @param GrantedAccess
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @return None.
|
||||||
|
*
|
||||||
|
* @remarks None.
|
||||||
|
*
|
||||||
|
*--*/
|
||||||
VOID
|
VOID
|
||||||
ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
|
NTAPI
|
||||||
PEPROCESS Process,
|
ObpDecrementHandleCount(IN PVOID ObjectBody,
|
||||||
int Count)
|
IN PEPROCESS Process,
|
||||||
|
IN ACCESS_MASK GrantedAccess)
|
||||||
{
|
{
|
||||||
ULONG P;
|
POBJECT_HEADER ObjectHeader;
|
||||||
// KIRQL oldIrql;
|
POBJECT_TYPE ObjectType;
|
||||||
|
LONG SystemHandleCount, ProcessHandleCount;
|
||||||
|
|
||||||
// pshi->HandleValue;
|
/* Get the object type and header */
|
||||||
|
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
|
||||||
|
ObjectType = ObjectHeader->Type;
|
||||||
|
|
||||||
/*
|
/* FIXME: The process handle count should be in the Handle DB. Investigate */
|
||||||
This will never work with ROS! M$, I guess uses 0 -> 65535.
|
SystemHandleCount = ObjectHeader->HandleCount;
|
||||||
Ros uses 0 -> 4294967295!
|
ProcessHandleCount = 0;
|
||||||
*/
|
|
||||||
|
|
||||||
P = (ULONG) Process->UniqueProcessId;
|
/* Decrement the handle count */
|
||||||
pshi->UniqueProcessId = (USHORT) P;
|
InterlockedDecrement(&ObjectHeader->HandleCount);
|
||||||
|
|
||||||
// KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
|
/* Check if we have a close procedure */
|
||||||
|
if (ObjectType->TypeInfo.CloseProcedure)
|
||||||
// pshi->GrantedAccess;
|
|
||||||
// pshi->Object;
|
|
||||||
// pshi->TypeIndex;
|
|
||||||
// pshi->HandleAttributes;
|
|
||||||
|
|
||||||
// KeReleaseSpinLock( &Process->HandleTable.ListLock, oldIrql );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
static VOID
|
|
||||||
ObpDecrementHandleCount(PVOID ObjectBody)
|
|
||||||
{
|
|
||||||
POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
|
|
||||||
LONG NewHandleCount = InterlockedDecrement(&ObjectHeader->HandleCount);
|
|
||||||
DPRINT("Header: %x\n", ObjectHeader);
|
|
||||||
DPRINT("NewHandleCount: %x\n", NewHandleCount);
|
|
||||||
DPRINT("OBJECT_HEADER_TO_NAME_INFO: %x\n", OBJECT_HEADER_TO_NAME_INFO(ObjectHeader));
|
|
||||||
|
|
||||||
if ((ObjectHeader->Type != NULL) &&
|
|
||||||
(ObjectHeader->Type->TypeInfo.CloseProcedure != NULL))
|
|
||||||
{
|
{
|
||||||
/* the handle count should be decremented but we pass the previous value
|
/* Call it */
|
||||||
to the callback */
|
ObjectType->TypeInfo.CloseProcedure(Process,
|
||||||
ObjectHeader->Type->TypeInfo.CloseProcedure(NULL, ObjectBody, 0, NewHandleCount + 1, NewHandleCount + 1);
|
ObjectBody,
|
||||||
|
GrantedAccess,
|
||||||
|
ProcessHandleCount,
|
||||||
|
SystemHandleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we should delete the object */
|
/* Check if we should delete the object */
|
||||||
ObpDeleteNameCheck(ObjectBody);
|
ObpDeleteNameCheck(ObjectBody);
|
||||||
|
|
||||||
|
/* Decrease the total number of handles for this type */
|
||||||
|
ObjectType->TotalNumberOfHandles--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NTSTATUS
|
||||||
|
ObpDeleteHandle(HANDLE Handle)
|
||||||
|
{
|
||||||
|
PHANDLE_TABLE_ENTRY HandleEntry;
|
||||||
|
PVOID Body;
|
||||||
|
POBJECT_HEADER ObjectHeader;
|
||||||
|
PHANDLE_TABLE ObjectTable;
|
||||||
|
ACCESS_MASK GrantedAccess;
|
||||||
|
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
DPRINT("ObpDeleteHandle(Handle %p)\n",Handle);
|
||||||
|
|
||||||
|
ObjectTable = PsGetCurrentProcess()->ObjectTable;
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
|
||||||
|
HandleEntry = ExMapHandleToPointer(ObjectTable,
|
||||||
|
Handle);
|
||||||
|
if(HandleEntry != NULL)
|
||||||
|
{
|
||||||
|
if(HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
||||||
|
{
|
||||||
|
ExUnlockHandleTableEntry(ObjectTable,
|
||||||
|
HandleEntry);
|
||||||
|
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
return STATUS_HANDLE_NOT_CLOSABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
||||||
|
Body = &ObjectHeader->Body;
|
||||||
|
GrantedAccess = HandleEntry->GrantedAccess;
|
||||||
|
|
||||||
|
/* destroy and unlock the handle entry */
|
||||||
|
ExDestroyHandleByEntry(ObjectTable,
|
||||||
|
HandleEntry,
|
||||||
|
Handle);
|
||||||
|
|
||||||
|
ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess);
|
||||||
|
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
return STATUS_INVALID_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*++
|
||||||
|
* @name ObpSetHandleAttributes
|
||||||
|
*
|
||||||
|
* The ObpSetHandleAttributes routine <FILLMEIN>
|
||||||
|
*
|
||||||
|
* @param HandleTable
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @param HandleTableEntry
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @param Context
|
||||||
|
* <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @return <FILLMEIN>.
|
||||||
|
*
|
||||||
|
* @remarks None.
|
||||||
|
*
|
||||||
|
*--*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
||||||
|
@ -229,54 +357,6 @@ ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS
|
|
||||||
ObpDeleteHandle(HANDLE Handle)
|
|
||||||
{
|
|
||||||
PHANDLE_TABLE_ENTRY HandleEntry;
|
|
||||||
PVOID Body;
|
|
||||||
POBJECT_HEADER ObjectHeader;
|
|
||||||
PHANDLE_TABLE ObjectTable;
|
|
||||||
|
|
||||||
PAGED_CODE();
|
|
||||||
|
|
||||||
DPRINT("ObpDeleteHandle(Handle %p)\n",Handle);
|
|
||||||
|
|
||||||
ObjectTable = PsGetCurrentProcess()->ObjectTable;
|
|
||||||
|
|
||||||
KeEnterCriticalRegion();
|
|
||||||
|
|
||||||
HandleEntry = ExMapHandleToPointer(ObjectTable,
|
|
||||||
Handle);
|
|
||||||
if(HandleEntry != NULL)
|
|
||||||
{
|
|
||||||
if(HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE)
|
|
||||||
{
|
|
||||||
ExUnlockHandleTableEntry(ObjectTable,
|
|
||||||
HandleEntry);
|
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
|
||||||
return STATUS_HANDLE_NOT_CLOSABLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectHeader = EX_HTE_TO_HDR(HandleEntry);
|
|
||||||
Body = &ObjectHeader->Body;
|
|
||||||
|
|
||||||
/* destroy and unlock the handle entry */
|
|
||||||
ExDestroyHandleByEntry(ObjectTable,
|
|
||||||
HandleEntry,
|
|
||||||
Handle);
|
|
||||||
|
|
||||||
ObpDecrementHandleCount(Body);
|
|
||||||
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
|
||||||
}
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
return STATUS_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
ObDuplicateObject(PEPROCESS SourceProcess,
|
ObDuplicateObject(PEPROCESS SourceProcess,
|
||||||
|
@ -448,7 +528,7 @@ SweepHandleCallback(PHANDLE_TABLE HandleTable,
|
||||||
ObjectHeader = EX_OBJ_TO_HDR(Object);
|
ObjectHeader = EX_OBJ_TO_HDR(Object);
|
||||||
ObjectBody = &ObjectHeader->Body;
|
ObjectBody = &ObjectHeader->Body;
|
||||||
|
|
||||||
ObpDecrementHandleCount(ObjectBody);
|
ObpDecrementHandleCount(ObjectBody, PsGetCurrentProcess(), GrantedAccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOLEAN STDCALL
|
static BOOLEAN STDCALL
|
||||||
|
|
Loading…
Reference in a new issue