/*
* PROJECT:         ReactOS Kernel
* LICENSE:         GPL - See COPYING in the top level directory
* FILE:            ntoskrnl/include/ob.h
* PURPOSE:         Internal header for the Object Manager
* PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
*/

//
// Define this if you want debugging support
//
#define _OB_DEBUG_                                      0x01

//
// These define the Debug Masks Supported
//
#define OB_HANDLE_DEBUG                                 0x01
#define OB_NAMESPACE_DEBUG                              0x02
#define OB_SECURITY_DEBUG                               0x04
#define OB_REFERENCE_DEBUG                              0x08
#define OB_CALLBACK_DEBUG                               0x10

//
// Debug/Tracing support
//
#if _OB_DEBUG_
#ifdef NEW_DEBUG_SYSTEM_IMPLEMENTED // enable when Debug Filters are implemented
#define OBTRACE DbgPrintEx
#else
#define OBTRACE(x, ...)                                 \
    if (x & ObpTraceLevel) DbgPrint(__VA_ARGS__)
#endif
#else
#define OBTRACE(x, ...) DPRINT(__VA_ARGS__)
#endif

//
// Mask to detect GENERIC_XXX access masks being used
//
#define GENERIC_ACCESS                                  \
    (GENERIC_READ    |                                  \
     GENERIC_WRITE   |                                  \
     GENERIC_EXECUTE |                                  \
     GENERIC_ALL)

//
// Handle Bit Flags
//
#define OBJ_PROTECT_CLOSE                               0x01
//#define OBJ_INHERIT                                   0x02
#define OBJ_AUDIT_OBJECT_CLOSE                          0x04
#define OBJ_HANDLE_ATTRIBUTES                           (OBJ_PROTECT_CLOSE |\
                                                         OBJ_INHERIT |      \
                                                         OBJ_AUDIT_OBJECT_CLOSE)

//
// Identifies a Kernel Handle
//
#define KERNEL_HANDLE_FLAG                              \
    (1 << ((sizeof(HANDLE) * 8) - 1))
#define ObIsKernelHandle(Handle, ProcessorMode)         \
    (((ULONG_PTR)(Handle) & KERNEL_HANDLE_FLAG) &&      \
    ((ProcessorMode) == KernelMode))

//
// Converts to and from a Kernel Handle to a normal handle
//
#define ObKernelHandleToHandle(Handle)                  \
    (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
#define ObMarkHandleAsKernelHandle(Handle)              \
    (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)

//
// Returns the number of handles in a handle table
//
#define ObpGetHandleCountByHandleTable(HandleTable)     \
    ((PHANDLE_TABLE)HandleTable)->HandleCount

//
// Converts from an EXHANDLE object to a POBJECT_HEADER
//
#define ObpGetHandleObject(x)                           \
    ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES))

//
// Context Structures for Ex*Handle Callbacks
//
typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
{
    KPROCESSOR_MODE PreviousMode;
    OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information;
} OBP_SET_HANDLE_ATTRIBUTES_CONTEXT, *POBP_SET_HANDLE_ATTRIBUTES_CONTEXT;
typedef struct _OBP_CLOSE_HANDLE_CONTEXT
{
    PHANDLE_TABLE HandleTable;
    KPROCESSOR_MODE AccessMode;
} OBP_CLOSE_HANDLE_CONTEXT, *POBP_CLOSE_HANDLE_CONTEXT;
typedef struct _OBP_FIND_HANDLE_DATA
{
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    POBJECT_HANDLE_INFORMATION HandleInformation;
} OBP_FIND_HANDLE_DATA, *POBP_FIND_HANDLE_DATA;

//
// Structure for quick-compare of a DOS Device path
//
typedef union
{
    WCHAR Name[sizeof(ULARGE_INTEGER) / sizeof(WCHAR)];
    ULARGE_INTEGER Alignment;
} ALIGNEDNAME;

//
// Private Temporary Buffer for Lookup Routines
//
#define TAG_OB_TEMP_STORAGE TAG('O', 'b', 'S', 't')
typedef struct _OB_TEMP_BUFFER
{
    ACCESS_STATE LocalAccessState;
    OBJECT_CREATE_INFORMATION ObjectCreateInfo;
    OBP_LOOKUP_CONTEXT LookupContext;
    AUX_DATA AuxData;
} OB_TEMP_BUFFER, *POB_TEMP_BUFFER;

//
// Directory Namespace Functions
//
BOOLEAN
NTAPI
ObpDeleteEntryDirectory(
    IN POBP_LOOKUP_CONTEXT Context
);

BOOLEAN
NTAPI
ObpInsertEntryDirectory(
    IN POBJECT_DIRECTORY Parent,
    IN POBP_LOOKUP_CONTEXT Context,
    IN POBJECT_HEADER ObjectHeader
);

