mirror of
https://github.com/reactos/reactos.git
synced 2024-07-03 11:14:33 +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;
|
||||
|
||||
/* 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 *********************************************************/
|
||||
|
||||
/*++
|
||||
* @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
|
||||
NTAPI
|
||||
ObpDeleteNameCheck(IN PVOID Object)
|
||||
|
@ -88,17 +144,19 @@ ObpDeleteNameCheck(IN PVOID Object)
|
|||
/*++
|
||||
* @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
|
||||
* <FILLMEIN>
|
||||
* Pointer to the object to make permanent or temporary.
|
||||
*
|
||||
* @param Permanent
|
||||
* <FILLMEIN>
|
||||
* Flag specifying which operation to perform.
|
||||
*
|
||||
* @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
|
||||
|
@ -125,63 +183,133 @@ ObpSetPermanentObject(IN PVOID ObjectBody,
|
|||
}
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable)
|
||||
{
|
||||
return HandleTable->HandleCount;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpDecrementHandleCount
|
||||
*
|
||||
* The ObpDecrementHandleCount routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectBody
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param Process
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param GrantedAccess
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
ObpGetNextHandleByProcessCount(PSYSTEM_HANDLE_TABLE_ENTRY_INFO pshi,
|
||||
PEPROCESS Process,
|
||||
int Count)
|
||||
NTAPI
|
||||
ObpDecrementHandleCount(IN PVOID ObjectBody,
|
||||
IN PEPROCESS Process,
|
||||
IN ACCESS_MASK GrantedAccess)
|
||||
{
|
||||
ULONG P;
|
||||
// KIRQL oldIrql;
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
POBJECT_TYPE ObjectType;
|
||||
LONG SystemHandleCount, ProcessHandleCount;
|
||||
|
||||
// pshi->HandleValue;
|
||||
/* Get the object type and header */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
|
||||
ObjectType = ObjectHeader->Type;
|
||||
|
||||
/*
|
||||
This will never work with ROS! M$, I guess uses 0 -> 65535.
|
||||
Ros uses 0 -> 4294967295!
|
||||
*/
|
||||
/* FIXME: The process handle count should be in the Handle DB. Investigate */
|
||||
SystemHandleCount = ObjectHeader->HandleCount;
|
||||
ProcessHandleCount = 0;
|
||||
|
||||
P = (ULONG) Process->UniqueProcessId;
|
||||
pshi->UniqueProcessId = (USHORT) P;
|
||||
/* Decrement the handle count */
|
||||
InterlockedDecrement(&ObjectHeader->HandleCount);
|
||||
|
||||
// KeAcquireSpinLock( &Process->HandleTable.ListLock, &oldIrql );
|
||||
|
||||
// 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))
|
||||
/* Check if we have a close procedure */
|
||||
if (ObjectType->TypeInfo.CloseProcedure)
|
||||
{
|
||||
/* the handle count should be decremented but we pass the previous value
|
||||
to the callback */
|
||||
ObjectHeader->Type->TypeInfo.CloseProcedure(NULL, ObjectBody, 0, NewHandleCount + 1, NewHandleCount + 1);
|
||||
/* Call it */
|
||||
ObjectType->TypeInfo.CloseProcedure(Process,
|
||||
ObjectBody,
|
||||
GrantedAccess,
|
||||
ProcessHandleCount,
|
||||
SystemHandleCount);
|
||||
}
|
||||
|
||||
/* Check if we should delete the object */
|
||||
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
|
||||
NTAPI
|
||||
ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
||||
|
@ -229,54 +357,6 @@ ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable,
|
|||
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
|
||||
NTAPI
|
||||
ObDuplicateObject(PEPROCESS SourceProcess,
|
||||
|
@ -448,7 +528,7 @@ SweepHandleCallback(PHANDLE_TABLE HandleTable,
|
|||
ObjectHeader = EX_OBJ_TO_HDR(Object);
|
||||
ObjectBody = &ObjectHeader->Body;
|
||||
|
||||
ObpDecrementHandleCount(ObjectBody);
|
||||
ObpDecrementHandleCount(ObjectBody, PsGetCurrentProcess(), GrantedAccess);
|
||||
}
|
||||
|
||||
static BOOLEAN STDCALL
|
||||
|
|
Loading…
Reference in a new issue