mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
- [FORMATTING]:
- Get rid of ObpGetHandleCountByHandleTable and ObpGetNextHandleByProcessCount. - Add some function comment headers. - Move ObMakeTemporaryObject, NtMakeTemporaryObject, NtMakePermanentObject to oblife.c - Move ObpDeleteNameCheck to obname.c svn path=/trunk/; revision=22285
This commit is contained in:
parent
1f896561d9
commit
1891e7787c
4 changed files with 274 additions and 266 deletions
|
@ -34,6 +34,8 @@ typedef struct _OBP_CLOSE_HANDLE_CONTEXT
|
|||
(HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
|
||||
#define ObMarkHandleAsKernelHandle(Handle) \
|
||||
(HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
|
||||
#define ObpGetHandleCountByHandleTable(HandleTable) \
|
||||
((PHANDLE_TABLE)HandleTable)->HandleCount
|
||||
|
||||
extern KEVENT ObpDefaultObject;
|
||||
extern POBJECT_TYPE ObpTypeObjectType;
|
||||
|
@ -131,10 +133,6 @@ ObDuplicateObject(
|
|||
ULONG Options
|
||||
);
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
ObpGetHandleCountByHandleTable(PHANDLE_TABLE HandleTable);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ObQueryDeviceMapInformation(
|
||||
|
|
|
@ -25,170 +25,8 @@ PHANDLE_TABLE ObpKernelHandleTable = NULL;
|
|||
#define OBTRACE DPRINT
|
||||
#endif
|
||||
|
||||
/* 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)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
OBP_LOOKUP_CONTEXT Context;
|
||||
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
|
||||
POBJECT_TYPE ObjectType;
|
||||
|
||||
/* Get object structures */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
||||
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||
ObjectType = ObjectHeader->Type;
|
||||
|
||||
/*
|
||||
* Check if the handle count is 0, if the object is named,
|
||||
* and if the object isn't a permanent object.
|
||||
*/
|
||||
if (!(ObjectHeader->HandleCount) &&
|
||||
(ObjectNameInfo) &&
|
||||
(ObjectNameInfo->Name.Length) &&
|
||||
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
||||
{
|
||||
/* Make sure it's still inserted */
|
||||
Context.Directory = ObjectNameInfo->Directory;
|
||||
Context.DirectoryLocked = TRUE;
|
||||
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
||||
&ObjectNameInfo->Name,
|
||||
0,
|
||||
FALSE,
|
||||
&Context);
|
||||
if (Object)
|
||||
{
|
||||
/* First delete it from the directory */
|
||||
ObpDeleteEntryDirectory(&Context);
|
||||
|
||||
/* Now check if we have a security callback */
|
||||
if (ObjectType->TypeInfo.SecurityRequired)
|
||||
{
|
||||
/* Call it */
|
||||
ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||
DeleteSecurityDescriptor,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&ObjectHeader->
|
||||
SecurityDescriptor,
|
||||
ObjectType->
|
||||
TypeInfo.PoolType,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Free the name */
|
||||
ExFreePool(ObjectNameInfo->Name.Buffer);
|
||||
RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
|
||||
|
||||
/* Clear the current directory and de-reference it */
|
||||
ObDereferenceObject(ObjectNameInfo->Directory);
|
||||
ObDereferenceObject(Object);
|
||||
ObjectNameInfo->Directory = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpSetPermanentObject
|
||||
*
|
||||
* The ObpSetPermanentObject routine makes an sets or clears the permanent
|
||||
* flag of an object, thus making it either permanent or temporary.
|
||||
*
|
||||
* @param ObjectBody
|
||||
* Pointer to the object to make permanent or temporary.
|
||||
*
|
||||
* @param Permanent
|
||||
* Flag specifying which operation to perform.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks If the object is being made temporary, then it will be checked
|
||||
* as a candidate for immediate removal from the namespace.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
ObpSetPermanentObject(IN PVOID ObjectBody,
|
||||
IN BOOLEAN Permanent)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
/* Get the header */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
|
||||
if (Permanent)
|
||||
{
|
||||
/* Set it to permanent */
|
||||
ObjectHeader->Flags |= OB_FLAG_PERMANENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove the flag */
|
||||
ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
|
||||
|
||||
/* Check if we should delete the object now */
|
||||
ObpDeleteNameCheck(ObjectBody);
|
||||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpDecrementHandleCount
|
||||
*
|
||||
|
@ -680,6 +518,22 @@ ObpCreateHandle(IN OB_OPEN_REASON OpenReason,
|
|||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpCloseHandle
|
||||
*
|
||||
* The ObpCloseHandle routine <FILLMEIN>
|
||||
*
|
||||
* @param Handle
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param AccessMode
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return <FILLMEIN>.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObpCloseHandle(IN HANDLE Handle,
|
||||
|
@ -1448,27 +1302,6 @@ ObFindHandleForObject(IN PEPROCESS Process,
|
|||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObMakeTemporaryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The ObMakeTemporaryObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectBody
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
ObMakeTemporaryObject(IN PVOID ObjectBody)
|
||||
{
|
||||
ObpSetPermanentObject (ObjectBody, FALSE);
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObInsertObject
|
||||
* @implemented NT4
|
||||
|
@ -1753,6 +1586,23 @@ ObInsertObject(IN PVOID Object,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObCloseHandle
|
||||
* @implemented NT5.1
|
||||
*
|
||||
* The ObCloseHandle routine <FILLMEIN>
|
||||
*
|
||||
* @param Handle
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @param AccessMode
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return <FILLMEIN>.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObCloseHandle(IN HANDLE Handle,
|
||||
|
@ -1764,6 +1614,20 @@ ObCloseHandle(IN HANDLE Handle,
|
|||
return ObpCloseHandle(Handle, AccessMode);
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtClose
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtClose routine <FILLMEIN>
|
||||
*
|
||||
* @param Handle
|
||||
* <FILLMEIN>.
|
||||
*
|
||||
* @return <FILLMEIN>.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtClose(IN HANDLE Handle)
|
||||
|
@ -1954,83 +1818,4 @@ NtDuplicateObject (IN HANDLE SourceProcessHandle,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtMakeTemporaryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtMakeTemporaryObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectHandle
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return STATUS_SUCCESS or appropriate error value.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMakeTemporaryObject(IN HANDLE ObjectHandle)
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Reference the object for DELETE access */
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
DELETE,
|
||||
NULL,
|
||||
KeGetPreviousMode(),
|
||||
&ObjectBody,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS) return Status;
|
||||
|
||||
/* Set it as temporary and dereference it */
|
||||
ObpSetPermanentObject(ObjectBody, FALSE);
|
||||
ObDereferenceObject(ObjectBody);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtMakePermanentObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtMakePermanentObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectHandle
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return STATUS_SUCCESS or appropriate error value.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMakePermanentObject(IN HANDLE ObjectHandle)
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
PAGED_CODE();
|
||||
|
||||
/* Make sure that the caller has SeCreatePermanentPrivilege */
|
||||
Status = SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
|
||||
PreviousMode);
|
||||
if (!NT_SUCCESS(Status)) return STATUS_PRIVILEGE_NOT_HELD;
|
||||
|
||||
/* Reference the object */
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
0,
|
||||
NULL,
|
||||
PreviousMode,
|
||||
&ObjectBody,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS) return Status;
|
||||
|
||||
/* Set it as permanent and dereference it */
|
||||
ObpSetPermanentObject(ObjectBody, TRUE);
|
||||
ObDereferenceObject(ObjectBody);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/* EOF */
|
||||
|
|
|
@ -180,6 +180,48 @@ ObpReapObject(IN PVOID Parameter)
|
|||
}
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObpSetPermanentObject
|
||||
*
|
||||
* The ObpSetPermanentObject routine makes an sets or clears the permanent
|
||||
* flag of an object, thus making it either permanent or temporary.
|
||||
*
|
||||
* @param ObjectBody
|
||||
* Pointer to the object to make permanent or temporary.
|
||||
*
|
||||
* @param Permanent
|
||||
* Flag specifying which operation to perform.
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks If the object is being made temporary, then it will be checked
|
||||
* as a candidate for immediate removal from the namespace.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
FASTCALL
|
||||
ObpSetPermanentObject(IN PVOID ObjectBody,
|
||||
IN BOOLEAN Permanent)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
|
||||
/* Get the header */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
|
||||
if (Permanent)
|
||||
{
|
||||
/* Set it to permanent */
|
||||
ObjectHeader->Flags |= OB_FLAG_PERMANENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Remove the flag */
|
||||
ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
|
||||
|
||||
/* Check if we should delete the object now */
|
||||
ObpDeleteNameCheck(ObjectBody);
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName,
|
||||
|
@ -762,6 +804,108 @@ ObCreateObjectType(IN PUNICODE_STRING TypeName,
|
|||
return Status;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name ObMakeTemporaryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The ObMakeTemporaryObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectBody
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return None.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
VOID
|
||||
NTAPI
|
||||
ObMakeTemporaryObject(IN PVOID ObjectBody)
|
||||
{
|
||||
/* Call the internal API */
|
||||
ObpSetPermanentObject (ObjectBody, FALSE);
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtMakeTemporaryObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtMakeTemporaryObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectHandle
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return STATUS_SUCCESS or appropriate error value.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMakeTemporaryObject(IN HANDLE ObjectHandle)
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
PAGED_CODE();
|
||||
|
||||
/* Reference the object for DELETE access */
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
DELETE,
|
||||
NULL,
|
||||
KeGetPreviousMode(),
|
||||
&ObjectBody,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS) return Status;
|
||||
|
||||
/* Set it as temporary and dereference it */
|
||||
ObpSetPermanentObject(ObjectBody, FALSE);
|
||||
ObDereferenceObject(ObjectBody);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtMakePermanentObject
|
||||
* @implemented NT4
|
||||
*
|
||||
* The NtMakePermanentObject routine <FILLMEIN>
|
||||
*
|
||||
* @param ObjectHandle
|
||||
* <FILLMEIN>
|
||||
*
|
||||
* @return STATUS_SUCCESS or appropriate error value.
|
||||
*
|
||||
* @remarks None.
|
||||
*
|
||||
*--*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtMakePermanentObject(IN HANDLE ObjectHandle)
|
||||
{
|
||||
PVOID ObjectBody;
|
||||
NTSTATUS Status;
|
||||
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
|
||||
PAGED_CODE();
|
||||
|
||||
/* Make sure that the caller has SeCreatePermanentPrivilege */
|
||||
Status = SeSinglePrivilegeCheck(SeCreatePermanentPrivilege,
|
||||
PreviousMode);
|
||||
if (!NT_SUCCESS(Status)) return STATUS_PRIVILEGE_NOT_HELD;
|
||||
|
||||
/* Reference the object */
|
||||
Status = ObReferenceObjectByHandle(ObjectHandle,
|
||||
0,
|
||||
NULL,
|
||||
PreviousMode,
|
||||
&ObjectBody,
|
||||
NULL);
|
||||
if (Status != STATUS_SUCCESS) return Status;
|
||||
|
||||
/* Set it as permanent and dereference it */
|
||||
ObpSetPermanentObject(ObjectBody, TRUE);
|
||||
ObDereferenceObject(ObjectBody);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/*++
|
||||
* @name NtQueryObject
|
||||
* @implemented NT4
|
||||
|
|
|
@ -20,6 +20,87 @@ POBJECT_DIRECTORY ObpTypeDirectoryObject = NULL;
|
|||
|
||||
/* 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)
|
||||
{
|
||||
POBJECT_HEADER ObjectHeader;
|
||||
OBP_LOOKUP_CONTEXT Context;
|
||||
POBJECT_HEADER_NAME_INFO ObjectNameInfo;
|
||||
POBJECT_TYPE ObjectType;
|
||||
|
||||
/* Get object structures */
|
||||
ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
|
||||
ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
|
||||
ObjectType = ObjectHeader->Type;
|
||||
|
||||
/*
|
||||
* Check if the handle count is 0, if the object is named,
|
||||
* and if the object isn't a permanent object.
|
||||
*/
|
||||
if (!(ObjectHeader->HandleCount) &&
|
||||
(ObjectNameInfo) &&
|
||||
(ObjectNameInfo->Name.Length) &&
|
||||
!(ObjectHeader->Flags & OB_FLAG_PERMANENT))
|
||||
{
|
||||
/* Make sure it's still inserted */
|
||||
Context.Directory = ObjectNameInfo->Directory;
|
||||
Context.DirectoryLocked = TRUE;
|
||||
Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
|
||||
&ObjectNameInfo->Name,
|
||||
0,
|
||||
FALSE,
|
||||
&Context);
|
||||
if (Object)
|
||||
{
|
||||
/* First delete it from the directory */
|
||||
ObpDeleteEntryDirectory(&Context);
|
||||
|
||||
/* Now check if we have a security callback */
|
||||
if (ObjectType->TypeInfo.SecurityRequired)
|
||||
{
|
||||
/* Call it */
|
||||
ObjectType->TypeInfo.SecurityProcedure(Object,
|
||||
DeleteSecurityDescriptor,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
&ObjectHeader->
|
||||
SecurityDescriptor,
|
||||
ObjectType->
|
||||
TypeInfo.PoolType,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/* Free the name */
|
||||
ExFreePool(ObjectNameInfo->Name.Buffer);
|
||||
RtlInitEmptyUnicodeString(&ObjectNameInfo->Name, NULL, 0);
|
||||
|
||||
/* Clear the current directory and de-reference it */
|
||||
ObDereferenceObject(ObjectNameInfo->Directory);
|
||||
ObDereferenceObject(Object);
|
||||
ObjectNameInfo->Directory = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
ObFindObject(IN HANDLE RootHandle,
|
||||
|
|
Loading…
Reference in a new issue