PVOID
NTAPI
ObpLookupEntryDirectory(
    IN POBJECT_DIRECTORY Directory,
    IN PUNICODE_STRING Name,
    IN ULONG Attributes,
    IN UCHAR SearchShadow,
    IN POBP_LOOKUP_CONTEXT Context
);

//
// Symbolic Link Functions
//
VOID
NTAPI
ObpDeleteSymbolicLink(
    IN PVOID ObjectBody
);

NTSTATUS
NTAPI
ObpParseSymbolicLink(
    IN PVOID ParsedObject,
    IN PVOID ObjectType,
    IN OUT PACCESS_STATE AccessState,
    IN KPROCESSOR_MODE AccessMode,
    IN ULONG Attributes,
    IN OUT PUNICODE_STRING FullPath,
    IN OUT PUNICODE_STRING RemainingName,
    IN OUT PVOID Context OPTIONAL,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
    OUT PVOID *NextObject
);

VOID
NTAPI
ObpCreateSymbolicLinkName(
    IN POBJECT_SYMBOLIC_LINK SymbolicLink
);

VOID
NTAPI
ObpDeleteSymbolicLinkName(
    IN POBJECT_SYMBOLIC_LINK SymbolicLink
);

//
// Process/Handle Table Init/Rundown
//
NTSTATUS
NTAPI
ObInitProcess(
    IN PEPROCESS Parent OPTIONAL,
    IN PEPROCESS Process
);

PHANDLE_TABLE
NTAPI
ObReferenceProcessHandleTable(
    IN PEPROCESS Process
);

VOID
NTAPI
ObDereferenceProcessHandleTable(
    IN PEPROCESS Process
);

VOID
NTAPI
ObKillProcess(
    IN PEPROCESS Process
);

//
// Object Lookup Functions
//
NTSTATUS
NTAPI
ObpLookupObjectName(
    IN HANDLE RootHandle,
    IN PUNICODE_STRING ObjectName,
    IN ULONG Attributes,
    IN POBJECT_TYPE ObjectType,
    IN KPROCESSOR_MODE AccessMode,
    IN OUT PVOID ParseContext,
    IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
    IN PVOID InsertObject,
    IN PACCESS_STATE AccessState,
    IN POBP_LOOKUP_CONTEXT LookupContext,
    OUT PVOID *FoundObject
);

//
// Object Attribute Functions
//
BOOLEAN
NTAPI
ObpSetHandleAttributes(
    IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry,
    IN ULONG_PTR Context
);

VOID
NTAPI
ObQueryDeviceMapInformation(
    IN PEPROCESS Process,
    OUT PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo
);

//
// Object Lifetime Functions
//
VOID
NTAPI
ObpDeleteObject(
    IN PVOID Object,
    IN BOOLEAN CalledFromWorkerThread
);

LONG
FASTCALL
ObDereferenceObjectEx(
    IN PVOID Object,
    IN LONG Count
);

LONG
FASTCALL
ObReferenceObjectEx(
    IN PVOID Object,
    IN LONG Count
);

BOOLEAN
FASTCALL
ObReferenceObjectSafe(
    IN PVOID Object
);

VOID
NTAPI
ObpReapObject(
    IN PVOID Unused
);

VOID
FASTCALL
ObpSetPermanentObject(
    IN PVOID ObjectBody,
    IN BOOLEAN Permanent
);

VOID
NTAPI
ObpDeleteNameCheck(
    IN PVOID Object
);

VOID
NTAPI
ObClearProcessHandleTable(
    IN PEPROCESS Process
);

NTSTATUS
NTAPI
ObDuplicateObject(
    IN PEPROCESS SourceProcess,
    IN HANDLE SourceHandle,
    IN PEPROCESS TargetProcess OPTIONAL,
    IN PHANDLE TargetHandle OPTIONAL,
    IN ACCESS_MASK DesiredAccess,
    IN ULONG HandleAttributes,
    IN ULONG Options,
    IN KPROCESSOR_MODE PreviousMode
);

VOID
NTAPI
ObFreeObjectCreateInfoBuffer(
    IN POBJECT_CREATE_INFORMATION ObjectCreateInfo
);

VOID
NTAPI
ObpFreeObjectNameBuffer(
    IN PUNICODE_STRING Name
);

//
// DOS Devices Functions
//
VOID
NTAPI
ObDereferenceDeviceMap(
    IN PEPROCESS Process
);

VOID
FASTCALL
ObfDereferenceDeviceMap(
    IN PVOID DeviceMap
);

VOID
NTAPI
ObInheritDeviceMap(
    IN PEPROCESS Parent,
    IN PEPROCESS Process
);

NTSTATUS
NTAPI
ObpCreateDosDevicesDirectory(
    VOID
);

//
// Security descriptor cache functions
//
NTSTATUS
NTAPI
ObpInitSdCache(
    VOID
);

NTSTATUS
NTAPI
ObpAddSecurityDescriptor(
    IN PSECURITY_DESCRIPTOR SourceSD,
    OUT PSECURITY_DESCRIPTOR *DestinationSD
);

NTSTATUS
NTAPI
ObpRemoveSecurityDescriptor(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor
);

PSECURITY_DESCRIPTOR
NTAPI
ObpReferenceCachedSecurityDescriptor(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor
);

VOID
NTAPI
ObpDereferenceCachedSecurityDescriptor(
    IN PSECURITY_DESCRIPTOR SecurityDescriptor
);

//
// Object Security Routines
//
BOOLEAN
NTAPI
ObCheckObjectAccess(
    IN PVOID Object,
    IN OUT PACCESS_STATE AccessState,
    IN BOOLEAN LockHeld,
    IN KPROCESSOR_MODE AccessMode,
    OUT PNTSTATUS ReturnedStatus
);

BOOLEAN
NTAPI
ObCheckCreateObjectAccess(
    IN PVOID Object,
    IN ACCESS_MASK CreateAccess,
    IN PACCESS_STATE AccessState,
    IN PUNICODE_STRING ComponentName,
    IN BOOLEAN LockHeld,
    IN KPROCESSOR_MODE AccessMode,
    OUT PNTSTATUS AccessStatus
);

BOOLEAN
NTAPI
ObpCheckTraverseAccess(
    IN PVOID Object,
    IN ACCESS_MASK TraverseAccess,
    IN PACCESS_STATE AccessState OPTIONAL,
    IN BOOLEAN LockHeld,
    IN KPROCESSOR_MODE AccessMode,
    OUT PNTSTATUS AccessStatus
);

BOOLEAN
NTAPI
ObpCheckObjectReference(
    IN PVOID Object,
    IN OUT PACCESS_STATE AccessState,
    IN BOOLEAN LockHeld,
    IN KPROCESSOR_MODE AccessMode,
    OUT PNTSTATUS AccessStatus
);

//
// Executive Fast Referencing Functions
//
VOID
FASTCALL
ObInitializeFastReference(
    IN PEX_FAST_REF FastRef,
    IN PVOID Object
);

PVOID
FASTCALL
ObFastReplaceObject(
    IN PEX_FAST_REF FastRef,
    IN PVOID Object
);

PVOID
FASTCALL
ObFastReferenceObject(
    IN PEX_FAST_REF FastRef
);

PVOID
FASTCALL
ObFastReferenceObjectLocked(
    IN PEX_FAST_REF FastRef
);

VOID
FASTCALL
ObFastDereferenceObject(
    IN PEX_FAST_REF FastRef,
    IN PVOID Object
);

//
// Object Create and Object Name Capture Functions
//
NTSTATUS
NTAPI
ObpCaptureObjectName(
    IN PUNICODE_STRING CapturedName,
    IN PUNICODE_STRING ObjectName,
    IN KPROCESSOR_MODE AccessMode,
    IN BOOLEAN AllocateFromLookaside
);

NTSTATUS
NTAPI
ObpCaptureObjectAttributes(
    IN POBJECT_ATTRIBUTES ObjectAttributes,
    IN KPROCESSOR_MODE AccessMode,
    IN BOOLEAN AllocateFromLookaside,
    IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
    OUT PUNICODE_STRING ObjectName
);

//
// Global data inside the Object Manager
//
extern ULONG ObpTraceLevel;
extern KEVENT ObpDefaultObject;
extern POBJECT_TYPE ObpTypeObjectType;
extern POBJECT_TYPE ObSymbolicLinkType;
extern POBJECT_TYPE ObpTypeObjectType;
extern POBJECT_DIRECTORY ObpRootDirectoryObject;
extern POBJECT_DIRECTORY ObpTypeDirectoryObject;
extern PHANDLE_TABLE ObpKernelHandleTable;
extern WORK_QUEUE_ITEM ObpReaperWorkItem;
extern volatile PVOID ObpReaperList;
extern NPAGED_LOOKASIDE_LIST ObpNmLookasideList, ObpCiLookasideList;
extern BOOLEAN IoCountOperations;
extern ALIGNEDNAME ObpDosDevicesShortNamePrefix;
extern ALIGNEDNAME ObpDosDevicesShortNameRoot;
extern UNICODE_STRING ObpDosDevicesShortName;

//
// Inlined Functions
//
#include "ob_x.h"
