ReactOS 0.4.15-dev-7788-g1ad9096
ob.h File Reference
#include "ob_x.h"
Include dependency graph for ob.h:

Go to the source code of this file.

Classes

struct  _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
 
struct  _OBP_CLOSE_HANDLE_CONTEXT
 
struct  _OBP_FIND_HANDLE_DATA
 
struct  _SECURITY_DESCRIPTOR_HEADER
 
struct  _OB_SD_CACHE_LIST
 
union  ALIGNEDNAME
 
struct  _OB_TEMP_BUFFER
 

Macros

#define _OB_DEBUG_   0x00
 
#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
 
#define OBTRACE(x, fmt, ...)   DPRINT(fmt, ##__VA_ARGS__)
 
#define GENERIC_ACCESS
 
#define OBJ_PROTECT_CLOSE   0x01
 
#define OBJ_AUDIT_OBJECT_CLOSE   0x04
 
#define OBJ_HANDLE_ATTRIBUTES
 
#define ObpAccessProtectCloseBit   0x02000000L
 
#define OBP_SYSTEM_PROCESS_QUOTA   ((PEPROCESS_QUOTA_BLOCK)(ULONG_PTR)1)
 
#define KERNEL_HANDLE_FLAG   0x80000000
 
#define ObpIsKernelHandle(Handle, ProcessorMode)
 
#define ObKernelHandleToHandle(Handle)    (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)
 
#define ObMarkHandleAsKernelHandle(Handle)    (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)
 
#define ObpGetHandleObject(x)    ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES))
 
#define ObpGetHeaderForSd(x)    CONTAINING_RECORD((x), SECURITY_DESCRIPTOR_HEADER, SecurityDescriptor)
 
#define ObpGetHeaderForEntry(x)    CONTAINING_RECORD((x), SECURITY_DESCRIPTOR_HEADER, Link)
 
#define TAG_OB_TEMP_STORAGE   'tSbO'
 

Typedefs

typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXT OBP_SET_HANDLE_ATTRIBUTES_CONTEXT
 
typedef struct _OBP_SET_HANDLE_ATTRIBUTES_CONTEXTPOBP_SET_HANDLE_ATTRIBUTES_CONTEXT
 
typedef struct _OBP_CLOSE_HANDLE_CONTEXT OBP_CLOSE_HANDLE_CONTEXT
 
typedef struct _OBP_CLOSE_HANDLE_CONTEXTPOBP_CLOSE_HANDLE_CONTEXT
 
typedef struct _OBP_FIND_HANDLE_DATA OBP_FIND_HANDLE_DATA
 
typedef struct _OBP_FIND_HANDLE_DATAPOBP_FIND_HANDLE_DATA
 
typedef struct _SECURITY_DESCRIPTOR_HEADER SECURITY_DESCRIPTOR_HEADER
 
typedef struct _SECURITY_DESCRIPTOR_HEADERPSECURITY_DESCRIPTOR_HEADER
 
typedef struct _OB_SD_CACHE_LIST OB_SD_CACHE_LIST
 
typedef struct _OB_SD_CACHE_LISTPOB_SD_CACHE_LIST
 
typedef struct _OB_TEMP_BUFFER OB_TEMP_BUFFER
 
typedef struct _OB_TEMP_BUFFERPOB_TEMP_BUFFER
 

Functions

BOOLEAN NTAPI ObInitSystem (VOID)
 
VOID NTAPI ObShutdownSystem (VOID)
 
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)
 
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)
 
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)
 
NTSTATUS NTAPI ObpLookupObjectName (IN HANDLE RootHandle OPTIONAL, IN OUT PUNICODE_STRING ObjectName, IN ULONG Attributes, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext, IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL, IN PVOID InsertObject OPTIONAL, IN OUT PACCESS_STATE AccessState, OUT POBP_LOOKUP_CONTEXT LookupContext, OUT PVOID *FoundObject)
 
BOOLEAN NTAPI ObpSetHandleAttributes (IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, IN ULONG_PTR Context)
 
NTSTATUS NTAPI ObQueryDeviceMapInformation (_In_opt_ PEPROCESS Process, _Out_ PPROCESS_DEVICEMAP_INFORMATION DeviceMapInfo, _In_ ULONG Flags)
 
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)
 
VOID NTAPI ObpDeleteObjectType (IN PVOID Object)
 
NTSTATUS NTAPI ObReferenceFileObjectForWrite (IN HANDLE Handle, IN KPROCESSOR_MODE AccessMode, OUT PFILE_OBJECT *FileObject, OUT POBJECT_HANDLE_INFORMATION HandleInformation)
 
NTSTATUS NTAPI ObSetDeviceMap (IN PEPROCESS Process, IN HANDLE DirectoryHandle)
 
NTSTATUS NTAPI ObSetDirectoryDeviceMap (OUT PDEVICE_MAP *DeviceMap, IN HANDLE DirectoryHandle)
 
VOID NTAPI ObDereferenceDeviceMap (IN PEPROCESS Process)
 
VOID FASTCALL ObfDereferenceDeviceMap (IN PDEVICE_MAP DeviceMap)
 
VOID NTAPI ObInheritDeviceMap (IN PEPROCESS Parent, IN PEPROCESS Process)
 
NTSTATUS NTAPI ObpCreateDosDevicesDirectory (VOID)
 
ULONG NTAPI ObIsLUIDDeviceMapsEnabled (VOID)
 
PDEVICE_MAP NTAPI ObpReferenceDeviceMap (VOID)
 
NTSTATUS NTAPI ObpInitSdCache (VOID)
 
PSECURITY_DESCRIPTOR NTAPI ObpReferenceSecurityDescriptor (IN POBJECT_HEADER ObjectHeader)
 
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)
 
NTSTATUS NTAPI ObAssignObjectSecurityDescriptor (IN PVOID Object, IN PSECURITY_DESCRIPTOR SecurityDescriptor OPTIONAL, IN POOL_TYPE PoolType)
 
NTSTATUS NTAPI ObDeassignSecurity (IN OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
 
NTSTATUS NTAPI ObQuerySecurityDescriptorInfo (IN PVOID Object, IN PSECURITY_INFORMATION SecurityInformation, OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PULONG Length, IN PSECURITY_DESCRIPTOR *OutputSecurityDescriptor)
 
NTSTATUS NTAPI ObSetSecurityDescriptorInfo (IN PVOID Object, IN PSECURITY_INFORMATION SecurityInformation, IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor, IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, IN POOL_TYPE PoolType, IN PGENERIC_MAPPING GenericMapping)
 
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)
 
NTSTATUS NTAPI ObpCaptureObjectName (IN PUNICODE_STRING CapturedName, IN PUNICODE_STRING ObjectName, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN AllocateFromLookaside)
 
NTSTATUS NTAPI ObpCaptureObjectCreateInformation (IN POBJECT_ATTRIBUTES ObjectAttributes, IN KPROCESSOR_MODE AccessMode, IN KPROCESSOR_MODE CreatorMode, IN BOOLEAN AllocateFromLookaside, IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, OUT PUNICODE_STRING ObjectName)
 
ULONG NTAPI ObGetProcessHandleCount (IN PEPROCESS Process)
 

Variables

ULONG ObpTraceLevel
 
KEVENT ObpDefaultObject
 
KGUARDED_MUTEX ObpDeviceMapLock
 
POBJECT_TYPE ObpTypeObjectType
 
POBJECT_TYPE ObpDirectoryObjectType
 
POBJECT_TYPE ObpSymbolicLinkObjectType
 
POBJECT_DIRECTORY ObpRootDirectoryObject
 
POBJECT_DIRECTORY ObpTypeDirectoryObject
 
PHANDLE_TABLE ObpKernelHandleTable
 
WORK_QUEUE_ITEM ObpReaperWorkItem
 
volatile PVOID ObpReaperList
 
GENERAL_LOOKASIDE ObpNameBufferLookasideList
 
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
 
BOOLEAN IoCountOperations
 
ALIGNEDNAME ObpDosDevicesShortNamePrefix
 
ALIGNEDNAME ObpDosDevicesShortNameRoot
 
UNICODE_STRING ObpDosDevicesShortName
 
WCHAR ObpUnsecureGlobalNamesBuffer [128]
 
ULONG ObpUnsecureGlobalNamesLength
 
ULONG ObpObjectSecurityMode
 
ULONG ObpProtectionMode
 
ULONG ObpLUIDDeviceMapsDisabled
 
ULONG ObpLUIDDeviceMapsEnabled
 

Macro Definition Documentation

◆ _OB_DEBUG_

#define _OB_DEBUG_   0x00

Definition at line 12 of file ob.h.

◆ GENERIC_ACCESS

#define GENERIC_ACCESS
Value:
#define GENERIC_READ
Definition: compat.h:135
#define GENERIC_ALL
Definition: nt_native.h:92
#define GENERIC_WRITE
Definition: nt_native.h:90
#define GENERIC_EXECUTE
Definition: nt_native.h:91

Definition at line 40 of file ob.h.

◆ KERNEL_HANDLE_FLAG

#define KERNEL_HANDLE_FLAG   0x80000000

Definition at line 72 of file ob.h.

◆ OB_CALLBACK_DEBUG

#define OB_CALLBACK_DEBUG   0x10

Definition at line 21 of file ob.h.

◆ OB_HANDLE_DEBUG

#define OB_HANDLE_DEBUG   0x01

Definition at line 17 of file ob.h.

◆ OB_NAMESPACE_DEBUG

#define OB_NAMESPACE_DEBUG   0x02

Definition at line 18 of file ob.h.

◆ OB_REFERENCE_DEBUG

#define OB_REFERENCE_DEBUG   0x08

Definition at line 20 of file ob.h.

◆ OB_SECURITY_DEBUG

#define OB_SECURITY_DEBUG   0x04

Definition at line 19 of file ob.h.

◆ OBJ_AUDIT_OBJECT_CLOSE

#define OBJ_AUDIT_OBJECT_CLOSE   0x04

Definition at line 51 of file ob.h.

◆ OBJ_HANDLE_ATTRIBUTES

#define OBJ_HANDLE_ATTRIBUTES
Value:
#define OBJ_INHERIT
Definition: winternl.h:225
#define OBJ_AUDIT_OBJECT_CLOSE
Definition: ob.h:51
#define OBJ_PROTECT_CLOSE
Definition: ob.h:49

Definition at line 52 of file ob.h.

◆ OBJ_PROTECT_CLOSE

#define OBJ_PROTECT_CLOSE   0x01

Definition at line 49 of file ob.h.

◆ ObKernelHandleToHandle

#define ObKernelHandleToHandle (   Handle)     (HANDLE)((ULONG_PTR)(Handle) & ~KERNEL_HANDLE_FLAG)

Definition at line 83 of file ob.h.

◆ ObMarkHandleAsKernelHandle

#define ObMarkHandleAsKernelHandle (   Handle)     (HANDLE)((ULONG_PTR)(Handle) | KERNEL_HANDLE_FLAG)

Definition at line 85 of file ob.h.

◆ OBP_SYSTEM_PROCESS_QUOTA

#define OBP_SYSTEM_PROCESS_QUOTA   ((PEPROCESS_QUOTA_BLOCK)(ULONG_PTR)1)

Definition at line 64 of file ob.h.

◆ ObpAccessProtectCloseBit

#define ObpAccessProtectCloseBit   0x02000000L

Definition at line 59 of file ob.h.

◆ ObpGetHandleObject

#define ObpGetHandleObject (   x)     ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES))

Definition at line 91 of file ob.h.

◆ ObpGetHeaderForEntry

#define ObpGetHeaderForEntry (   x)     CONTAINING_RECORD((x), SECURITY_DESCRIPTOR_HEADER, Link)

Definition at line 103 of file ob.h.

◆ ObpGetHeaderForSd

Definition at line 97 of file ob.h.

◆ ObpIsKernelHandle

#define ObpIsKernelHandle (   Handle,
  ProcessorMode 
)
Value:
((ProcessorMode) == KernelMode) && \
((Handle) != NtCurrentProcess()) && \
#define ULONG_PTR
Definition: config.h:101
ULONG Handle
Definition: gdb_input.c:15
#define KernelMode
Definition: asm.h:34
#define NtCurrentProcess()
Definition: nt_native.h:1657
#define KERNEL_HANDLE_FLAG
Definition: ob.h:72
#define NtCurrentThread()

Definition at line 74 of file ob.h.

◆ OBTRACE

#define OBTRACE (   x,
  fmt,
  ... 
)    DPRINT(fmt, ##__VA_ARGS__)

Definition at line 34 of file ob.h.

◆ TAG_OB_TEMP_STORAGE

#define TAG_OB_TEMP_STORAGE   'tSbO'

Definition at line 160 of file ob.h.

Typedef Documentation

◆ OB_SD_CACHE_LIST

◆ OB_TEMP_BUFFER

◆ OBP_CLOSE_HANDLE_CONTEXT

◆ OBP_FIND_HANDLE_DATA

◆ OBP_SET_HANDLE_ATTRIBUTES_CONTEXT

◆ POB_SD_CACHE_LIST

◆ POB_TEMP_BUFFER

◆ POBP_CLOSE_HANDLE_CONTEXT

◆ POBP_FIND_HANDLE_DATA

◆ POBP_SET_HANDLE_ATTRIBUTES_CONTEXT

◆ PSECURITY_DESCRIPTOR_HEADER

◆ SECURITY_DESCRIPTOR_HEADER

Function Documentation

◆ ObAssignObjectSecurityDescriptor()

NTSTATUS NTAPI ObAssignObjectSecurityDescriptor ( IN PVOID  Object,
IN PSECURITY_DESCRIPTOR SecurityDescriptor  OPTIONAL,
IN POOL_TYPE  PoolType 
)

Definition at line 20 of file obsecure.c.

23{
24 POBJECT_HEADER ObjectHeader;
27 PEX_FAST_REF FastRef;
28 PAGED_CODE();
29
30 /* Get the object header */
31 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
32 FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor;
34 {
35 /* Nothing to assign */
37 return STATUS_SUCCESS;
38 }
39
40 /* Add it to our internal cache */
42 &NewSd,
43 MAX_FAST_REFS + 1);
44 if (NT_SUCCESS(Status))
45 {
46 /* Free the old copy */
48
49 /* Set the new pointer */
50 ASSERT(NewSd);
51 ExInitializeFastReference(FastRef, NewSd);
52 }
53
54 /* Return status */
55 return Status;
56}
#define PAGED_CODE()
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_FAST_REFS
Definition: ex.h:133
FORCEINLINE VOID ExInitializeFastReference(OUT PEX_FAST_REF FastRef, IN OPTIONAL PVOID Object)
Definition: ex.h:596
Status
Definition: gdiplustypes.h:25
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
struct _EX_FAST_REF * PEX_FAST_REF
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
NTSTATUS NTAPI ObLogSecurityDescriptor(IN PSECURITY_DESCRIPTOR InputSecurityDescriptor, OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor, IN ULONG RefBias)
Definition: obsdcach.c:364
#define STATUS_SUCCESS
Definition: shellext.h:65
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:503
#define TAG_SD
Definition: tag.h:153
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_In_ USHORT _In_ ULONG _In_ PSOCKADDR _In_ PSOCKADDR _Reserved_ ULONG _In_opt_ PVOID _In_opt_ const WSK_CLIENT_CONNECTION_DISPATCH _In_opt_ PEPROCESS _In_opt_ PETHREAD _In_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: wsk.h:191

Referenced by SeDefaultObjectMethod(), and WmipSecurityMethod().

◆ ObCheckCreateObjectAccess()

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 
)

Definition at line 203 of file obsecure.c.

210{
211 POBJECT_HEADER ObjectHeader;
214 BOOLEAN SdAllocated;
219 PAGED_CODE();
220
221 /* Get the header and type */
222 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
223 ObjectType = ObjectHeader->Type;
224
225 /* Get the security descriptor */
227 if (!NT_SUCCESS(Status))
228 {
229 /* We failed */
231 return FALSE;
232 }
233
234 /* Lock the security context */
235 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
236
237 /* Check if we have an SD */
239 {
240 /* Now do the entire access check */
242 &AccessState->SubjectSecurityContext,
243 TRUE,
244 CreateAccess,
245 0,
246 &Privileges,
247 &ObjectType->TypeInfo.GenericMapping,
251 if (Privileges)
252 {
253 /* We got privileges, append them to the access state and free them */
256 }
257 }
258
259 /* We're done, unlock the context and release security */
260 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
262 return Result;
263}
unsigned char BOOLEAN
BOOLEAN NTAPI SeAccessCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext, _In_ BOOLEAN SubjectContextLocked, _In_ ACCESS_MASK DesiredAccess, _In_ ACCESS_MASK PreviouslyGrantedAccess, _Out_ PPRIVILEGE_SET *Privileges, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode, _Out_ PACCESS_MASK GrantedAccess, _Out_ PNTSTATUS AccessStatus)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:1994
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ObjectType
Definition: metafile.c:81
ULONG ACCESS_MASK
Definition: nt_native.h:40
VOID NTAPI SeFreePrivileges(_In_ PPRIVILEGE_SET Privileges)
Frees a set of privileges.
Definition: priv.c:669
NTSTATUS NTAPI SeAppendPrivileges(_Inout_ PACCESS_STATE AccessState, _In_ PPRIVILEGE_SET Privileges)
Appends additional privileges.
Definition: priv.c:588
NTSTATUS NTAPI ObGetObjectSecurity(IN PVOID Object, OUT PSECURITY_DESCRIPTOR *SecurityDescriptor, OUT PBOOLEAN MemoryAllocated)
Definition: obsecure.c:611
VOID NTAPI ObReleaseObjectSecurity(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN BOOLEAN MemoryAllocated)
Definition: obsecure.c:709
POBJECT_TYPE Type
Definition: obtypes.h:493
VOID NTAPI SeLockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Locks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:107
VOID NTAPI SeUnlockSubjectContext(_In_ PSECURITY_SUBJECT_CONTEXT SubjectContext)
Unlocks both the referenced primary and client access tokens of a security subject context.
Definition: subject.c:138
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK _Out_ PNTSTATUS AccessStatus
Definition: sefuncs.h:21
_In_opt_ PVOID _In_opt_ PUNICODE_STRING _In_ PSECURITY_DESCRIPTOR _In_ PACCESS_STATE AccessState
Definition: sefuncs.h:417
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET _In_ PGENERIC_MAPPING _In_ KPROCESSOR_MODE _Out_ PACCESS_MASK GrantedAccess
Definition: sefuncs.h:20

Referenced by ObpLookupObjectName().

◆ ObCheckObjectAccess()

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

Definition at line 441 of file obsecure.c.

446{
447 POBJECT_HEADER ObjectHeader;
450 BOOLEAN SdAllocated;
455 PAGED_CODE();
456
457 /* Get the object header and type */
458 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
459 ObjectType = ObjectHeader->Type;
460
461 /* Get security information */
463 if (!NT_SUCCESS(Status))
464 {
465 /* Return failure */
466 *ReturnedStatus = Status;
467 return FALSE;
468 }
469 else if (!SecurityDescriptor)
470 {
471 /* Otherwise, if we don't actually have an SD, return success */
472 *ReturnedStatus = Status;
473 return TRUE;
474 }
475
476 /* Lock the security context */
477 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
478
479 /* Now do the entire access check */
481 &AccessState->SubjectSecurityContext,
482 TRUE,
483 AccessState->RemainingDesiredAccess,
484 AccessState->PreviouslyGrantedAccess,
485 &Privileges,
486 &ObjectType->TypeInfo.GenericMapping,
489 ReturnedStatus);
490 if (Privileges)
491 {
492 /* We got privileges, append them to the access state and free them */
495 }
496
497 /* Check if access was granted */
498 if (Result)
499 {
500 /* Update the access state */
501 AccessState->RemainingDesiredAccess &= ~(GrantedAccess |
503 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
504 }
505
506 /* Do audit alarm */
508 Object,
509 NULL,
512 FALSE,
513 Result,
515 &AccessState->GenerateOnClose);
516
517 /* We're done, unlock the context and release security */
518 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
520 return Result;
521}
#define MAXIMUM_ALLOWED
Definition: nt_native.h:83
VOID NTAPI SeOpenObjectAuditAlarm(_In_ PUNICODE_STRING ObjectTypeName, _In_opt_ PVOID Object, _In_opt_ PUNICODE_STRING AbsoluteObjectName, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PACCESS_STATE AccessState, _In_ BOOLEAN ObjectCreated, _In_ BOOLEAN AccessGranted, _In_ KPROCESSOR_MODE AccessMode, _Out_ PBOOLEAN GenerateOnClose)
Creates an audit with alarm notification of an object that is being opened.
Definition: audit.c:1213

Referenced by CmpDoOpen(), and ObpIncrementHandleCount().

◆ ObClearProcessHandleTable()

VOID NTAPI ObClearProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 2027 of file obhandle.c.

2028{
2032 BOOLEAN AttachedToProcess = FALSE;
2033
2034 ASSERT(Process);
2035
2036 /* Ensure the handle table doesn't go away while we use it */
2038 if (!HandleTable) return;
2039
2040 /* Attach to the current process if needed */
2042 {
2044 AttachedToProcess = TRUE;
2045 }
2046
2047 /* Enter a critical region */
2049
2050 /* Fill out the context */
2051 Context.AccessMode = UserMode;
2052 Context.HandleTable = HandleTable;
2053
2054 /* Sweep the handle table to close all handles */
2057 &Context);
2058
2059 /* Leave the critical region */
2061
2062 /* Detach if needed */
2063 if (AttachedToProcess)
2065
2066 /* Let the handle table go */
2068}
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
static XMS_HANDLE HandleTable[XMS_MAX_HANDLES]
Definition: himem.c:83
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define UserMode
Definition: asm.h:35
VOID NTAPI ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context)
Definition: handle.c:1232
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
VOID NTAPI ObDereferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:48
BOOLEAN NTAPI ObpCloseHandleCallback(IN PHANDLE_TABLE_ENTRY HandleTableEntry, IN HANDLE Handle, IN PVOID Context)
Definition: obhandle.c:1924
PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable(IN PEPROCESS Process)
Definition: obhandle.c:26
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
KAPC_STATE
Definition: ketypes.h:1409
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by NtTerminateProcess(), and PspTerminateProcess().

◆ ObDeassignSecurity()

NTSTATUS NTAPI ObDeassignSecurity ( IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor)

Definition at line 60 of file obsecure.c.

61{
62 EX_FAST_REF FastRef;
64 PSECURITY_DESCRIPTOR OldSecurityDescriptor;
65
66 /* Get the fast reference and capture it */
68
69 /* Don't free again later */
71
72 /* Get the descriptor and reference count */
73 OldSecurityDescriptor = ExGetObjectFastReference(FastRef);
75
76 /* Dereference the descriptor */
77 ObDereferenceSecurityDescriptor(OldSecurityDescriptor, Count + 1);
78
79 /* All done */
80 return STATUS_SUCCESS;
81}
FORCEINLINE ULONG ExGetCountFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:588
FORCEINLINE PVOID ExGetObjectFastReference(IN EX_FAST_REF FastRef)
Definition: ex.h:580
int Count
Definition: noreturn.cpp:7
VOID NTAPI ObDereferenceSecurityDescriptor(IN PSECURITY_DESCRIPTOR SecurityDescriptor, IN ULONG Count)
Definition: obsdcach.c:287
uint32_t ULONG
Definition: typedefs.h:59

Referenced by SeDefaultObjectMethod(), and WmipSecurityMethod().

◆ ObDereferenceDeviceMap()

VOID NTAPI ObDereferenceDeviceMap ( IN PEPROCESS  Process)

Definition at line 456 of file devicemap.c.

457{
458 PDEVICE_MAP DeviceMap;
459
460 DPRINT("ObDereferenceDeviceMap()\n");
461
462 /* Get the pointer to this process devicemap and reset it
463 holding the device map lock */
465 DeviceMap = Process->DeviceMap;
466 Process->DeviceMap = NULL;
468
469 /* Continue only if there is a device map */
470 if (DeviceMap != NULL)
471 ObfDereferenceDeviceMap(DeviceMap);
472}
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
KGUARDED_MUTEX ObpDeviceMapLock
Definition: oblife.c:24
#define DPRINT
Definition: sndvol32.h:71

Referenced by PspDeleteProcess(), and PspSetPrimaryToken().

◆ ObDereferenceObjectEx()

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

Definition at line 88 of file obref.c.

90{
92 LONG_PTR NewCount;
93
94 /* Extract the object header */
96
97 /* Check whether the object can now be deleted. */
98 NewCount = InterlockedExchangeAddSizeT(&Header->PointerCount, -Count) - Count;
99 if (!NewCount) ObpDeferObjectDeletion(Header);
100
101 /* Return the current count */
102 return NewCount;
103}
Definition: Header.h:9
#define InterlockedExchangeAddSizeT(a, b)
Definition: interlocked.h:196
__int3264 LONG_PTR
Definition: mstsclib_h.h:276
VOID NTAPI ObpDeferObjectDeletion(IN POBJECT_HEADER Header)
Definition: obref.c:53

Referenced by ExpTimerApcKernelRoutine(), ExTimerRundown(), NtCancelTimer(), NtSetTimer(), ObFastReferenceObject(), ObFastReplaceObject(), and PspCreateThread().

◆ ObDereferenceProcessHandleTable()

VOID NTAPI ObDereferenceProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 48 of file obhandle.c.

49{
50 /* Release the process lock */
51 ExReleaseRundownProtection(&Process->RundownProtect);
52}
#define ExReleaseRundownProtection
Definition: ex.h:136

Referenced by ObClearProcessHandleTable(), ObDuplicateObject(), ObFindHandleForObject(), ObGetProcessHandleCount(), and ObInitProcess().

◆ ObDuplicateObject()

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 
)

Definition at line 2204 of file obhandle.c.

2212{
2213 HANDLE_TABLE_ENTRY NewHandleEntry;
2214 BOOLEAN AttachedToProcess = FALSE;
2215 PVOID SourceObject;
2216 POBJECT_HEADER ObjectHeader;
2218 HANDLE NewHandle;
2221 ACCESS_MASK TargetAccess, SourceAccess;
2224 AUX_ACCESS_DATA AuxData;
2227 ULONG AuditMask;
2229
2230 PAGED_CODE();
2232 "%s - Duplicating handle: %p for %p into %p\n",
2235 SourceProcess,
2236 TargetProcess);
2237
2238 /* Assume failure */
2240
2241 /* Check if we're not duplicating the same access */
2243 {
2244 /* Validate the desired access */
2245 Status = STATUS_SUCCESS; //ObpValidateDesiredAccess(DesiredAccess);
2246 if (!NT_SUCCESS(Status)) return Status;
2247 }
2248
2249 /* Reference the object table */
2252
2253 /* Reference the process object */
2255 SourceProcess,
2258 &SourceObject,
2260 &AuditMask);
2261 if (!NT_SUCCESS(Status))
2262 {
2263 /* Fail */
2264 ObDereferenceProcessHandleTable(SourceProcess);
2265 return Status;
2266 }
2267 else
2268 {
2269 /* Check if we have to don't have to audit object close */
2270 if (!(HandleInformation.HandleAttributes & OBJ_AUDIT_OBJECT_CLOSE))
2271 {
2272 /* Then there is no audit mask */
2273 AuditMask = 0;
2274 }
2275 }
2276
2277 /* Check if there's no target process */
2278 if (!TargetProcess)
2279 {
2280 /* Check if the caller wanted actual duplication */
2282 {
2283 /* Invalid request */
2285 }
2286 else
2287 {
2288 /* Otherwise, do the attach */
2289 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2290
2291 /* Close the handle and detach */
2294 }
2295
2296 /* Return */
2297 ObDereferenceProcessHandleTable(SourceProcess);
2298 ObDereferenceObject(SourceObject);
2299 return Status;
2300 }
2301
2302 /* Create a kernel handle if asked, but only in the system process */
2303 if (PreviousMode == KernelMode &&
2305 TargetProcess == PsInitialSystemProcess)
2306 {
2308 }
2309
2310 /* Get the target handle table */
2312 if (!HandleTable)
2313 {
2314 /* Check if the caller wanted us to close the handle */
2316 {
2317 /* Do the attach */
2318 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2319
2320 /* Close the handle and detach */
2323 }
2324
2325 /* Return */
2326 ObDereferenceProcessHandleTable(SourceProcess);
2327 ObDereferenceObject(SourceObject);
2329 }
2330
2331 /* Get the source access */
2332 SourceAccess = HandleInformation.GrantedAccess;
2333
2334 /* Check if we're not in the target process */
2335 if (TargetProcess != PsGetCurrentProcess())
2336 {
2337 /* Attach to it */
2338 KeStackAttachProcess(&TargetProcess->Pcb, &ApcState);
2339 AttachedToProcess = TRUE;
2340 }
2341
2342 /* Check if we're duplicating the attributes */
2344 {
2345 /* Duplicate them */
2346 HandleAttributes = HandleInformation.HandleAttributes;
2347 }
2348 else
2349 {
2350 /* Don't allow caller to bypass auditing */
2351 HandleAttributes |= HandleInformation.HandleAttributes &
2353 }
2354
2355 /* Check if we're duplicating the access */
2356 if (Options & DUPLICATE_SAME_ACCESS) DesiredAccess = SourceAccess;
2357
2358 /* Get object data */
2359 ObjectHeader = OBJECT_TO_OBJECT_HEADER(SourceObject);
2360 ObjectType = ObjectHeader->Type;
2361
2362 /* Fill out the entry */
2363 RtlZeroMemory(&NewHandleEntry, sizeof(HANDLE_TABLE_ENTRY));
2364 NewHandleEntry.Object = ObjectHeader;
2366
2367 /* Check if we're using a generic mask */
2369 {
2370 /* Map it */
2372 &ObjectType->TypeInfo.GenericMapping);
2373 }
2374
2375 /* Set the target access, always propagate ACCESS_SYSTEM_SECURITY */
2376 TargetAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask |
2378 NewHandleEntry.GrantedAccess = TargetAccess;
2379
2380 /* Check if we're asking for new access */
2381 if (TargetAccess & ~SourceAccess)
2382 {
2383 /* We are. We need the security procedure to validate this */
2384 if (ObjectType->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
2385 {
2386 /* Use our built-in access state */
2389 &AuxData,
2390 TargetAccess,
2391 &ObjectType->TypeInfo.GenericMapping);
2392 }
2393 else
2394 {
2395 /* Otherwise we can't allow this privilege elevation */
2397 }
2398 }
2399 else
2400 {
2401 /* We don't need an access state */
2403 }
2404
2405 /* Make sure the access state was created OK */
2406 if (NT_SUCCESS(Status))
2407 {
2408 /* Add a new handle */
2409 Status = ObpIncrementHandleCount(SourceObject,
2415 }
2416
2417 /* Check if we were attached */
2418 if (AttachedToProcess)
2419 {
2420 /* We can safely detach now */
2422 AttachedToProcess = FALSE;
2423 }
2424
2425 /* Check if we have to close the source handle */
2427 {
2428 /* Attach and close */
2429 KeStackAttachProcess(&SourceProcess->Pcb, &ApcState);
2432 }
2433
2434 /* Check if we had an access state */
2436
2437 /* Now check if incrementing actually failed */
2438 if (!NT_SUCCESS(Status))
2439 {
2440 /* Dereference handle tables */
2441 ObDereferenceProcessHandleTable(SourceProcess);
2442 ObDereferenceProcessHandleTable(TargetProcess);
2443
2444 /* Dereference the source object */
2445 ObDereferenceObject(SourceObject);
2446 return Status;
2447 }
2448
2449 if (NewHandleEntry.ObAttributes & OBJ_PROTECT_CLOSE)
2450 {
2451 NewHandleEntry.ObAttributes &= ~OBJ_PROTECT_CLOSE;
2452 NewHandleEntry.GrantedAccess |= ObpAccessProtectCloseBit;
2453 }
2454
2455 /* Now create the handle */
2456 NewHandle = ExCreateHandle(HandleTable, &NewHandleEntry);
2457 if (!NewHandle)
2458 {
2459 /* Undo the increment */
2460 ObpDecrementHandleCount(SourceObject,
2461 TargetProcess,
2462 TargetAccess,
2463 ObjectType);
2464
2465 /* Deference the object and set failure status */
2466 ObDereferenceObject(SourceObject);
2468 }
2469
2470 /* Mark it as a kernel handle if requested */
2471 if (KernelHandle)
2472 {
2473 NewHandle = ObMarkHandleAsKernelHandle(NewHandle);
2474 }
2475
2476 /* Return the handle */
2477 if (TargetHandle) *TargetHandle = NewHandle;
2478
2479 /* Dereference handle tables */
2480 ObDereferenceProcessHandleTable(SourceProcess);
2481 ObDereferenceProcessHandleTable(TargetProcess);
2482
2483 /* Return status */
2485 "%s - Duplicated handle: %p for %p into %p. Source: %p HC PC %lx %lx\n",
2487 NewHandle,
2488 SourceProcess,
2489 TargetProcess,
2490 SourceObject,
2491 ObjectHeader->PointerCount,
2492 ObjectHeader->HandleCount);
2493 return Status;
2494}
#define OBJ_PROTECT_CLOSE
static OB_SECURITY_METHOD SeDefaultObjectMethod
Definition: ObTypes.c:134
#define GENERIC_ACCESS
Definition: security.c:35
HANDLE KernelHandle
Definition: legacy.c:24
#define __FUNCTION__
Definition: types.h:116
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE TargetHandle
Definition: obfuncs.h:431
_In_ HANDLE _In_opt_ HANDLE _Out_opt_ PHANDLE _In_ ACCESS_MASK _In_ ULONG HandleAttributes
Definition: obfuncs.h:433
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
@ ObDuplicateHandle
Definition: obtypes.h:143
NTSYSAPI VOID NTAPI RtlMapGenericMask(PACCESS_MASK AccessMask, PGENERIC_MAPPING GenericMapping)
#define ACCESS_SYSTEM_SECURITY
Definition: nt_native.h:77
HANDLE NTAPI ExCreateHandle(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:827
NTSTATUS NTAPI SeCreateAccessState(_Inout_ PACCESS_STATE AccessState, _In_ PAUX_ACCESS_DATA AuxData, _In_ ACCESS_MASK Access, _In_ PGENERIC_MAPPING GenericMapping)
Creates an access state.
Definition: access.c:121
VOID NTAPI SeDeleteAccessState(_In_ PACCESS_STATE AccessState)
Deletes an allocated access state from the memory.
Definition: access.c:150
#define STATUS_PROCESS_IS_TERMINATING
Definition: ntstatus.h:502
#define OBJ_HANDLE_ATTRIBUTES
Definition: ob.h:52
#define OBTRACE(x, fmt,...)
Definition: ob.h:34
#define ObpAccessProtectCloseBit
Definition: ob.h:59
#define ObMarkHandleAsKernelHandle(Handle)
Definition: ob.h:85
#define OB_HANDLE_DEBUG
Definition: ob.h:17
VOID NTAPI ObpDecrementHandleCount(IN PVOID ObjectBody, IN PEPROCESS Process, IN ACCESS_MASK GrantedAccess, IN POBJECT_TYPE ObjectType)
Definition: obhandle.c:530
NTSTATUS NTAPI ObpReferenceProcessObjectByHandle(IN HANDLE Handle, IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation, OUT PACCESS_MASK AuditMask)
Definition: obhandle.c:85
NTSTATUS NTAPI ObpIncrementHandleCount(IN PVOID Object, IN PACCESS_STATE AccessState OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN ULONG HandleAttributes, IN PEPROCESS Process, IN OB_OPEN_REASON OpenReason)
Definition: obhandle.c:811
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
Definition: extypes.h:596
PVOID Object
Definition: extypes.h:599
ULONG GrantedAccess
Definition: extypes.h:606
ULONG_PTR ObAttributes
Definition: extypes.h:600
LONG_PTR HandleCount
Definition: obtypes.h:490
LONG_PTR PointerCount
Definition: obtypes.h:487
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_In_ PWDFDEVICE_INIT _In_ PWDF_REMOVE_LOCK_OPTIONS Options
Definition: wdfdevice.h:3534
_In_ ACCESS_MASK _In_opt_ POBJECT_TYPE _In_ KPROCESSOR_MODE _Out_ PVOID _Out_opt_ POBJECT_HANDLE_INFORMATION HandleInformation
Definition: obfuncs.h:44
#define ObDereferenceObject
Definition: obfuncs.h:203
_Inout_opt_ PACCESS_STATE PassedAccessState
Definition: obfuncs.h:71
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by DbgkpOpenHandles(), and NtDuplicateObject().

◆ ObFastDereferenceObject()

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

Definition at line 167 of file obref.c.

169{
170 /* Release a fast reference. If this failed, use the slow path */
172}
FORCEINLINE BOOLEAN ExReleaseFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:685

Referenced by PsImpersonateClient(), PspCreateProcess(), PspCreateThread(), PspExitThread(), PspInitializeProcessSecurity(), PspSetPrimaryToken(), SeIsTokenChild(), SeIsTokenSibling(), SepImpersonateAnonymousToken(), SepOpenThreadToken(), and SeReleaseSubjectContext().

◆ ObFastReferenceObject()

PVOID FASTCALL ObFastReferenceObject ( IN PEX_FAST_REF  FastRef)

Definition at line 132 of file obref.c.

133{
134 EX_FAST_REF OldValue;
137
138 /* Reference the object and get it pointer */
139 OldValue = ExAcquireFastReference(FastRef);
141
142 /* Check how many references are left */
143 Count = ExGetCountFastReference(OldValue);
144
145 /* Check if the reference count is over 1 */
146 if (Count > 1) return Object;
147
148 /* Check if the reference count has reached 0 */
149 if (!Count) return NULL;
150
151 /* Otherwise, reference the object 7 times */
153
154 /* Now update the reference count */
155 if (!ExInsertFastReference(FastRef, Object))
156 {
157 /* We failed: completely dereference the object */
159 }
160
161 /* Return the Object */
162 return Object;
163}
FORCEINLINE BOOLEAN ExInsertFastReference(IN OUT PEX_FAST_REF FastRef, IN PVOID Object)
Definition: ex.h:646
FORCEINLINE EX_FAST_REF ExAcquireFastReference(IN OUT PEX_FAST_REF FastRef)
Definition: ex.h:617
LONG FASTCALL ObDereferenceObjectEx(IN PVOID Object, IN LONG Count)
Definition: obref.c:88
LONG FASTCALL ObReferenceObjectEx(IN PVOID Object, IN LONG Count)
Definition: obref.c:77
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by PsReferenceEffectiveToken(), and PsReferencePrimaryToken().

◆ ObFastReferenceObjectLocked()

PVOID FASTCALL ObFastReferenceObjectLocked ( IN PEX_FAST_REF  FastRef)

Definition at line 119 of file obref.c.

120{
122 EX_FAST_REF OldValue = *FastRef;
123
124 /* Get the object and reference it slowly */
127 return Object;
128}
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by PsReferenceEffectiveToken(), and PsReferencePrimaryToken().

◆ ObFastReplaceObject()

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

◆ ObfDereferenceDeviceMap()

VOID FASTCALL ObfDereferenceDeviceMap ( IN PDEVICE_MAP  DeviceMap)

Definition at line 477 of file devicemap.c.

478{
479 DPRINT("ObfDereferenceDeviceMap()\n");
480
481 /* Acquire the device map lock */
483
484 /* Decrement the reference counter */
485 DeviceMap->ReferenceCount--;
486 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount);
487
488 /* Leave, if there are still references to this device map */
489 if (DeviceMap->ReferenceCount != 0)
490 {
491 /* Release the device map lock and leave */
493 return;
494 }
495
496 /* Nobody is referencing it anymore, unlink the DOS directory */
497 DeviceMap->DosDevicesDirectory->DeviceMap = NULL;
498
499 /* Release the devicemap lock */
501
502 /* Dereference the DOS Devices Directory and free the Device Map */
503 ObMakeTemporaryObject(DeviceMap->DosDevicesDirectory);
504 ObDereferenceObject(DeviceMap->DosDevicesDirectory);
505 ExFreePoolWithTag(DeviceMap, 'mDbO');
506}
VOID NTAPI ObMakeTemporaryObject(IN PVOID ObjectBody)
Definition: oblife.c:1449

Referenced by ObDereferenceDeviceMap(), ObpLookupObjectName(), ObpSetCurrentProcessDeviceMap(), ObQueryDeviceMapInformation(), ObSetDeviceMap(), SeGetLogonIdDeviceMap(), SepRmDeleteLogonSession(), and SepRmDereferenceLogonSession().

◆ ObFreeObjectCreateInfoBuffer()

VOID NTAPI ObFreeObjectCreateInfoBuffer ( IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo)

Definition at line 603 of file oblife.c.

604{
605 /* Call the macro. We use this function to isolate Ob internals from Io */
607}
@ LookasideCreateInfoList
Definition: mmtypes.h:171
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:416

Referenced by IoCreateStreamFileObjectLite().

◆ ObGetProcessHandleCount()

ULONG NTAPI ObGetProcessHandleCount ( IN PEPROCESS  Process)

Definition at line 56 of file obhandle.c.

57{
58 ULONG HandleCount;
60
62
63 /* Ensure the handle table doesn't go away while we use it */
65
66 if (HandleTable != NULL)
67 {
68 /* Count the number of handles the process has */
69 HandleCount = HandleTable->HandleCount;
70
71 /* Let the handle table go */
73 }
74 else
75 {
76 /* No handle table, no handles */
77 HandleCount = 0;
78 }
79
80 return HandleCount;
81}

Referenced by NtQueryInformationProcess(), and QSI_DEF().

◆ ObInheritDeviceMap()

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

Definition at line 511 of file devicemap.c.

513{
514 PDEVICE_MAP DeviceMap;
515
516 DPRINT("ObInheritDeviceMap()\n");
517
518 /* Acquire the device map lock */
520
521 /* Get the parent process device map or the system device map */
522 DeviceMap = (Parent != NULL) ? Parent->DeviceMap : ObSystemDeviceMap;
523 if (DeviceMap != NULL)
524 {
525 /* Reference the device map and attach it to the new process */
526 DeviceMap->ReferenceCount++;
527 DPRINT("ReferenceCount: %lu\n", DeviceMap->ReferenceCount);
528
529 Process->DeviceMap = DeviceMap;
530 }
531
532 /* Release the device map lock */
534}
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
PDEVICE_MAP ObSystemDeviceMap
Definition: obinit.c:46
ULONG ReferenceCount
Definition: obtypes.h:527

Referenced by PspCreateProcess().

◆ ObInitializeFastReference()

VOID FASTCALL ObInitializeFastReference ( IN PEX_FAST_REF  FastRef,
IN PVOID  Object 
)

Definition at line 107 of file obref.c.

109{
110 /* Check if we were given an object and reference it 7 times */
112
113 /* Setup the fast reference */
115}

Referenced by PspInitializeProcessSecurity(), SeAssignPrimaryToken(), and SepInitializationPhase0().

◆ ObInitProcess()

NTSTATUS NTAPI ObInitProcess ( IN PEPROCESS Parent  OPTIONAL,
IN PEPROCESS  Process 
)

Definition at line 2090 of file obhandle.c.

2092{
2093 PHANDLE_TABLE ParentTable, ObjectTable;
2094
2095 /* Check for a parent */
2096 if (Parent)
2097 {
2098 /* Reference the parent's table */
2100 if (!ParentTable) return STATUS_PROCESS_IS_TERMINATING;
2101
2102 /* Duplicate it */
2103 ObjectTable = ExDupHandleTable(Process,
2104 ParentTable,
2106 OBJ_INHERIT);
2107 }
2108 else
2109 {
2110 /* Otherwise just create a new table */
2111 ParentTable = NULL;
2112 ObjectTable = ExCreateHandleTable(Process);
2113 }
2114
2115 /* Make sure we have a table */
2116 if (ObjectTable)
2117 {
2118 /* Associate it */
2119 Process->ObjectTable = ObjectTable;
2120
2121 /* Check for auditing */
2123 {
2124 /* FIXME: TODO */
2125 DPRINT1("Need auditing!\n");
2126 }
2127
2128 /* Get rid of the old table now */
2129 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2130
2131 /* We are done */
2132 return STATUS_SUCCESS;
2133 }
2134 else
2135 {
2136 /* Fail */
2137 Process->ObjectTable = NULL;
2138 if (ParentTable) ObDereferenceProcessHandleTable(Parent);
2140 }
2141}
#define DPRINT1
Definition: precomp.h:8
PHANDLE_TABLE NTAPI ExCreateHandleTable(IN PEPROCESS Process OPTIONAL)
Definition: handle.c:801
PHANDLE_TABLE NTAPI ExDupHandleTable(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, IN ULONG_PTR Mask)
Definition: handle.c:1072
BOOLEAN NTAPI SeDetailedAuditingWithToken(_In_ PTOKEN Token)
Peforms a detailed security auditing with an access token.
Definition: audit.c:34
BOOLEAN NTAPI ObpDuplicateHandleCallback(IN PEPROCESS Process, IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY OldEntry, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: obhandle.c:1960

Referenced by PspCreateProcess().

◆ ObInitSystem()

BOOLEAN NTAPI ObInitSystem ( VOID  )

Definition at line 203 of file obinit.c.

204{
207 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
210 PKPRCB Prcb = KeGetCurrentPrcb();
211 PLIST_ENTRY ListHead, NextEntry;
213 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
215 PSECURITY_DESCRIPTOR KernelObjectsSD = NULL;
217
218 /* Check if this is actually Phase 1 initialization */
219 if (ObpInitializationPhase != 0) goto ObPostPhase0;
220
221 /* Initialize the OBJECT_CREATE_INFORMATION List */
225 'ICbO',
226 32,
228
229 /* Set the captured UNICODE_STRING Object Name List */
231 PagedPool,
232 248,
233 'MNbO',
234 16,
236
237 /* Temporarily setup both pointers to the shared list */
242
243 /* Initialize the security descriptor cache */
245
246 /* Initialize the Default Event */
248
249 /* Initialize the Dos Device Map mutex */
251
252 /* Setup default access for the system process */
253 PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
254 PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;
255
256 /* Setup the Object Reaper */
258
259 /* Initialize default Quota block */
261
262 /* Create kernel handle table */
265
266 /* Create the Type Type */
267 RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
268 RtlInitUnicodeString(&Name, L"Type");
269 ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
270 ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
271 ObjectTypeInitializer.UseDefaultObject = TRUE;
272 ObjectTypeInitializer.MaintainTypeList = TRUE;
273 ObjectTypeInitializer.PoolType = NonPagedPool;
274 ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
275 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
276 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
277 ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType;
278 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType);
279
280 /* Create the Directory Type */
281 RtlInitUnicodeString(&Name, L"Directory");
282 ObjectTypeInitializer.PoolType = PagedPool;
283 ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
284 ObjectTypeInitializer.CaseInsensitive = TRUE;
285 ObjectTypeInitializer.MaintainTypeList = FALSE;
286 ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
287 ObjectTypeInitializer.DeleteProcedure = NULL;
288 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
289 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpDirectoryObjectType);
290 ObpDirectoryObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
291
292 /* Create 'symbolic link' object type */
293 RtlInitUnicodeString(&Name, L"SymbolicLink");
294 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK);
295 ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
296 ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
297 ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
298 ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
299 ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpSymbolicLinkObjectType);
300 ObpSymbolicLinkObjectType->TypeInfo.ValidAccessMask &= ~SYNCHRONIZE;
301
302 /* Phase 0 initialization complete */
304 return TRUE;
305
306ObPostPhase0:
307
308 /* Re-initialize lookaside lists */
309 ObInit2();
310
311 /* Initialize Object Types directory attributes */
314 &Name,
316 NULL,
318
319 /* Create the directory */
323 if (!NT_SUCCESS(Status)) return FALSE;
324
325 /* Get a handle to it */
327 0,
331 NULL);
332 if (!NT_SUCCESS(Status)) return FALSE;
333
334 /* Close the extra handle */
336 if (!NT_SUCCESS(Status)) return FALSE;
337
338 /* Create a custom security descriptor for the KernelObjects directory */
339 Status = ObpCreateKernelObjectsSD(&KernelObjectsSD);
340 if (!NT_SUCCESS(Status))
341 return FALSE;
342
343 /* Initialize the KernelObjects directory attributes */
344 RtlInitUnicodeString(&Name, L"\\KernelObjects");
346 &Name,
348 NULL,
349 KernelObjectsSD);
350
351 /* Create the directory */
355 ExFreePoolWithTag(KernelObjectsSD, TAG_SD);
356 if (!NT_SUCCESS(Status)) return FALSE;
357
358 /* Close the extra handle */
360 if (!NT_SUCCESS(Status)) return FALSE;
361
362 /* Initialize ObjectTypes directory attributes */
363 RtlInitUnicodeString(&Name, L"\\ObjectTypes");
365 &Name,
367 NULL,
368 NULL);
369
370 /* Create the directory */
374 if (!NT_SUCCESS(Status)) return FALSE;
375
376 /* Get a handle to it */
378 0,
382 NULL);
383 if (!NT_SUCCESS(Status)) return FALSE;
384
385 /* Close the extra handle */
387 if (!NT_SUCCESS(Status)) return FALSE;
388
389 /* Initialize the lookup context and lock it */
392
393 /* Loop the object types */
394 ListHead = &ObpTypeObjectType->TypeList;
395 NextEntry = ListHead->Flink;
396 while (ListHead != NextEntry)
397 {
398 /* Get the creator info from the list */
399 CreatorInfo = CONTAINING_RECORD(NextEntry,
401 TypeList);
402
403 /* Recover the header and the name header from the creator info */
404 Header = (POBJECT_HEADER)(CreatorInfo + 1);
406
407 /* Make sure we have a name, and aren't inserted yet */
408 if ((NameInfo) && !(NameInfo->Directory))
409 {
410 /* Do the initial lookup to setup the context */
412 &NameInfo->Name,
414 FALSE,
415 &Context))
416 {
417 /* Insert this object type */
419 &Context,
420 Header);
421 }
422 }
423
424 /* Move to the next entry */
425 NextEntry = NextEntry->Flink;
426 }
427
428 /* Cleanup after lookup */
430
431 /* Initialize DOS Devices Directory and related Symbolic Links */
433 if (!NT_SUCCESS(Status)) return FALSE;
434 return TRUE;
435}
#define ObpDirectoryObjectType
Definition: ObTypes.c:118
static POBJECT_TYPE ObpDefaultObject
Definition: ObTypes.c:133
static POBJECT_TYPE ObpTypeObjectType
Definition: ObTypes.c:117
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:119
struct NameRec_ * Name
Definition: cdprocs.h:460
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define PsGetCurrentThread()
Definition: env_spec_w32.h:81
#define KeInitializeEvent(pEvt, foo, foo2)
Definition: env_spec_w32.h:477
#define NonPagedPool
Definition: env_spec_w32.h:307
#define PagedPool
Definition: env_spec_w32.h:308
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_OPENLINK
Definition: winternl.h:230
#define OBJ_PERMANENT
Definition: winternl.h:226
VOID NTAPI ExInitializeSystemLookasideList(IN PGENERAL_LOOKASIDE List, IN POOL_TYPE Type, IN ULONG Size, IN ULONG Tag, IN USHORT MaximumDepth, IN PLIST_ENTRY ListHead)
Definition: lookas.c:31
LIST_ENTRY ExSystemLookasideListHead
Definition: lookas.c:21
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
FORCEINLINE struct _KPRCB * KeGetCurrentPrcb(VOID)
Definition: ketypes.h:1148
@ LookasideNameBufferList
Definition: mmtypes.h:172
struct _OBJECT_SYMBOLIC_LINK OBJECT_SYMBOLIC_LINK
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
struct _OBJECT_HEADER * POBJECT_HEADER
struct _OBJECT_DIRECTORY OBJECT_DIRECTORY
#define SYMBOLIC_LINK_ALL_ACCESS
Definition: nt_native.h:1267
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1339
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1324
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define OBJECT_TYPE_ALL_ACCESS
Definition: nt_native.h:1248
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define DIRECTORY_ALL_ACCESS
Definition: nt_native.h:1259
@ NotificationEvent
OBJECT_TYPE
Definition: ntobjenum.h:13
PSECURITY_DESCRIPTOR SePublicDefaultUnrestrictedSd
Definition: sd.c:17
#define L(x)
Definition: ntvdm.h:50
VOID NTAPI ObpReapObject(IN PVOID Unused)
Definition: oblife.c:220
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
VOID NTAPI ObpDeleteObjectType(IN PVOID Object)
Definition: oblife.c:1417
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
NTSTATUS NTAPI ObpCreateDosDevicesDirectory(VOID)
Definition: obname.c:177
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN UCHAR SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:158
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
GENERAL_LOOKASIDE ObpNameBufferLookasideList
Definition: oblife.c:26
WORK_QUEUE_ITEM ObpReaperWorkItem
Definition: oblife.c:28
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
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)
Definition: oblink.c:431
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
Definition: ob.h:644
VOID NTAPI ObpDeleteSymbolicLink(IN PVOID ObjectBody)
NTSTATUS NTAPI ObpInitSdCache(VOID)
Definition: obsdcach.c:61
FORCEINLINE VOID ObpAcquireLookupContextLock(IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_DIRECTORY Directory)
Locks an object directory lookup context for performing lookup operations (insertions/deletions) in a...
Definition: ob_x.h:281
FORCEINLINE VOID ObpInitializeLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Initializes a new object directory lookup context. Used for lookup operations (insertions/deletions) ...
Definition: ob_x.h:258
FORCEINLINE VOID ObpReleaseLookupContext(IN POBP_LOOKUP_CONTEXT Context)
Releases an initialized object directory lookup context. Unlocks it if necessary, and dereferences th...
Definition: ob_x.h:323
NTSTATUS NTAPI NtCreateDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:765
VOID NTAPI PsInitializeQuotaSystem(VOID)
Initializes the quota system during boot phase of the system, which sets up the default quota block t...
Definition: quota.c:443
BOOLEAN NTAPI ObInit2(VOID)
Definition: obinit.c:136
ULONG ObpInitializationPhase
Definition: obinit.c:54
GENERIC_MAPPING ObpSymbolicLinkMapping
Definition: obinit.c:38
static NTSTATUS NTAPI ObpCreateKernelObjectsSD(OUT PSECURITY_DESCRIPTOR *SecurityDescriptor)
Definition: obinit.c:65
GENERIC_MAPPING ObpTypeMapping
Definition: obinit.c:19
GENERIC_MAPPING ObpDirectoryMapping
Definition: obinit.c:27
NTSTATUS NTAPI ObCreateObjectType(IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
Definition: oblife.c:1136
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
PP_LOOKASIDE_LIST PPLookasideList[16]
Definition: ketypes.h:694
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
UNICODE_STRING Name
Definition: obtypes.h:433
GENERIC_MAPPING GenericMapping
Definition: obtypes.h:358
OB_DELETE_METHOD DeleteProcedure
Definition: obtypes.h:369
OB_PARSE_METHOD ParseProcedure
Definition: obtypes.h:370
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
LIST_ENTRY TypeList
Definition: obtypes.h:382
struct _GENERAL_LOOKASIDE * P
Definition: ketypes.h:871
struct _GENERAL_LOOKASIDE * L
Definition: ketypes.h:872
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define ExInitializeWorkItem(Item, Routine, Context)
Definition: exfuncs.h:265

Referenced by ExpInitializeExecutive(), and Phase1InitializationDiscard().

◆ ObIsLUIDDeviceMapsEnabled()

ULONG NTAPI ObIsLUIDDeviceMapsEnabled ( VOID  )

Definition at line 662 of file devicemap.c.

663{
665}
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18

Referenced by NtQueryInformationProcess(), and PspSetPrimaryToken().

◆ ObKillProcess()

VOID NTAPI ObKillProcess ( IN PEPROCESS  Process)

Definition at line 2160 of file obhandle.c.

2161{
2164 BOOLEAN HardErrors;
2165 PAGED_CODE();
2166
2167 /* Wait for process rundown and then complete it */
2169 ExRundownCompleted(&Process->RundownProtect);
2170
2171 /* Get the object table */
2172 HandleTable = Process->ObjectTable;
2173 if (!HandleTable) return;
2174
2175 /* Disable hard errors while we close handles */
2176 HardErrors = IoSetThreadHardErrorMode(FALSE);
2177
2178 /* Enter a critical region */
2180
2181 /* Fill out the context */
2182 Context.AccessMode = KernelMode;
2183 Context.HandleTable = HandleTable;
2184
2185 /* Sweep the handle table to close all handles */
2188 &Context);
2189 ASSERT(HandleTable->HandleCount == 0);
2190
2191 /* Leave the critical region */
2193
2194 /* Re-enable hard errors */
2195 IoSetThreadHardErrorMode(HardErrors);
2196
2197 /* Destroy the object table */
2198 Process->ObjectTable = NULL;
2200}
#define ExWaitForRundownProtectionRelease
Definition: ex.h:138
#define ExRundownCompleted
Definition: ex.h:139
VOID NTAPI ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, IN PVOID DestroyHandleProcedure OPTIONAL)
Definition: handle.c:963
BOOLEAN NTAPI IoSetThreadHardErrorMode(IN BOOLEAN HardErrorEnabled)
Definition: error.c:726

Referenced by PspDeleteProcess(), and PspExitThread().

◆ ObpCaptureObjectCreateInformation()

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

Definition at line 455 of file oblife.c.

461{
462 ULONG SdCharge, QuotaInfoSize;
466 PUNICODE_STRING LocalObjectName = NULL;
467 PAGED_CODE();
468
469 /* Zero out the Capture Data */
470 RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
471
472 /* SEH everything here for protection */
474 {
475 /* Check if we got attributes */
477 {
478 /* Check if we're in user mode */
479 if (AccessMode != KernelMode)
480 {
481 /* Probe the attributes */
483 sizeof(OBJECT_ATTRIBUTES),
484 sizeof(ULONG));
485 }
486
487 /* Validate the Size and Attributes */
488 if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
490 {
491 /* Invalid combination, fail */
493 }
494
495 /* Set some Create Info and do not allow user-mode kernel handles */
496 ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
497 ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_KERNEL_ATTRIBUTES;
498 if (CreatorMode != KernelMode) ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
499 LocalObjectName = ObjectAttributes->ObjectName;
500 SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
501 SecurityQos = ObjectAttributes->SecurityQualityOfService;
502
503 /* Check if we have a security descriptor */
505 {
506 /* Capture it. Note: This has an implicit memory barrier due
507 to the function call, so cleanup is safe here.) */
511 TRUE,
512 &ObjectCreateInfo->
514 if (!NT_SUCCESS(Status))
515 {
516 /* Capture failed, quit */
517 ObjectCreateInfo->SecurityDescriptor = NULL;
518 _SEH2_YIELD(return Status);
519 }
520
521 /*
522 * By default, assume a SD size of 1024 and allow twice its
523 * size.
524 * If SD size happen to be bigger than that, then allow it
525 */
526 SdCharge = 2048;
527 SeComputeQuotaInformationSize(ObjectCreateInfo->SecurityDescriptor,
528 &QuotaInfoSize);
529 if ((2 * QuotaInfoSize) > 2048)
530 {
531 SdCharge = 2 * QuotaInfoSize;
532 }
533
534 /* Save the probe mode and security descriptor size */
535 ObjectCreateInfo->SecurityDescriptorCharge = SdCharge;
536 ObjectCreateInfo->ProbeMode = AccessMode;
537 }
538
539 /* Check if we have QoS */
540 if (SecurityQos)
541 {
542 /* Check if we came from user mode */
543 if (AccessMode != KernelMode)
544 {
545 /* Validate the QoS */
546 ProbeForRead(SecurityQos,
548 sizeof(ULONG));
549 }
550
551 /* Save Info */
552 ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
553 ObjectCreateInfo->SecurityQos =
554 &ObjectCreateInfo->SecurityQualityOfService;
555 }
556 }
557 else
558 {
559 /* We don't have a name */
560 LocalObjectName = NULL;
561 }
562 }
564 {
565 /* Cleanup and return the exception code */
566 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
568 }
569 _SEH2_END;
570
571 /* Now check if the Object Attributes had an Object Name */
572 if (LocalObjectName)
573 {
575 LocalObjectName,
577 AllocateFromLookaside);
578 }
579 else
580 {
581 /* Clear the string */
582 RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
583
584 /* It cannot have specified a Root Directory */
585 if (ObjectCreateInfo->RootDirectory)
586 {
588 }
589 }
590
591 /* Cleanup if we failed */
592 if (!NT_SUCCESS(Status))
593 {
594 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
595 }
596
597 /* Return status to caller */
598 return Status;
599}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
NTSTATUS NTAPI SeComputeQuotaInformationSize(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Out_ PULONG QuotaInfoSize)
NTSTATUS NTAPI SeCaptureSecurityDescriptor(_In_ PSECURITY_DESCRIPTOR _OriginalSecurityDescriptor, _In_ KPROCESSOR_MODE CurrentMode, _In_ POOL_TYPE PoolType, _In_ BOOLEAN CaptureIfKernel, _Out_ PSECURITY_DESCRIPTOR *CapturedSecurityDescriptor)
Captures a security descriptor.
Definition: sd.c:386
FORCEINLINE VOID ObpReleaseObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:364
NTSTATUS NTAPI ObpCaptureObjectName(IN OUT PUNICODE_STRING CapturedName, IN PUNICODE_STRING ObjectName, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN UseLookaside)
Definition: oblife.c:376
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64

Referenced by ObCreateObject(), and ObOpenObjectByName().

◆ ObpCaptureObjectName()

NTSTATUS NTAPI ObpCaptureObjectName ( IN PUNICODE_STRING  CapturedName,
IN PUNICODE_STRING  ObjectName,
IN KPROCESSOR_MODE  AccessMode,
IN BOOLEAN  AllocateFromLookaside 
)

Referenced by ObReferenceObjectByName().

◆ ObpCheckObjectReference()

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

Definition at line 340 of file obsecure.c.

345{
346 POBJECT_HEADER ObjectHeader;
349 BOOLEAN SdAllocated;
354 PAGED_CODE();
355
356 /* Get the header and type */
357 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
358 ObjectType = ObjectHeader->Type;
359
360 /* Get the security descriptor */
362 if (!NT_SUCCESS(Status))
363 {
364 /* We failed */
366 return FALSE;
367 }
368
369 /* Lock the security context */
370 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
371
372 /* Now do the entire access check */
374 &AccessState->SubjectSecurityContext,
375 TRUE,
376 AccessState->RemainingDesiredAccess,
377 AccessState->PreviouslyGrantedAccess,
378 &Privileges,
379 &ObjectType->TypeInfo.GenericMapping,
383 if (Result)
384 {
385 /* Update the access state */
386 AccessState->RemainingDesiredAccess &= ~GrantedAccess;
387 AccessState->PreviouslyGrantedAccess |= GrantedAccess;
388 }
389
390 /* Check if we have an SD */
392 {
393 /* Do audit alarm */
394#if 0
395 SeObjectReferenceAuditAlarm(&AccessState->OperationID,
396 Object,
398 &AccessState->SubjectSecurityContext,
399 AccessState->RemainingDesiredAccess |
400 AccessState->PreviouslyGrantedAccess,
401 ((PAUX_ACCESS_DATA)(AccessState->AuxData))->
402 PrivilegeSet,
403 Result,
404 AccessMode);
405#endif
406 }
407
408 /* We're done, unlock the context and release security */
409 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
411 return Result;
412}

Referenced by ObReferenceObjectByName().

◆ ObpCheckTraverseAccess()

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 
)

Definition at line 267 of file obsecure.c.

273{
274 POBJECT_HEADER ObjectHeader;
277 BOOLEAN SdAllocated;
282 PAGED_CODE();
283
284 /* Get the header and type */
285 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
286 ObjectType = ObjectHeader->Type;
287
288 /* Get the security descriptor */
290 if (!NT_SUCCESS(Status))
291 {
292 /* We failed */
294 return FALSE;
295 }
296
297 /* First try to perform a fast traverse check
298 * If it fails, then the entire access check will
299 * have to be done.
300 */
304 AccessMode);
305 if (Result)
306 {
308 return TRUE;
309 }
310
311 /* Lock the security context */
312 SeLockSubjectContext(&AccessState->SubjectSecurityContext);
313
314 /* Now do the entire access check */
316 &AccessState->SubjectSecurityContext,
317 TRUE,
318 TraverseAccess,
319 0,
320 &Privileges,
321 &ObjectType->TypeInfo.GenericMapping,
325 if (Privileges)
326 {
327 /* We got privileges, append them to the access state and free them */
330 }
331
332 /* We're done, unlock the context and release security */
333 SeUnlockSubjectContext(&AccessState->SubjectSecurityContext);
335 return Result;
336}
#define FILE_WRITE_DATA
Definition: nt_native.h:631
BOOLEAN NTAPI SeFastTraverseCheck(_In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _In_ PACCESS_STATE AccessState, _In_ ACCESS_MASK DesiredAccess, _In_ KPROCESSOR_MODE AccessMode)
Determines whether security access rights can be given to an object depending on the security descrip...
Definition: accesschk.c:2138

Referenced by ObpLookupObjectName().

◆ ObpCreateDosDevicesDirectory()

NTSTATUS NTAPI ObpCreateDosDevicesDirectory ( VOID  )

Definition at line 177 of file obname.c.

178{
180 UNICODE_STRING RootName, TargetName, LinkName;
181 HANDLE Handle, SymHandle;
182 SECURITY_DESCRIPTOR DosDevicesSD;
184
185 /*
186 * Enable LUID mappings only if not explicitely disabled
187 * and if protection mode is set
188 */
191 else
193
194 /* Create a custom security descriptor for the global DosDevices directory */
195 Status = ObpGetDosDevicesProtection(&DosDevicesSD);
196 if (!NT_SUCCESS(Status))
197 return Status;
198
199 /* Create the global DosDevices directory \?? */
200 RtlInitUnicodeString(&RootName, L"\\GLOBAL??");
202 &RootName,
204 NULL,
205 &DosDevicesSD);
209 if (!NT_SUCCESS(Status))
210 goto done;
211
212 /* Create the system device map */
214 if (!NT_SUCCESS(Status))
215 goto done;
216
217 /*
218 * Initialize the \??\GLOBALROOT symbolic link
219 * pointing to the root directory \ .
220 */
221 RtlInitUnicodeString(&LinkName, L"GLOBALROOT");
224 &LinkName,
226 Handle,
227 &DosDevicesSD);
231 &TargetName);
232 if (NT_SUCCESS(Status)) NtClose(SymHandle);
233
234 /*
235 * Initialize the \??\Global symbolic link pointing to the global
236 * DosDevices directory \?? . It is used to access the global \??
237 * by user-mode components which, by default, use a per-session
238 * DosDevices directory.
239 */
240 RtlInitUnicodeString(&LinkName, L"Global");
242 &LinkName,
244 Handle,
245 &DosDevicesSD);
249 &RootName);
250 if (NT_SUCCESS(Status)) NtClose(SymHandle);
251
252 /* Close the directory handle */
254 if (!NT_SUCCESS(Status))
255 goto done;
256
257 /*
258 * Initialize the \DosDevices symbolic link pointing to the global
259 * DosDevices directory \?? , for backward compatibility with
260 * Windows NT-2000 systems.
261 */
262 RtlInitUnicodeString(&LinkName, L"\\DosDevices");
265 &LinkName,
267 NULL,
268 &DosDevicesSD);
272 &RootName);
273 if (NT_SUCCESS(Status)) NtClose(SymHandle);
274
275done:
276 ObpFreeDosDevicesProtection(&DosDevicesSD);
277
278 /* Return status */
279 return Status;
280}
NTSTATUS NTAPI ObSetDeviceMap(IN PEPROCESS Process, IN HANDLE DirectoryHandle)
Definition: devicemap.c:24
ULONG ObpProtectionMode
Definition: obinit.c:57
ULONG ObpLUIDDeviceMapsEnabled
Definition: devicemap.c:18
ULONG ObpLUIDDeviceMapsDisabled
Definition: devicemap.c:17
NTSTATUS NTAPI ObpGetDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:40
ALIGNEDNAME ObpDosDevicesShortNameRoot
Definition: obname.c:24
VOID NTAPI ObpFreeDosDevicesProtection(OUT PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: obname.c:161
static PCWSTR TargetName
Definition: ping.c:67
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by ObInitSystem().

◆ ObpCreateSymbolicLinkName()

VOID NTAPI ObpCreateSymbolicLinkName ( IN POBJECT_SYMBOLIC_LINK  SymbolicLink)

Definition at line 334 of file oblink.c.

335{
336 WCHAR UpperDrive;
337 POBJECT_HEADER ObjectHeader;
338 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
339
340 /* Get header data */
342 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
343
344 /* No name info, nothing to create */
345 if (ObjectNameInfo == NULL)
346 {
347 return;
348 }
349
350 /* If we have a device map, look for creating a letter based drive */
351 if (ObjectNameInfo->Directory != NULL &&
352 ObjectNameInfo->Directory->DeviceMap != NULL)
353 {
354 /* Is it a drive letter based name? */
355 if (ObjectNameInfo->Name.Length == 2 * sizeof(WCHAR))
356 {
357 if (ObjectNameInfo->Name.Buffer[1] == L':')
358 {
359 UpperDrive = RtlUpcaseUnicodeChar(ObjectNameInfo->Name.Buffer[0]);
360 if (UpperDrive >= L'A' && UpperDrive <= L'Z')
361 {
362 /* Compute its index (it's 1 based - 0 means no letter) */
363 SymbolicLink->DosDeviceDriveIndex = UpperDrive - (L'A' - 1);
364 }
365 }
366 }
367
368 /* Call the helper */
370 }
371
372 /* We're done */
373 ObpDereferenceNameInfo(ObjectNameInfo);
374}
static const WCHAR SymbolicLink[]
Definition: interface.c:31
WCHAR NTAPI RtlUpcaseUnicodeChar(_In_ WCHAR Source)
Definition: nlsboot.c:176
FORCEINLINE VOID ObpDereferenceNameInfo(IN POBJECT_HEADER_NAME_INFO HeaderNameInfo)
Definition: ob_x.h:143
FORCEINLINE POBJECT_HEADER_NAME_INFO ObpReferenceNameInfo(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:102
struct _DEVICE_MAP * DeviceMap
Definition: obtypes.h:418
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ObInsertObject().

◆ ObpDeleteEntryDirectory()

BOOLEAN NTAPI ObpDeleteEntryDirectory ( IN POBP_LOOKUP_CONTEXT  Context)

Referenced by ObpDeleteNameCheck().

◆ ObpDeleteNameCheck()

VOID NTAPI ObpDeleteNameCheck ( IN PVOID  Object)

Definition at line 301 of file obname.c.

302{
303 POBJECT_HEADER ObjectHeader;
305 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
308
309 /* Get object structures */
310 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
311 ObjectNameInfo = ObpReferenceNameInfo(ObjectHeader);
312 ObjectType = ObjectHeader->Type;
313
314 /*
315 * Check if the handle count is 0, if the object is named,
316 * and if the object isn't a permanent object.
317 */
318 if (!(ObjectHeader->HandleCount) &&
319 (ObjectNameInfo) &&
320 (ObjectNameInfo->Name.Length) &&
321 (ObjectNameInfo->Directory) &&
322 !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
323 {
324 /* Setup a lookup context and lock it */
327
328 /* Do the lookup */
329 Object = ObpLookupEntryDirectory(ObjectNameInfo->Directory,
330 &ObjectNameInfo->Name,
331 0,
332 FALSE,
333 &Context);
334 if (Object)
335 {
336 /* Lock the object */
337 ObpAcquireObjectLock(ObjectHeader);
338
339 /* Make sure we can still delete the object */
340 if (!(ObjectHeader->HandleCount) &&
341 !(ObjectHeader->Flags & OB_FLAG_PERMANENT))
342 {
343 /* First delete it from the directory */
345
346 /* Check if this is a symbolic link */
348 {
349 /* Remove internal name */
351 }
352
353 /* Check if the kernel exclusive flag is set */
354 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
355 if ((ObjectNameInfo) &&
356 (ObjectNameInfo->QueryReferences & OB_FLAG_KERNEL_EXCLUSIVE))
357 {
358 /* Remove protection flag */
361 }
362
363 /* Get the directory */
364 Directory = ObjectNameInfo->Directory;
365 }
366
367 /* Release the lock */
368 ObpReleaseObjectLock(ObjectHeader);
369 }
370
371 /* Cleanup after lookup */
373
374 /* Remove another query reference since we added one on top */
375 ObpDereferenceNameInfo(ObjectNameInfo);
376
377 /* Check if we were inserted in a directory */
378 if (Directory)
379 {
380 /* We were, so first remove the extra reference we had added */
381 ObpDereferenceNameInfo(ObjectNameInfo);
382
383 /* Now dereference the object as well */
385 }
386 }
387 else
388 {
389 /* Remove the reference we added */
390 ObpDereferenceNameInfo(ObjectNameInfo);
391 }
392}
#define InterlockedExchangeAdd
Definition: interlocked.h:181
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
BOOLEAN NTAPI ObpDeleteEntryDirectory(IN POBP_LOOKUP_CONTEXT Context)
VOID NTAPI ObpDeleteSymbolicLinkName(IN POBJECT_SYMBOLIC_LINK SymbolicLink)
Definition: oblink.c:326
FORCEINLINE VOID ObpAcquireObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:48
FORCEINLINE VOID ObpReleaseObjectLock(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:84
base for all directory entries
Definition: entries.h:138
UCHAR Flags
Definition: obtypes.h:497
int32_t * PLONG
Definition: typedefs.h:58

Referenced by ObInsertObject(), ObpDecrementHandleCount(), and ObpSetPermanentObject().

◆ ObpDeleteObject()

VOID NTAPI ObpDeleteObject ( IN PVOID  Object,
IN BOOLEAN  CalledFromWorkerThread 
)

Definition at line 147 of file oblife.c.

149{
153 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
154 KIRQL CalloutIrql;
155 PAGED_CODE();
156
157 /* Get the header and type */
159 ObjectType = Header->Type;
160
161 /* Get creator and name information */
164
165 /* Check if the object is on a type list */
166 if ((CreatorInfo) && !(IsListEmpty(&CreatorInfo->TypeList)))
167 {
168 /* Lock the object type */
170
171 /* Remove the object from the type list */
172 RemoveEntryList(&CreatorInfo->TypeList);
173
174 /* Release the lock */
176 }
177
178 /* Check if we have a name */
179 if ((NameInfo) && (NameInfo->Name.Buffer))
180 {
181 /* Free it */
182 ExFreePool(NameInfo->Name.Buffer);
183 RtlInitEmptyUnicodeString(&NameInfo->Name, NULL, 0);
184 }
185
186 /* Check if we have a security descriptor */
187 if (Header->SecurityDescriptor)
188 {
189 /* Call the security procedure to delete it */
190 ObpCalloutStart(&CalloutIrql);
191 ObjectType->TypeInfo.SecurityProcedure(Object,
192 DeleteSecurityDescriptor,
193 0,
194 NULL,
195 NULL,
196 &Header->SecurityDescriptor,
197 0,
198 NULL);
199 ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object);
200 }
201
202 /* Check if we have a delete procedure */
203 if (ObjectType->TypeInfo.DeleteProcedure)
204 {
205 /* Save whether we were deleted from worker thread or not */
206 if (!CalledFromWorkerThread) Header->Flags |= OB_FLAG_DEFER_DELETE;
207
208 /* Call it */
209 ObpCalloutStart(&CalloutIrql);
210 ObjectType->TypeInfo.DeleteProcedure(Object);
211 ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object);
212 }
213
214 /* Now de-allocate all object members */
216}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:126
#define OB_FLAG_DEFER_DELETE
Definition: obtypes.h:104
FORCEINLINE VOID ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
FORCEINLINE VOID ObpCalloutStart(IN PKIRQL CalloutIrql)
Definition: ob_x.h:497
FORCEINLINE VOID ObpCalloutEnd(IN KIRQL CalloutIrql, IN PCHAR Procedure, IN POBJECT_TYPE ObjectType, IN PVOID Object)
Definition: ob_x.h:505
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
VOID FASTCALL ObpDeallocateObject(IN PVOID Object)
Definition: oblife.c:39

Referenced by ObfDereferenceObject(), and ObpReapObject().

◆ ObpDeleteObjectType()

VOID NTAPI ObpDeleteObjectType ( IN PVOID  Object)

Definition at line 1417 of file oblife.c.

1418{
1419 ULONG i;
1421
1422 /* Loop our locks */
1423 for (i = 0; i < 4; i++)
1424 {
1425 /* Delete each one */
1426 ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1427 }
1428
1429 /* Delete our main mutex */
1431}
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void * PVOID
Definition: typedefs.h:50

Referenced by ObInitSystem().

◆ ObpDeleteSymbolicLink()

VOID NTAPI ObpDeleteSymbolicLink ( IN PVOID  ObjectBody)

Referenced by ObInitSystem().

◆ ObpDeleteSymbolicLinkName()

VOID NTAPI ObpDeleteSymbolicLinkName ( IN POBJECT_SYMBOLIC_LINK  SymbolicLink)

Definition at line 326 of file oblink.c.

327{
328 /* Just call the helper */
330}

Referenced by ObpDeleteNameCheck().

◆ ObpFreeObjectNameBuffer()

VOID NTAPI ObpFreeObjectNameBuffer ( IN PUNICODE_STRING  Name)

Definition at line 346 of file oblife.c.

347{
348 PVOID Buffer = Name->Buffer;
349
350 /* We know this is a pool-allocation if the size doesn't match */
351 if (Name->MaximumLength != OBP_NAME_LOOKASIDE_MAX_SIZE)
352 {
353 /*
354 * Free it from the pool.
355 *
356 * We cannot use here ExFreePoolWithTag(..., OB_NAME_TAG); , because
357 * the object name may have been massaged during operation by different
358 * object parse routines. If the latter ones have to resolve a symbolic
359 * link (e.g. as is done by CmpParseKey() and CmpGetSymbolicLink()),
360 * the original object name is freed and re-allocated from the pool,
361 * possibly with a different pool tag. At the end of the day, the new
362 * object name can be reallocated and completely different, but we
363 * should still be able to free it!
364 */
366 }
367 else
368 {
369 /* Otherwise, free from the lookaside */
371 }
372}
Definition: bufpool.h:45
#define OBP_NAME_LOOKASIDE_MAX_SIZE
Definition: ob_x.h:18

Referenced by ObCreateObject(), ObOpenObjectByName(), ObpCaptureObjectName(), and ObReferenceObjectByName().

◆ ObpInitSdCache()

NTSTATUS NTAPI ObpInitSdCache ( VOID  )

Definition at line 61 of file obsdcach.c.

62{
63 ULONG i;
64
65 /* Loop each cache entry */
66 for (i = 0; i < SD_CACHE_ENTRIES; i++)
67 {
68 /* Initialize the lock and the list */
71 }
72
73 /* Return success */
74 return STATUS_SUCCESS;
75}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define ExInitializePushLock
Definition: ex.h:1013
#define SD_CACHE_ENTRIES
Definition: obsdcach.c:17
OB_SD_CACHE_LIST ObsSecurityDescriptorCache[SD_CACHE_ENTRIES]
Definition: obsdcach.c:18

Referenced by ObInitSystem().

◆ ObpInsertEntryDirectory()

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

Definition at line 45 of file obdir.c.

48{
49 POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
51 POBJECT_HEADER_NAME_INFO HeaderNameInfo;
52
53 /* Make sure we have a name */
54 ASSERT(ObjectHeader->NameInfoOffset != 0);
55
56 /* Validate the context */
57 if ((Context->Object) ||
58 !(Context->DirectoryLocked) ||
59 (Parent != Context->Directory))
60 {
61 /* Invalid context */
62 DPRINT1("OB: ObpInsertEntryDirectory - invalid context %p %u\n",
63 Context, Context->DirectoryLocked);
65 return FALSE;
66 }
67
68 /* Allocate a new Directory Entry */
72 if (!NewEntry) return FALSE;
73
74 /* Save the hash */
75 NewEntry->HashValue = Context->HashValue;
76
77 /* Get the Object Name Information */
78 HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
79
80 /* Get the Allocated entry */
81 AllocatedEntry = &Parent->HashBuckets[Context->HashIndex];
82
83 /* Set it */
84 NewEntry->ChainLink = *AllocatedEntry;
85 *AllocatedEntry = NewEntry;
86
87 /* Associate the Object */
88 NewEntry->Object = &ObjectHeader->Body;
89
90 /* Associate the Directory */
91 HeaderNameInfo->Directory = Parent;
92 return TRUE;
93}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
Definition: obtypes.h:399
ULONG HashValue
Definition: obtypes.h:403
struct _OBJECT_DIRECTORY_ENTRY * ChainLink
Definition: obtypes.h:400
PVOID Object
Definition: obtypes.h:401
#define OB_DIR_TAG
Definition: tag.h:119

Referenced by ObCreateObjectType(), ObInitSystem(), and ObpLookupObjectName().

◆ ObpLookupEntryDirectory()

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

Definition at line 158 of file obdir.c.

163{
165 POBJECT_HEADER_NAME_INFO HeaderNameInfo;
166 POBJECT_HEADER ObjectHeader;
168 ULONG HashIndex;
169 LONG TotalChars;
170 WCHAR CurrentChar;
171 POBJECT_DIRECTORY_ENTRY *AllocatedEntry;
172 POBJECT_DIRECTORY_ENTRY *LookupBucket;
173 POBJECT_DIRECTORY_ENTRY CurrentEntry;
174 PVOID FoundObject = NULL;
176 POBJECT_DIRECTORY ShadowDirectory;
177
178 PAGED_CODE();
179
180 /* Check if we should search the shadow directory */
181 if (ObpLUIDDeviceMapsEnabled == 0) SearchShadow = FALSE;
182
183 /* Fail if we don't have a directory or name */
184 if (!(Directory) || !(Name)) goto Quickie;
185
186 /* Get name information */
187 TotalChars = Name->Length / sizeof(WCHAR);
188 Buffer = Name->Buffer;
189
190 /* Set up case-sensitivity */
192
193 /* Fail if the name is empty */
194 if (!(Buffer) || !(TotalChars)) goto Quickie;
195
196 /* Create the Hash */
197 for (HashValue = 0; TotalChars; TotalChars--)
198 {
199 /* Go to the next Character */
200 CurrentChar = *Buffer++;
201
202 /* Prepare the Hash */
203 HashValue += (HashValue << 1) + (HashValue >> 1);
204
205 /* Create the rest based on the name */
206 if (CurrentChar < 'a') HashValue += CurrentChar;
207 else if (CurrentChar > 'z') HashValue += RtlUpcaseUnicodeChar(CurrentChar);
208 else HashValue += (CurrentChar - ('a'-'A'));
209 }
210
211 /* Merge it with our number of hash buckets */
212 HashIndex = HashValue % 37;
213
214 /* Save the result */
215 Context->HashValue = HashValue;
216 Context->HashIndex = (USHORT)HashIndex;
217
218DoItAgain:
219 /* Get the root entry and set it as our lookup bucket */
220 AllocatedEntry = &Directory->HashBuckets[HashIndex];
221 LookupBucket = AllocatedEntry;
222
223 /* Check if the directory is already locked */
224 if (!Context->DirectoryLocked)
225 {
226 /* Lock it */
228 }
229
230 /* Start looping */
231 while ((CurrentEntry = *AllocatedEntry))
232 {
233 /* Do the hashes match? */
234 if (CurrentEntry->HashValue == HashValue)
235 {
236 /* Make sure that it has a name */
237 ObjectHeader = OBJECT_TO_OBJECT_HEADER(CurrentEntry->Object);
238
239 /* Get the name information */
240 ASSERT(ObjectHeader->NameInfoOffset != 0);
241 HeaderNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
242
243 /* Do the names match? */
244 if ((Name->Length == HeaderNameInfo->Name.Length) &&
245 (RtlEqualUnicodeString(Name, &HeaderNameInfo->Name, CaseInsensitive)))
246 {
247 break;
248 }
249 }
250
251 /* Move to the next entry */
252 AllocatedEntry = &CurrentEntry->ChainLink;
253 }
254
255 /* Check if we still have an entry */
256 if (CurrentEntry)
257 {
258 /* Set this entry as the first, to speed up incoming insertion */
259 if (AllocatedEntry != LookupBucket)
260 {
261 /* Check if the directory was locked or convert the lock */
262 if ((Context->DirectoryLocked) ||
264 {
265 /* Set the Current Entry */
266 *AllocatedEntry = CurrentEntry->ChainLink;
267
268 /* Link to the old Hash Entry */
269 CurrentEntry->ChainLink = *LookupBucket;
270
271 /* Set the new Hash Entry */
272 *LookupBucket = CurrentEntry;
273 }
274 }
275
276 /* Save the found object */
277 FoundObject = CurrentEntry->Object;
278 goto Quickie;
279 }
280 else
281 {
282 /* Check if the directory was locked */
283 if (!Context->DirectoryLocked)
284 {
285 /* Release the lock */
287 }
288
289 /* Check if we should scan the shadow directory */
290 if ((SearchShadow) && (Directory->DeviceMap))
291 {
292 ShadowDirectory = ObpGetShadowDirectory(Directory);
293 /* A global DOS directory was found, loop it again */
294 if (ShadowDirectory != NULL)
295 {
296 Directory = ShadowDirectory;
297 goto DoItAgain;
298 }
299 }
300 }
301
302Quickie:
303 /* Check if we inserted an object */
304 if (FoundObject)
305 {
306 /* Get the object name information */
307 ObjectHeader = OBJECT_TO_OBJECT_HEADER(FoundObject);
308 ObpReferenceNameInfo(ObjectHeader);
309
310 /* Reference the object being looked up */
311 ObReferenceObject(FoundObject);
312
313 /* Check if the directory was locked */
314 if (!Context->DirectoryLocked)
315 {
316 /* Release the lock */
318 }
319 }
320
321 /* Release any object previously looked up and replace it with the new one */
323 Context->Object = FoundObject;
324
325 /* Return the object we found */
326 return FoundObject;
327}
FORCEINLINE BOOLEAN ExConvertPushLockSharedToExclusive(IN PEX_PUSH_LOCK PushLock)
Definition: ex.h:1139
_In_ const STRING _In_ BOOLEAN CaseInsensitive
Definition: rtlfuncs.h:2359
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
FORCEINLINE VOID ObpAcquireDirectoryLockShared(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Locks a directory for shared access. Used for reading members of the directory object.
Definition: ob_x.h:185
FORCEINLINE VOID ObpReleaseLookupContextObject(IN POBP_LOOKUP_CONTEXT Context)
Definition: ob_x.h:292
FORCEINLINE VOID ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Unlocks a previously shared or exclusively locked directory.
Definition: ob_x.h:238
POBJECT_DIRECTORY NTAPI ObpGetShadowDirectory(IN POBJECT_DIRECTORY Directory)
Definition: obdir.c:110
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
UCHAR NameInfoOffset
Definition: obtypes.h:494
uint16_t * PWSTR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_In_ BOOLEAN _In_ ULONG _Out_ PULONG HashValue
Definition: rtlfuncs.h:2039

Referenced by ObCreateObjectType(), ObInitSystem(), ObpDeleteNameCheck(), ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

◆ ObpLookupObjectName()

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

Definition at line 446 of file obname.c.

457{
459 POBJECT_HEADER ObjectHeader;
460 UNICODE_STRING ComponentName, RemainingName;
461 BOOLEAN Reparse = FALSE, SymLink = FALSE;
463 POBJECT_DIRECTORY ReferencedDirectory = NULL, ReferencedParentDirectory = NULL;
464 KIRQL CalloutIrql;
465 OB_PARSE_METHOD ParseRoutine;
467 KPROCESSOR_MODE AccessCheckMode;
469 POBJECT_HEADER_NAME_INFO ObjectNameInfo;
470 ULONG MaxReparse = 30;
471 PDEVICE_MAP DeviceMap = NULL;
472 UNICODE_STRING LocalName;
473 PAGED_CODE();
475 "%s - Finding Object: %wZ. Expecting: %p\n",
478 InsertObject);
479
480 /* Initialize starting state */
481 ObpInitializeLookupContext(LookupContext);
482 *FoundObject = NULL;
484 Object = NULL;
485
486 /* Check if case-insensitivity is checked */
488 {
489 /* Check if the object type requests this */
490 if (!(ObjectType) || (ObjectType->TypeInfo.CaseInsensitive))
491 {
492 /* Add the flag to disable case sensitivity */
494 }
495 }
496
497 /* Check if this is a access checks are being forced */
498 AccessCheckMode = (Attributes & OBJ_FORCE_ACCESS_CHECK) ?
500
501 /* Check if we got a Root Directory */
502 if (RootHandle)
503 {
504 /* We did. Reference it */
506 0,
507 NULL,
510 NULL);
511 if (!NT_SUCCESS(Status)) return Status;
512
513 /* Get the header */
515
516 /* The name cannot start with a separator, unless this is a file */
517 if ((ObjectName->Buffer) &&
518 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR) &&
519 (ObjectHeader->Type != IoFileObjectType))
520 {
521 /* The syntax is bad, so fail this request */
524 }
525
526 /* Don't parse a Directory */
527 if (ObjectHeader->Type != ObpDirectoryObjectType)
528 {
529 /* Make sure the Object Type has a parse routine */
530 ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
531 if (!ParseRoutine)
532 {
533 /* We can't parse a name if we don't have a parse routine */
536 }
537
538 /* Set default parse count */
539 MaxReparse = 30;
540
541 /* Now parse */
542 while (TRUE)
543 {
544 /* Start with the full name */
546
547 /* Call the Parse Procedure */
548 ObpCalloutStart(&CalloutIrql);
549 Status = ParseRoutine(RootDirectory,
552 AccessCheckMode,
556 ParseContext,
557 SecurityQos,
558 &Object);
559 ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
560
561 /* Check for success or failure, so not reparse */
562 if ((Status != STATUS_REPARSE) &&
564 {
565 /* Check for failure */
566 if (!NT_SUCCESS(Status))
567 {
568 /* Parse routine might not have cleared this, do it */
569 Object = NULL;
570 }
571 else if (!Object)
572 {
573 /* Modify status to reflect failure inside Ob */
575 }
576
577 /* We're done, return the status and object */
578 *FoundObject = Object;
580 return Status;
581 }
582 else if ((!ObjectName->Length) ||
583 (!ObjectName->Buffer) ||
584 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
585 {
586 /* Reparsed to the root directory, so start over */
589
590 /* Don't use this anymore, since we're starting at root */
591 RootHandle = NULL;
592 goto ParseFromRoot;
593 }
594 else if (--MaxReparse)
595 {
596 /* Try reparsing again */
597 continue;
598 }
599 else
600 {
601 /* Reparsed too many times */
603
604 /* Return the object and normalized status */
605 *FoundObject = Object;
607 return Status;
608 }
609 }
610 }
611 else if (!(ObjectName->Length) || !(ObjectName->Buffer))
612 {
613 /* Just return the Root Directory if we didn't get a name */
615 0,
617 AccessMode);
619
620 /* Remove the first reference we added and return the object */
622 *FoundObject = Object;
623 return Status;
624 }
625
626 LocalName = *ObjectName;
627 }
628 else
629 {
630 /* We did not get a Root Directory, so use the root */
632
633 /* It must start with a path separator */
634 if (!(ObjectName->Length) ||
635 !(ObjectName->Buffer) ||
636 (ObjectName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR))
637 {
638 /* This name is invalid, so fail */
640 }
641
642 /* Check if the name is only the path separator */
643 if (ObjectName->Length == sizeof(OBJ_NAME_PATH_SEPARATOR))
644 {
645 /* So the caller only wants the root directory; do we have one? */
646 if (!RootDirectory)
647 {
648 /* This must be the first time we're creating it... right? */
649 if (InsertObject)
650 {
651 /* Yes, so return it to ObInsert so that it can create it */
652 Status = ObReferenceObjectByPointer(InsertObject,
653 0,
655 AccessMode);
656 if (NT_SUCCESS(Status)) *FoundObject = InsertObject;
657 return Status;
658 }
659 else
660 {
661 /* This should never really happen */
662 ASSERT(FALSE);
664 }
665 }
666 else
667 {
668 /* We do have the root directory, so just return it */
670 0,
672 AccessMode);
673 if (NT_SUCCESS(Status)) *FoundObject = RootDirectory;
674 return Status;
675 }
676 }
677 else
678 {
679ParseFromRoot:
680 LocalName = *ObjectName;
681
682 /* Deference the device map if we already have one */
683 if (DeviceMap != NULL)
684 {
685 ObfDereferenceDeviceMap(DeviceMap);
686 DeviceMap = NULL;
687 }
688
689 /* Check if this is a possible DOS name */
690 if (!((ULONG_PTR)(ObjectName->Buffer) & 7))
691 {
692 /*
693 * This could be one. Does it match the prefix?
694 * Note that as an optimization, the match is done as 64-bit
695 * compare since the prefix is "\??\" which is exactly 8 bytes.
696 *
697 * In the second branch, we test for "\??" which is also valid.
698 * This time, we use a 32-bit compare followed by a Unicode
699 * character compare (16-bit), since the sum is 6 bytes.
700 */
701 if ((ObjectName->Length >= ObpDosDevicesShortName.Length) &&
702 (*(PULONGLONG)(ObjectName->Buffer) ==
704 {
705 DeviceMap = ObpReferenceDeviceMap();
706 /* We have a local mapping, drop the ?? prefix */
707 if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
708 {
711 LocalName.Buffer += (ObpDosDevicesShortName.Length / sizeof(WCHAR));
712
713 /* We'll browse that local directory */
714 Directory = DeviceMap->DosDevicesDirectory;
715 }
716 }
717 else if ((ObjectName->Length == ObpDosDevicesShortName.Length -
718 sizeof(WCHAR)) &&
719 (*(PULONG)(ObjectName->Buffer) ==
721 (*((PWCHAR)(ObjectName->Buffer) + 2) ==
723 {
724 DeviceMap = ObpReferenceDeviceMap();
725
726 /* Caller is looking for the directory itself */
727 if (DeviceMap != NULL && DeviceMap->DosDevicesDirectory != NULL)
728 {
730 0,
732 AccessMode);
733 if (NT_SUCCESS(Status))
734 {
735 *FoundObject = DeviceMap->DosDevicesDirectory;
736 }
737
738 ObfDereferenceDeviceMap(DeviceMap);
739 return Status;
740 }
741 }
742 }
743 }
744 }
745
746 /* Check if we were reparsing a symbolic link */
747 if (!SymLink)
748 {
749 /* Allow reparse */
750 Reparse = TRUE;
751 MaxReparse = 30;
752 }
753
754 /* Reparse */
755 while (Reparse && MaxReparse)
756 {
757 /* Get the name */
758 RemainingName = LocalName;
759
760 /* Disable reparsing again */
761 Reparse = FALSE;
762
763 /* Start parse loop */
764 while (TRUE)
765 {
766 /* Clear object */
767 Object = NULL;
768
769 /* Check if the name starts with a path separator */
770 if ((RemainingName.Length) &&
772 {
773 /* Skip the path separator */
774 RemainingName.Buffer++;
775 RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
776 }
777
778 /* Find the next Part Name */
779 ComponentName = RemainingName;
780 while (RemainingName.Length)
781 {
782 /* Break if we found the \ ending */
783 if (RemainingName.Buffer[0] == OBJ_NAME_PATH_SEPARATOR) break;
784
785 /* Move on */
786 RemainingName.Buffer++;
787 RemainingName.Length -= sizeof(OBJ_NAME_PATH_SEPARATOR);
788 }
789
790 /* Get its size and make sure it's valid */
791 ComponentName.Length -= RemainingName.Length;
792 if (!ComponentName.Length)
793 {
794 /* Invalid size, fail */
796 break;
797 }
798
799 /* Check if we're in the root */
801
802 /* Check if this is a user-mode call that needs to traverse */
803 if ((AccessCheckMode != KernelMode) &&
805 {
806 /* We shouldn't have referenced a directory yet */
807 ASSERT(ReferencedDirectory == NULL);
808
809 /* Reference the directory */
811 ReferencedDirectory = Directory;
812
813 /* Check if we have a parent directory */
814 if (ParentDirectory)
815 {
816 /* Check for traverse access */
820 FALSE,
821 AccessCheckMode,
822 &Status))
823 {
824 /* We don't have it, fail */
825 break;
826 }
827 }
828 }
829
830 /* Check if we don't have a remaining name yet */
831 if (!RemainingName.Length)
832 {
833 /* Check if we don't have a referenced directory yet */
834 if (!ReferencedDirectory)
835 {
836 /* Reference it */
838 ReferencedDirectory = Directory;
839 }
840
841 /* Check if we are inserting an object */
842 if (InsertObject)
843 {
844 /* Lock the lookup context */
846 }
847 }
848
849 /* Do the lookup */
851 &ComponentName,
853 InsertObject ? FALSE : TRUE,
854 LookupContext);
855 if (!Object)
856 {
857 /* We didn't find it... do we still have a path? */
858 if (RemainingName.Length)
859 {
860 /* Then tell the caller the path wasn't found */
862 break;
863 }
864 else if (!InsertObject)
865 {
866 /* Otherwise, we have a path, but the name isn't valid */
868 break;
869 }
870
871 /* Check create access for the object */
877 &ComponentName,
878 FALSE,
879 AccessCheckMode,
880 &Status))
881 {
882 /* We don't have create access, fail */
883 break;
884 }
885
886 /* Get the object header */
887 ObjectHeader = OBJECT_TO_OBJECT_HEADER(InsertObject);
888
889 /*
890 * Deny object creation if:
891 * That's a section object or a symbolic link
892 * Which isn't in the same section that root directory
893 * That doesn't have the SeCreateGlobalPrivilege
894 * And that is not a known unsecure name
895 */
896 if (RootDirectory->SessionId != -1)
897 {
898 if (ObjectHeader->Type == MmSectionObjectType ||
899 ObjectHeader->Type == ObpSymbolicLinkObjectType)
900 {
901 if (RootDirectory->SessionId != PsGetCurrentProcessSessionId() &&
904 {
906 break;
907 }
908 }
909 }
910
911 /* Create Object Name */
913 ComponentName.Length,
915 if (!(NewName) ||
917 LookupContext,
918 ObjectHeader)))
919 {
920 /* Either couldn't allocate the name, or insert failed */
922
923 /* Fail due to memory reasons */
925 break;
926 }
927
928 /* Reference newly to be inserted object */
929 ObReferenceObject(InsertObject);
930
931 /* Get the name information */
932 ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
933
934 /* Reference the directory */
936
937 /* Copy the Name */
939 ComponentName.Buffer,
940 ComponentName.Length);
941
942 /* Check if we had an old name */
943 if (ObjectNameInfo->Name.Buffer)
944 {
945 /* Free it */
946 ExFreePoolWithTag(ObjectNameInfo->Name.Buffer, OB_NAME_TAG);
947 }
948
949 /* Write new one */
950 ObjectNameInfo->Name.Buffer = NewName;
951 ObjectNameInfo->Name.Length = ComponentName.Length;
952 ObjectNameInfo->Name.MaximumLength = ComponentName.Length;
953
954 /* Return Status and the Expected Object */
956 Object = InsertObject;
957
958 /* Get out of here */
959 break;
960 }
961
962ReparseObject:
963 /* We found it, so now get its header */
964 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
965
966 /*
967 * Check for a parse Procedure, but don't bother to parse for an insert
968 * unless it's a Symbolic Link, in which case we MUST parse
969 */
970 ParseRoutine = ObjectHeader->Type->TypeInfo.ParseProcedure;
971 if ((ParseRoutine) &&
972 (!(InsertObject) || (ParseRoutine == ObpParseSymbolicLink)))
973 {
974 /* Use the Root Directory next time */
975 Directory = NULL;
976
977 /* Increment the pointer count */
978 InterlockedExchangeAddSizeT(&ObjectHeader->PointerCount, 1);
979
980 /* Cleanup from the first lookup */
981 ObpReleaseLookupContext(LookupContext);
982
983 /* Check if we have a referenced directory */
984 if (ReferencedDirectory)
985 {
986 /* We do, dereference it */
987 ObDereferenceObject(ReferencedDirectory);
988 ReferencedDirectory = NULL;
989 }
990
991 /* Check if we have a referenced parent directory */
992 if (ReferencedParentDirectory)
993 {
994 /* We do, dereference it */
995 ObDereferenceObject(ReferencedParentDirectory);
996 ReferencedParentDirectory = NULL;
997 }
998
999 /* Call the Parse Procedure */
1000 ObpCalloutStart(&CalloutIrql);
1001 Status = ParseRoutine(Object,
1002 ObjectType,
1004 AccessCheckMode,
1005 Attributes,
1006 ObjectName,
1008 ParseContext,
1009 SecurityQos,
1010 &Object);
1011 ObpCalloutEnd(CalloutIrql, "Parse", ObjectHeader->Type, Object);
1012
1013 /* Remove our extra reference */
1014 ObDereferenceObject(&ObjectHeader->Body);
1015
1016 /* Check if we have to reparse */
1017 if ((Status == STATUS_REPARSE) ||
1019 {
1020 /* Reparse again */
1021 Reparse = TRUE;
1022 --MaxReparse;
1023 if (MaxReparse == 0)
1024 {
1025 Object = NULL;
1026 break;
1027 }
1028
1029 /* Start over from root if we got sent back there */
1030 if ((Status == STATUS_REPARSE_OBJECT) ||
1031 (ObjectName->Buffer[0] == OBJ_NAME_PATH_SEPARATOR))
1032 {
1033 /* Check if we got a root directory */
1034 if (RootHandle)
1035 {
1036 /* Stop using it, because we have a new directory now */
1038 RootHandle = NULL;
1039 }
1040
1041 /* Start at Root */
1044
1045 /* Check for reparse status */
1047 {
1048 /* Don't reparse again */
1049 Reparse = FALSE;
1050
1051 /* Did we actually get an object to which to reparse? */
1052 if (!Object)
1053 {
1054 /* We didn't, so set a failure status */
1056 }
1057 else
1058 {
1059 /* We did, so we're free to parse the new object */
1060 goto ReparseObject;
1061 }
1062 }
1063 else
1064 {
1065 /* This is a symbolic link */
1066 SymLink = TRUE;
1067 goto ParseFromRoot;
1068 }
1069 }
1071 {
1072 /* We got STATUS_REPARSE but are at the Root Directory */
1073 Object = NULL;
1075 Reparse = FALSE;
1076 }
1077 }
1078 else if (!NT_SUCCESS(Status))
1079 {
1080 /* Total failure */
1081 Object = NULL;
1082 }
1083 else if (!Object)
1084 {
1085 /* We didn't reparse but we didn't find the Object Either */
1087 }
1088
1089 /* Break out of the loop */
1090 break;
1091 }
1092 else
1093 {
1094 /* No parse routine...do we still have a remaining name? */
1095 if (!RemainingName.Length)
1096 {
1097 /* Are we creating an object? */
1098 if (!InsertObject)
1099 {
1100 /* Check if this is a user-mode call that needs to traverse */
1101 if ((AccessCheckMode != KernelMode) &&
1103 {
1104 /* Check if we can get it */
1108 FALSE,
1109 AccessCheckMode,
1110 &Status))
1111 {
1112 /* We don't have access, fail */
1113 Object = NULL;
1114 break;
1115 }
1116 }
1117
1118 /* Reference the Object */
1120 0,
1121 ObjectType,
1122 AccessMode);
1123 if (!NT_SUCCESS(Status)) Object = NULL;
1124 }
1125
1126 /* And get out of the reparse loop */
1127 break;
1128 }
1129 else
1130 {
1131 /* We still have a name; check if this is a directory object */
1132 if (ObjectHeader->Type == ObpDirectoryObjectType)
1133 {
1134 /* Check if we have a referenced parent directory */
1135 if (ReferencedParentDirectory)
1136 {
1137 /* Dereference it */
1138 ObDereferenceObject(ReferencedParentDirectory);
1139 }
1140
1141 /* Restart the lookup from this directory */
1142 ReferencedParentDirectory = ReferencedDirectory;
1144 Directory = Object;
1145 ReferencedDirectory = NULL;
1146 }
1147 else
1148 {
1149 /* We still have a name, but no parse routine for it */
1151 Object = NULL;
1152 break;
1153 }
1154 }
1155 }
1156 }
1157 }
1158
1159 /* Check if we failed */
1160 if (!NT_SUCCESS(Status))
1161 {
1162 /* Cleanup after lookup */
1163 ObpReleaseLookupContext(LookupContext);
1164 }
1165
1166 /* Check if we have a device map and dereference it if so */
1167 if (DeviceMap) ObfDereferenceDeviceMap(DeviceMap);
1168
1169 /* Check if we have a referenced directory and dereference it if so */
1170 if (ReferencedDirectory) ObDereferenceObject(ReferencedDirectory);
1171
1172 /* Check if we have a referenced parent directory */
1173 if (ReferencedParentDirectory)
1174 {
1175 /* We do, dereference it */
1176 ObDereferenceObject(ReferencedParentDirectory);
1177 }
1178
1179 /* Set the found object and check if we got one */
1180 *FoundObject = Object;
1181 if (!Object)
1182 {
1183 /* Nothing was found. Did we reparse or get success? */
1184 if ((Status == STATUS_REPARSE) || (NT_SUCCESS(Status)))
1185 {
1186 /* Set correct failure */
1188 }
1189 }
1190
1191 /* Check if we had a root directory */
1192 if (RootHandle) ObDereferenceObject(RootDirectory);
1193
1194 /* Return status to caller */
1196 "%s - Found Object: %p. Expected: %p\n",
1198 *FoundObject,
1199 InsertObject);
1200 return Status;
1201}
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
static const LUID SeCreateGlobalPrivilege
Definition: authpackage.c:168
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
_Inout_ PFCB _Inout_ PUNICODE_STRING RemainingName
Definition: cdprocs.h:802
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
IN PDCB ParentDirectory
Definition: fatprocs.h:698
#define OBJ_FORCE_ACCESS_CHECK
Definition: winternl.h:232
POBJECT_TYPE IoFileObjectType
Definition: iomgr.c:36
NTSTATUS(NTAPI * OB_PARSE_METHOD)(_In_ PVOID ParseObject, _In_ PVOID ObjectType, _Inout_ PACCESS_STATE AccessState, _In_ KPROCESSOR_MODE AccessMode, _In_ ULONG Attributes, _Inout_ PUNICODE_STRING CompleteName, _Inout_ PUNICODE_STRING RemainingName, _Inout_opt_ PVOID Context, _In_opt_ PSECURITY_QUALITY_OF_SERVICE SecurityQos, _Out_ PVOID *Object)
Definition: obtypes.h:215
#define DIRECTORY_CREATE_OBJECT
Definition: nt_native.h:1256
#define DIRECTORY_TRAVERSE
Definition: nt_native.h:1255
#define DIRECTORY_CREATE_SUBDIRECTORY
Definition: nt_native.h:1257
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:383
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_REPARSE
Definition: ntstatus.h:83
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_REPARSE_OBJECT
Definition: ntstatus.h:102
#define STATUS_OBJECT_TYPE_MISMATCH
Definition: ntstatus.h:273
PDEVICE_MAP NTAPI ObpReferenceDeviceMap(VOID)
Definition: devicemap.c:325
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)
Definition: obsecure.c:267
#define OB_NAMESPACE_DEBUG
Definition: ob.h:18
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)
Definition: obsecure.c:203
VOID FASTCALL ObfDereferenceDeviceMap(IN PDEVICE_MAP DeviceMap)
Definition: devicemap.c:477
BOOLEAN NTAPI ObpIsUnsecureName(IN PUNICODE_STRING ObjectName, IN BOOLEAN CaseInSensitive)
Definition: obname.c:396
ALIGNEDNAME ObpDosDevicesShortNamePrefix
Definition: obname.c:23
BOOLEAN ObpCaseInsensitive
Definition: obname.c:18
UNICODE_STRING ObpDosDevicesShortName
Definition: obname.c:25
POBJECT_DIRECTORY ObpRootDirectoryObject
Definition: obname.c:19
NTSTATUS NTAPI ObReferenceObjectByPointer(IN PVOID Object, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode)
Definition: obref.c:381
POBJECT_TYPE MmSectionObjectType
Definition: section.c:194
POBJECT_DIRECTORY DosDevicesDirectory
Definition: obtypes.h:525
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
$ULONG LowPart
Definition: ntbasedef.h:569
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
$ULONG HighPart
Definition: ntbasedef.h:570
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define OB_NAME_TAG
Definition: tag.h:118
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
ULARGE_INTEGER Alignment
Definition: ob.h:154
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define TOKEN_HAS_TRAVERSE_PRIVILEGE
Definition: setypes.h:1178
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203

Referenced by ObInsertObject(), ObOpenObjectByName(), and ObReferenceObjectByName().

◆ ObpParseSymbolicLink()

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 
)

Definition at line 431 of file oblink.c.

441{
442 POBJECT_SYMBOLIC_LINK SymlinkObject = (POBJECT_SYMBOLIC_LINK)ParsedObject;
443 PUNICODE_STRING TargetPath;
444 PWSTR NewTargetPath;
445 ULONG LengthUsed, MaximumLength, TempLength;
447 PAGED_CODE();
448
449 /* Assume failure */
450 *NextObject = NULL;
451
452 /* Check if we're out of name to parse */
453 if (!RemainingName->Length)
454 {
455 /* Check if we got an object type */
456 if (ObjectType)
457 {
458 /* Reference the object only */
459 Status = ObReferenceObjectByPointer(ParsedObject,
460 0,
462 AccessMode);
463 if (NT_SUCCESS(Status))
464 {
465 /* Return it */
466 *NextObject = ParsedObject;
467 }
468
470 {
471 /* Fail */
472 return Status;
473 }
474 }
475 }
476 else if (RemainingName->Buffer[0] != OBJ_NAME_PATH_SEPARATOR)
477 {
478 /* Symbolic links must start with a backslash */
480 }
481
482 /* Check if this symlink is bound to a specific object */
483 if (SymlinkObject->LinkTargetObject)
484 {
485 /* No name to reparse, directly reparse the object */
486 if (!SymlinkObject->LinkTargetRemaining.Length)
487 {
488 *NextObject = SymlinkObject->LinkTargetObject;
490 }
491
492 TempLength = SymlinkObject->LinkTargetRemaining.Length;
493 /* The target and remaining names aren't empty, so check for slashes */
494 if (SymlinkObject->LinkTargetRemaining.Buffer[TempLength / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR &&
496 {
497 /* Reduce the length by one to cut off the extra '\' */
498 TempLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
499 }
500
501 /* Calculate the new length */
502 LengthUsed = TempLength + RemainingName->Length;
503 LengthUsed += (sizeof(WCHAR) * (RemainingName->Buffer - FullPath->Buffer));
504
505 /* Check if it's not too much */
506 if (LengthUsed > 0xFFF0)
508
509 /* If FullPath is enough, use it */
510 if (FullPath->MaximumLength > LengthUsed)
511 {
512 /* Update remaining length if appropriate */
513 if (RemainingName->Length)
514 {
515 RtlMoveMemory((PVOID)((ULONG_PTR)RemainingName->Buffer + TempLength),
516 RemainingName->Buffer,
517 RemainingName->Length);
518 }
519
520 /* And move the target object name */
522 SymlinkObject->LinkTargetRemaining.Buffer,
523 TempLength);
524
525 /* Finally update the full path with what we parsed */
526 FullPath->Length += SymlinkObject->LinkTargetRemaining.Length;
527 RemainingName->Length += SymlinkObject->LinkTargetRemaining.Length;
528 RemainingName->MaximumLength += RemainingName->Length + sizeof(WCHAR);
529 FullPath->Buffer[FullPath->Length / sizeof(WCHAR)] = UNICODE_NULL;
530
531 /* And reparse */
532 *NextObject = SymlinkObject->LinkTargetObject;
534 }
535
536 /* FullPath is not enough, we'll have to reallocate */
537 MaximumLength = LengthUsed + sizeof(WCHAR);
538 NewTargetPath = ExAllocatePoolWithTag(NonPagedPool,
541 if (!NewTargetPath) return STATUS_INSUFFICIENT_RESOURCES;
542
543 /* Copy path begin */
544 RtlCopyMemory(NewTargetPath,
545 FullPath->Buffer,
546 sizeof(WCHAR) * (RemainingName->Buffer - FullPath->Buffer));
547
548 /* Copy path end (if any) */
549 if (RemainingName->Length)
550 {
551 RtlCopyMemory((PVOID)((ULONG_PTR)&NewTargetPath[RemainingName->Buffer - FullPath->Buffer] + TempLength),
552 RemainingName->Buffer,
553 RemainingName->Length);
554 }
555
556 /* And finish path with bound object */
557 RtlCopyMemory(&NewTargetPath[RemainingName->Buffer - FullPath->Buffer],
558 SymlinkObject->LinkTargetRemaining.Buffer,
559 TempLength);
560
561 /* Free old buffer */
562 ExFreePool(FullPath->Buffer);
563
564 /* Set new buffer in FullPath */
565 FullPath->Buffer = NewTargetPath;
566 FullPath->MaximumLength = MaximumLength;
567 FullPath->Length = LengthUsed;
568
569 /* Update remaining with what we handled */
570 RemainingName->Length = LengthUsed + (ULONG_PTR)NewTargetPath - (ULONG_PTR)&NewTargetPath[RemainingName->Buffer - FullPath->Buffer];
571 RemainingName->Buffer = &NewTargetPath[RemainingName->Buffer - FullPath->Buffer];
572 RemainingName->MaximumLength = RemainingName->Length + sizeof(WCHAR);
573
574 /* Reparse! */
575 *NextObject = SymlinkObject->LinkTargetObject;
577 }
578
579 /* Set the target path and length */
580 TargetPath = &SymlinkObject->LinkTarget;
581 TempLength = TargetPath->Length;
582
583 /*
584 * Strip off the extra trailing '\', if we don't do this we will end up
585 * adding a extra '\' between TargetPath and RemainingName
586 * causing caller's like ObpLookupObjectName() to fail.
587 */
588 if (TempLength && RemainingName->Length)
589 {
590 /* The target and remaining names aren't empty, so check for slashes */
591 if ((TargetPath->Buffer[TempLength / sizeof(WCHAR) - 1] ==
594 {
595 /* Reduce the length by one to cut off the extra '\' */
596 TempLength -= sizeof(OBJ_NAME_PATH_SEPARATOR);
597 }
598 }
599
600 /* Calculate the new length */
601 LengthUsed = TempLength + RemainingName->Length;
602
603 /* Check if it's not too much */
604 if (LengthUsed > 0xFFF0)
606
607 /* Optimization: check if the new name is shorter */
608 if (FullPath->MaximumLength <= LengthUsed)
609 {
610 /* It's not, allocate a new one */
611 MaximumLength = LengthUsed + sizeof(WCHAR);
612 NewTargetPath = ExAllocatePoolWithTag(NonPagedPool,
615 if (!NewTargetPath) return STATUS_INSUFFICIENT_RESOURCES;
616 }
617 else
618 {
619 /* It is! Reuse the name... */
620 MaximumLength = FullPath->MaximumLength;
621 NewTargetPath = FullPath->Buffer;
622 }
623
624 /* Make sure we have a length */
625 if (RemainingName->Length)
626 {
627 /* Copy the new path */
628 RtlMoveMemory((PVOID)((ULONG_PTR)NewTargetPath + TempLength),
629 RemainingName->Buffer,
630 RemainingName->Length);
631 }
632
633 /* Copy the target path and null-terminate it */
634 RtlCopyMemory(NewTargetPath, TargetPath->Buffer, TempLength);
635 NewTargetPath[LengthUsed / sizeof(WCHAR)] = UNICODE_NULL;
636
637 /* If the optimization didn't work, free the old buffer */
638 if (NewTargetPath != FullPath->Buffer) ExFreePool(FullPath->Buffer);
639
640 /* Update the path values */
641 FullPath->Length = (USHORT)LengthUsed;
642 FullPath->MaximumLength = (USHORT)MaximumLength;
643 FullPath->Buffer = NewTargetPath;
644
645 /* Tell the parse routine to start reparsing */
646 return STATUS_REPARSE;
647}
struct _OBJECT_SYMBOLIC_LINK * POBJECT_SYMBOLIC_LINK
#define UNICODE_NULL
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:498
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength

Referenced by ObInitSystem(), and ObpLookupObjectName().

◆ ObpReapObject()

VOID NTAPI ObpReapObject ( IN PVOID  Unused)

Definition at line 220 of file oblife.c.

221{
222 POBJECT_HEADER ReapObject, NextObject;
223
224 /* Start reaping */
225 do
226 {
227 /* Get the reap object */
229
230 /* Start deletion loop */
231 do
232 {
233 /* Get the next object */
234 NextObject = ReapObject->NextToFree;
235
236 /* Delete the object */
237 ObpDeleteObject(&ReapObject->Body, TRUE);
238
239 /* Move to the next one */
240 ReapObject = NextObject;
241 } while ((ReapObject) && (ReapObject != (PVOID)1));
242 } while ((ObpReaperList != (PVOID)1) ||
244}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define InterlockedCompareExchange
Definition: interlocked.h:104
volatile PVOID ObpReaperList
Definition: oblife.c:29
VOID NTAPI ObpDeleteObject(IN PVOID Object, IN BOOLEAN CalledFromWorkerThread)
Definition: oblife.c:147
volatile PVOID NextToFree
Definition: obtypes.h:491

Referenced by ObInitSystem().

◆ ObpReferenceDeviceMap()

PDEVICE_MAP NTAPI ObpReferenceDeviceMap ( VOID  )

Definition at line 325 of file devicemap.c.

326{
329 PTOKEN Token = NULL;
330 PDEVICE_MAP DeviceMap;
331 PETHREAD CurrentThread;
332 BOOLEAN LookingForSystem;
333 LUID SystemLuid = SYSTEM_LUID;
336
337 LookingForSystem = FALSE;
338
339 /* If LUID mapping is enable, try to get appropriate device map */
341 {
342 /* In case of impersonation, we've got a bit of work to do */
343 CurrentThread = PsGetCurrentThread();
344 if (CurrentThread->ActiveImpersonationInfo)
345 {
346 /* Get impersonation token */
347 Token = PsReferenceImpersonationToken(CurrentThread,
348 &CopyOnOpen,
351 /* Get logon LUID */
352 if (Token != NULL)
353 {
355 }
356 else
357 {
358 /* Force failure */
360 }
361
362 /* If we got logon LUID */
363 if (NT_SUCCESS(Status))
364 {
365 /*
366 * Check it's not system, system is easy to handle,
367 * we just need to return ObSystemDeviceMap
368 */
369 if (!RtlEqualLuid(&LogonId, &SystemLuid))
370 {
371 /* Ask Se for the device map */
372 Status = SeGetLogonIdDeviceMap(&LogonId, &DeviceMap);
373 if (NT_SUCCESS(Status))
374 {
375 /* Acquire the device map lock */
377
378 /* Reference the device map if any */
379 if (DeviceMap != NULL)
380 {
381 ++DeviceMap->ReferenceCount;
382 }
383
384 /* Release the device map lock */
386
387 /* If we got the device map, we're done! */
388 if (DeviceMap != NULL)
389 {
391
392 return DeviceMap;
393 }
394 }
395 }
396 else
397 {
398 LookingForSystem = TRUE;
399 }
400 }
401 }
402
403 /*
404 * Fall back case of the LUID mapping, make sure there's a
405 * a device map attached to the current process
406 */
407 if (PsGetCurrentProcess()->DeviceMap == NULL &&
409 {
410 /* We may have failed after we got impersonation token */
411 if (Token != NULL)
412 {
414 }
415
416 return NULL;
417 }
418 }
419
420 /* Acquire the device map lock */
422
423 /* If we're looking for system map, use it */
424 if (LookingForSystem)
425 {
426 DeviceMap = ObSystemDeviceMap;
427 }
428 /* Otherwise, use current process device map */
429 else
430 {
431 DeviceMap = PsGetCurrentProcess()->DeviceMap;
432 }
433
434 /* If we got one, reference it */
435 if (DeviceMap != NULL)
436 {
437 ++DeviceMap->ReferenceCount;
438 }
439
440 /* Release the device map lock */
442
443 /* We may have impersonation token (if we failed in impersonation branch) */
444 if (Token != NULL)
445 {
447 }
448
449 /* Return the potentially found device map */
450 return DeviceMap;
451}
NTSTATUS NTAPI ObpSetCurrentProcessDeviceMap(VOID)
Definition: devicemap.c:248
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN EffectiveOnly
Definition: sefuncs.h:410
_IRQL_requires_same_ _In_ PLSA_STRING _In_ SECURITY_LOGON_TYPE _In_ ULONG _In_ ULONG _In_opt_ PTOKEN_GROUPS _In_ PTOKEN_SOURCE _Out_ PVOID _Out_ PULONG _Inout_ PLUID LogonId
NTSTATUS NTAPI SeGetLogonIdDeviceMap(_In_ PLUID LogonId, _Out_ PDEVICE_MAP *DeviceMap)
Retrieves the DOS device map from a logon session.
Definition: srm.c:1347
PACCESS_TOKEN NTAPI PsReferenceImpersonationToken(IN PETHREAD Thread, OUT PBOOLEAN CopyOnOpen, OUT PBOOLEAN EffectiveOnly, OUT PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: security.c:871
NTSTATUS NTAPI SeQueryAuthenticationIdToken(_In_ PACCESS_TOKEN Token, _Out_ PLUID LogonId)
Queries the authentication ID of an access token.
Definition: token.c:2036
#define STATUS_NO_TOKEN
Definition: ntstatus.h:360
ULONG ActiveImpersonationInfo
Definition: pstypes.h:1181
_Out_ PBOOLEAN CopyOnOpen
Definition: psfuncs.h:154
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156
#define RtlEqualLuid(Luid1, Luid2)
Definition: rtlfuncs.h:301
#define SYSTEM_LUID
Definition: setypes.h:700

Referenced by ObpLookupObjectName(), and ObQueryDeviceMapInformation().

◆ ObpReferenceSecurityDescriptor()

PSECURITY_DESCRIPTOR NTAPI ObpReferenceSecurityDescriptor ( IN POBJECT_HEADER  ObjectHeader)

Definition at line 181 of file obsdcach.c.

182{
185 PEX_FAST_REF FastRef;
186 EX_FAST_REF OldValue;
188
189 /* Acquire a reference to the security descriptor */
190 FastRef = (PEX_FAST_REF)&ObjectHeader->SecurityDescriptor;
191 OldValue = ExAcquireFastReference(FastRef);
192
193 /* Get the descriptor and reference count */
195 Count = ExGetCountFastReference(OldValue);
196
197 /* Check if there's no descriptor or if there's still cached references */
198 if ((Count >= 1) || !(SecurityDescriptor))
199 {
200 /* Check if this is the last reference */
201 if (Count == 1)
202 {
203 /* Add the extra references that we'll take */
206
207 /* Now insert them */
209 {
210 /* Undo the references since we failed */
213 }
214 }
215
216 /* Return the SD */
217 return SecurityDescriptor;
218 }
219
220 /* Lock the object */
221 ObpAcquireObjectLockShared(ObjectHeader);
222
223 /* Get the object header */
226
227 /* Do the reference */
229
230 /* Release the lock and return */
231 ObpReleaseObjectLock(ObjectHeader);
232 return SecurityDescriptor;
233}
#define InterlockedIncrement
Definition: armddk.h:53
#define ObpGetHeaderForSd(x)
Definition: ob.h:97
FORCEINLINE VOID ObpAcquireObjectLockShared(IN POBJECT_HEADER ObjectHeader)
Definition: ob_x.h:66

Referenced by ObGetObjectSecurity(), ObQuerySecurityDescriptorInfo(), and ObSetSecurityDescriptorInfo().

◆ ObpSetHandleAttributes()

BOOLEAN NTAPI ObpSetHandleAttributes ( IN OUT PHANDLE_TABLE_ENTRY  HandleTableEntry,
IN ULONG_PTR  Context 
)

Definition at line 1859 of file obhandle.c.

1861{
1863 POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry);
1864
1865 /* Check if making the handle inheritable */
1866 if (SetHandleInfo->Information.Inherit)
1867 {
1868 /* Check if inheriting is not supported for this object */
1869 if (ObjectHeader->Type->TypeInfo.InvalidAttributes & OBJ_INHERIT)
1870 {
1871 /* Fail without changing anything */
1872 return FALSE;
1873 }
1874
1875 /* Set the flag */
1876 HandleTableEntry->ObAttributes |= OBJ_INHERIT;
1877 }
1878 else
1879 {
1880 /* Otherwise this implies we're removing the flag */
1881 HandleTableEntry->ObAttributes &= ~OBJ_INHERIT;
1882 }
1883
1884 /* Check if making the handle protected */
1885 if (SetHandleInfo->Information.ProtectFromClose)
1886 {
1887 /* Set the flag */
1888 HandleTableEntry->GrantedAccess |= ObpAccessProtectCloseBit;
1889 }
1890 else
1891 {
1892 /* Otherwise, remove it */
1893 HandleTableEntry->GrantedAccess &= ~ObpAccessProtectCloseBit;
1894 }
1895
1896 /* Return success */
1897 return TRUE;
1898}
#define ObpGetHandleObject(x)
Definition: ob.h:91
OBJECT_HANDLE_ATTRIBUTE_INFORMATION Information
Definition: ob.h:112

Referenced by NtSetInformationObject(), and ObSetHandleAttributes().

◆ ObpSetPermanentObject()

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

Definition at line 266 of file oblife.c.

268{
269 POBJECT_HEADER ObjectHeader;
270
271 /* Get the header */
272 ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody);
273
274 /* Acquire object lock */
275 ObpAcquireObjectLock(ObjectHeader);
276
277 /* Check what we're doing to it */
278 if (Permanent)
279 {
280 /* Set it to permanent */
281 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
282
283 /* Release the lock */
284 ObpReleaseObjectLock(ObjectHeader);
285 }
286 else
287 {
288 /* Remove the flag */
289 ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
290
291 /* Release the lock */
292 ObpReleaseObjectLock(ObjectHeader);
293
294 /* Check if we should delete the object now */
295 ObpDeleteNameCheck(ObjectBody);
296 }
297}
VOID NTAPI ObpDeleteNameCheck(IN PVOID Object)
Definition: obname.c:301

Referenced by NtMakePermanentObject(), NtMakeTemporaryObject(), and ObMakeTemporaryObject().

◆ ObQueryDeviceMapInformation()

NTSTATUS NTAPI ObQueryDeviceMapInformation ( _In_opt_ PEPROCESS  Process,
_Out_ PPROCESS_DEVICEMAP_INFORMATION  DeviceMapInfo,
_In_ ULONG  Flags 
)

Definition at line 539 of file devicemap.c.

543{
544 PDEVICE_MAP DeviceMap = NULL, GlobalDeviceMap;
545 BOOLEAN Dereference;
547 ULONG BitMask, i;
548 BOOLEAN ReturnAny;
550
551 /* Validate flags */
553 {
555 }
556
557 Dereference = FALSE;
558 /* Do we want to return anything? */
560
561 /* If LUID mappings are enabled... */
563 {
564 /* Check for process parameter validness */
566 {
568 }
569
570 /* And get the device map */
571 DeviceMap = ObpReferenceDeviceMap();
572 }
573
574 /* Acquire the device map lock */
576
577 /*
578 * If we had a device map, if because of LUID mappings,
579 * we'll have to dereference it afterwards
580 */
581 if (DeviceMap != NULL)
582 {
583 Dereference = TRUE;
584 }
585 else
586 {
587 /* Get the process device map or the system device map */
588 DeviceMap = (Process != NULL) ? Process->DeviceMap : ObSystemDeviceMap;
589 }
590
591 /* Fail if no device map */
592 if (DeviceMap == NULL)
593 {
595 return STATUS_END_OF_FILE;
596 }
597
598 /* At that point, assume success */
600
601 /* Try to get the global device map if any */
602 GlobalDeviceMap = DeviceMap;
603 if (DeviceMap->GlobalDosDevicesDirectory != NULL)
604 {
605 if (DeviceMap->GlobalDosDevicesDirectory->DeviceMap != NULL)
606 {
607 GlobalDeviceMap = DeviceMap->GlobalDosDevicesDirectory->DeviceMap;
608 }
609 }
610
611 /* Now, setup our device map info, especially drive types */
612 MapInfo.Query.DriveMap = DeviceMap->DriveMap;
613 /* Browse every device */
614 for (i = 0, BitMask = 1; i < 32; ++i, BitMask *= 2)
615 {
616 /* Set the type given current device map */
617 MapInfo.Query.DriveType[i] = DeviceMap->DriveType[i];
618
619 /*
620 * If device is not existing and we're asked to return
621 * more than just LUID mapped, get the entry
622 * from global device map if not remote
623 */
624 if (!(MapInfo.Query.DriveMap & BitMask) && ReturnAny)
625 {
626 if (ObpLUIDDeviceMapsEnabled != 0 ||
627 (GlobalDeviceMap->DriveType[i] != DOSDEVICE_DRIVE_REMOTE &&
628 GlobalDeviceMap->DriveType[i] != DOSDEVICE_DRIVE_CALCULATE))
629 {
630 MapInfo.Query.DriveType[i] = GlobalDeviceMap->DriveType[i];
631 MapInfo.Query.DriveMap |= BitMask & GlobalDeviceMap->DriveMap;
632 }
633 }
634 }
635
636 /* Release the device map lock */
638
639 /* Dereference LUID device map */
640 if (Dereference)
641 {
642 ObfDereferenceDeviceMap(DeviceMap);
643 }
644
645 /* Copy back data */
647 {
648 RtlCopyMemory(DeviceMapInfo, &MapInfo, sizeof(PROCESS_DEVICEMAP_INFORMATION));
649 }
651 {
653 }
654 _SEH2_END;
655
656 return Status;
657}
PDEVICE_MAP NTAPI ObpReferenceDeviceMap(VOID)
Definition: devicemap.c:325
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define PROCESS_LUID_DOSDEVICES_ONLY
Definition: pstypes.h:228
#define DOSDEVICE_DRIVE_CALCULATE
Definition: obtypes.h:164
#define DOSDEVICE_DRIVE_REMOTE
Definition: obtypes.h:167
#define STATUS_END_OF_FILE
Definition: shellext.h:67
UCHAR DriveType[32]
Definition: obtypes.h:529
POBJECT_DIRECTORY GlobalDosDevicesDirectory
Definition: obtypes.h:526
ULONG DriveMap
Definition: obtypes.h:528
struct _PROCESS_DEVICEMAP_INFORMATION::@4170::@4172 Query
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by NtQueryInformationProcess().

◆ ObQuerySecurityDescriptorInfo()

NTSTATUS NTAPI ObQuerySecurityDescriptorInfo ( IN PVOID  Object,
IN PSECURITY_INFORMATION  SecurityInformation,
OUT PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN OUT PULONG  Length,
IN PSECURITY_DESCRIPTOR OutputSecurityDescriptor 
)

Definition at line 85 of file obsecure.c.

90{
91 POBJECT_HEADER ObjectHeader;
93 PSECURITY_DESCRIPTOR ObjectSd;
94 PAGED_CODE();
95
96 /* Get the object header */
97 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
98
99 /* Get the SD */
100 ObjectSd = ObpReferenceSecurityDescriptor(ObjectHeader);
101
102 /* Query the information */
105 Length,
106 &ObjectSd);
107
108 /* Check if we have an object SD and dereference it, if so */
109 if (ObjectSd) ObDereferenceSecurityDescriptor(ObjectSd, 1);
110
111 /* Return status */
112 return Status;
113}
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PSECURITY_DESCRIPTOR NTAPI ObpReferenceSecurityDescriptor(IN POBJECT_HEADER ObjectHeader)
Definition: obsdcach.c:181
NTKERNELAPI NTSTATUS NTAPI SeQuerySecurityDescriptorInfo(_In_ PSECURITY_INFORMATION SecurityInformation, _Out_writes_bytes_(*Length) PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PULONG Length, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor)

Referenced by SeDefaultObjectMethod(), and WmipSecurityMethod().

◆ ObReferenceFileObjectForWrite()

NTSTATUS NTAPI ObReferenceFileObjectForWrite ( IN HANDLE  Handle,
IN KPROCESSOR_MODE  AccessMode,
OUT PFILE_OBJECT FileObject,
OUT POBJECT_HANDLE_INFORMATION  HandleInformation 
)

Definition at line 200 of file obref.c.

204{
207 POBJECT_HEADER ObjectHeader;
208 PHANDLE_TABLE_ENTRY HandleEntry;
210
211 /* Assume failure */
212 *FileObject = NULL;
213
214 /* Check if this is a special handle */
215 if (HandleToLong(Handle) < 0)
216 {
217 /* Make sure we have a valid kernel handle */
219 {
221 }
222
223 /* Use the kernel handle table and get the actual handle value */
226 }
227 else
228 {
229 /* Otherwise use this process's handle table */
230 HandleTable = PsGetCurrentProcess()->ObjectTable;
231 }
232
235
236 /* Get the handle entry */
238 if (HandleEntry)
239 {
240 /* Get the object header and validate the type*/
241 ObjectHeader = ObpGetHandleObject(HandleEntry);
242
243 /* Get the desired access from the file object */
245 &DesiredAccess)))
246 {
248 }
249 else
250 {
251 /* Extract the granted access from the handle entry */
253 {
254 /* FIXME: Translate granted access */
255 GrantedAccess = HandleEntry->GrantedAccess;
256 }
257 else
258 {
259 GrantedAccess = HandleEntry->GrantedAccess & ~ObpAccessProtectCloseBit;
260 }
261
262 /* FIXME: Get handle information for audit */
263
264 HandleInformation->GrantedAccess = GrantedAccess;
265
266 /* FIXME: Get handle attributes */
267 HandleInformation->HandleAttributes = 0;
268
269 /* Do granted and desired access match? */
271 {
272 /* FIXME: Audit access if required */
273
274 /* Reference the object directly since we have its header */
276
277 /* Unlock the handle */
280
281 *FileObject = (PFILE_OBJECT)&ObjectHeader->Body;
282
283 /* Return success */
285 return STATUS_SUCCESS;
286 }
287
288 /* No match, deny write access */
290
292 }
293 }
294 else
295 {
297 }
298
299 /* Return failure status */
301 return Status;
302}
#define HandleToLong(h)
Definition: basetsd.h:80
#define FLG_KERNEL_STACK_TRACE_DB
Definition: pstypes.h:68
#define InterlockedIncrementSizeT(a)
Definition: interlocked.h:220
PHANDLE_TABLE_ENTRY NTAPI ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle)
Definition: handle.c:1046
VOID NTAPI ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, IN PHANDLE_TABLE_ENTRY HandleTableEntry)
Definition: handle.c:923
ULONG NtGlobalFlag
Definition: init.c:54
NTSTATUS NTAPI IoComputeDesiredAccessFileObject(IN PFILE_OBJECT FileObject, IN PACCESS_MASK DesiredAccess)
Definition: util.c:26
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
* PFILE_OBJECT
Definition: iotypes.h:1998

Referenced by NtWriteFile().

◆ ObReferenceObjectEx()

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

Definition at line 77 of file obref.c.

79{
80 /* Increment the reference count and return the count now */
82 PointerCount,
83 Count) + Count;
84}

Referenced by ObFastReferenceObject(), ObFastReplaceObject(), ObInitializeFastReference(), and PspCreateThread().

◆ ObReferenceObjectSafe()

BOOLEAN FASTCALL ObReferenceObjectSafe ( IN PVOID  Object)

Definition at line 22 of file obref.c.

23{
24 POBJECT_HEADER ObjectHeader;
25 LONG_PTR OldValue, NewValue;
26
27 /* Get the object header */
28 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
29
30 /* Get the current reference count and fail if it's zero */
31 OldValue = ObjectHeader->PointerCount;
32 if (!OldValue) return FALSE;
33
34 /* Start reference loop */
35 do
36 {
37 /* Increase the reference count */
38 NewValue = InterlockedCompareExchangeSizeT(&ObjectHeader->PointerCount,
39 OldValue + 1,
40 OldValue);
41 if (OldValue == NewValue) return TRUE;
42
43 /* Keep looping */
44 OldValue = NewValue;
45 } while (OldValue);
46
47 /* If we got here, then the reference count is now 0 */
48 return FALSE;
49}
#define InterlockedCompareExchangeSizeT(Destination, Exchange, Comperand)
Definition: ex.h:1539

Referenced by _Function_class_(), CmpFlushNotifiesOnKeyBodyList(), NtImpersonateClientOfPort(), NtRequestPort(), PsGetNextProcess(), PsGetNextProcessThread(), PsLookupProcessByProcessId(), PsLookupProcessThreadByCid(), PsLookupThreadByThreadId(), PspExitThread(), and SepCleanupLUIDDeviceMapDirectory().

◆ ObReferenceProcessHandleTable()

PHANDLE_TABLE NTAPI ObReferenceProcessHandleTable ( IN PEPROCESS  Process)

Definition at line 26 of file obhandle.c.

27{
29
30 /* Lock the process */
31 if (ExAcquireRundownProtection(&Process->RundownProtect))
32 {
33 /* Get the handle table */
34 HandleTable = Process->ObjectTable;
35 if (!HandleTable)
36 {
37 /* No table, release the lock */
38 ExReleaseRundownProtection(&Process->RundownProtect);
39 }
40 }
41
42 /* Return the handle table */
43 return HandleTable;
44}
#define ExAcquireRundownProtection
Definition: ex.h:135

Referenced by ObClearProcessHandleTable(), ObDuplicateObject(), ObFindHandleForObject(), ObGetProcessHandleCount(), and ObInitProcess().

◆ ObSetDeviceMap()

NTSTATUS NTAPI ObSetDeviceMap ( IN PEPROCESS  Process,
IN HANDLE  DirectoryHandle 
)

Definition at line 24 of file devicemap.c.

26{
27 POBJECT_DIRECTORY DirectoryObject = NULL;
28 PDEVICE_MAP DeviceMap = NULL, NewDeviceMap = NULL, OldDeviceMap;
30 PEPROCESS WorkProcess;
31 BOOLEAN MakePermanant = FALSE;
32
37 (PVOID*)&DirectoryObject,
38 NULL);
39 if (!NT_SUCCESS(Status))
40 {
41 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status);
42 return Status;
43 }
44
45 /* Allocate and initialize a new device map */
47 sizeof(*DeviceMap),
48 'mDbO');
49 if (DeviceMap == NULL)
50 {
51 ObDereferenceObject(DirectoryObject);
53 }
54
55 /* Initialize the device map */
56 RtlZeroMemory(DeviceMap, sizeof(*DeviceMap));
57 DeviceMap->ReferenceCount = 1;
58 DeviceMap->DosDevicesDirectory = DirectoryObject;
59
60 /* Acquire the device map lock */
62
63 /* Attach the device map to the directory object */
64 if (DirectoryObject->DeviceMap == NULL)
65 {
66 DirectoryObject->DeviceMap = DeviceMap;
67 }
68 else
69 {
70 NewDeviceMap = DeviceMap;
71
72 /* There's already a device map,
73 so reuse it */
74 DeviceMap = DirectoryObject->DeviceMap;
75 ++DeviceMap->ReferenceCount;
76 }
77
78 /* Caller gave a process, use it */
79 if (Process != NULL)
80 {
81 WorkProcess = Process;
82 }
83 /* If no process given, use current and
84 * set system device map */
85 else
86 {
87 WorkProcess = PsGetCurrentProcess();
88 ObSystemDeviceMap = DeviceMap;
89 }
90
91 /* If current object isn't system one, save system one in current
92 * device map */
93 if (DirectoryObject != ObSystemDeviceMap->DosDevicesDirectory)
94 {
95 /* We also need to make the object permanant */
97 MakePermanant = TRUE;
98 }
99
100 /* Save old process device map */
101 OldDeviceMap = WorkProcess->DeviceMap;
102 /* Attach the device map to the process */
103 WorkProcess->DeviceMap = DeviceMap;
104
105 /* Release the device map lock */
107
108 /* If we have to make the object permamant, do it now */
109 if (MakePermanant)
110 {
111 POBJECT_HEADER ObjectHeader;
112 POBJECT_HEADER_NAME_INFO HeaderNameInfo;
113
114 ObjectHeader = OBJECT_TO_OBJECT_HEADER(DirectoryObject);
115 HeaderNameInfo = ObpReferenceNameInfo(ObjectHeader);
116
117 ObpEnterObjectTypeMutex(ObjectHeader->Type);
118 if (HeaderNameInfo != NULL && HeaderNameInfo->Directory != NULL)
119 {
120 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
121 }
122 ObpLeaveObjectTypeMutex(ObjectHeader->Type);
123
124 if (HeaderNameInfo != NULL)
125 {
126 ObpDereferenceNameInfo(HeaderNameInfo);
127 }
128 }
129
130 /* Release useless device map if required */
131 if (NewDeviceMap != NULL)
132 {
133 ObDereferenceObject(DirectoryObject);
134 ExFreePoolWithTag(NewDeviceMap, 'mDbO');
135 }
136
137 /* And dereference previous process device map */
138 if (OldDeviceMap != NULL)
139 {
140 ObfDereferenceDeviceMap(OldDeviceMap);
141 }
142
143 return STATUS_SUCCESS;
144}
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define KeGetPreviousMode()
Definition: ketypes.h:1115
PVOID DeviceMap
Definition: pstypes.h:1313

Referenced by NtSetInformationProcess(), and ObpCreateDosDevicesDirectory().

◆ ObSetDirectoryDeviceMap()

NTSTATUS NTAPI ObSetDirectoryDeviceMap ( OUT PDEVICE_MAP DeviceMap,
IN HANDLE  DirectoryHandle 
)

Definition at line 149 of file devicemap.c.

151{
152 POBJECT_DIRECTORY DirectoryObject = NULL;
153 PDEVICE_MAP LocalMap = NULL, NewDeviceMap = NULL;
155 POBJECT_HEADER ObjectHeader;
156 POBJECT_HEADER_NAME_INFO HeaderNameInfo;
157
162 (PVOID*)&DirectoryObject,
163 NULL);
164 if (!NT_SUCCESS(Status))
165 {
166 DPRINT("ObReferenceObjectByHandle() failed (Status 0x%08lx)\n", Status);
167 return Status;
168 }
169
170 /* Allocate and initialize a new device map */
172 sizeof(*LocalMap),
173 'mDbO');
174 if (LocalMap == NULL)
175 {
176 ObDereferenceObject(DirectoryObject);
178 }
179
180 /* Initialize the device map */
181 RtlZeroMemory(LocalMap, sizeof(*LocalMap));
182 LocalMap->ReferenceCount = 1;
183 LocalMap->DosDevicesDirectory = DirectoryObject;
184
185 /* Acquire the device map lock */
187
188 /* Attach the device map to the directory object */
189 if (DirectoryObject->DeviceMap == NULL)
190 {
191 DirectoryObject->DeviceMap = LocalMap;
192 }
193 else
194 {
195 NewDeviceMap = LocalMap;
196
197 /* There's already a device map,
198 so reuse it */
199 LocalMap = DirectoryObject->DeviceMap;
200 ++LocalMap->ReferenceCount;
201 }
202
203 /* If current object isn't system one, save system one in current
204 * device map */
205 if (DirectoryObject != ObSystemDeviceMap->DosDevicesDirectory)
206 {
207 /* We also need to make the object permanant */
209 }
210
211 /* Release the device map lock */
213
214 if (DeviceMap != NULL)
215 {
216 *DeviceMap = LocalMap;
217 }
218
219 /* Caller expects us to make the object permanant, so do it! */
220 ObjectHeader = OBJECT_TO_OBJECT_HEADER(DirectoryObject);
221 HeaderNameInfo = ObpReferenceNameInfo(ObjectHeader);
222
223 ObpEnterObjectTypeMutex(ObjectHeader->Type);
224 if (HeaderNameInfo != NULL && HeaderNameInfo->Directory != NULL)
225 {
226 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
227 }
228 ObpLeaveObjectTypeMutex(ObjectHeader->Type);
229
230 if (HeaderNameInfo != NULL)
231 {
232 ObpDereferenceNameInfo(HeaderNameInfo);
233 }
234
235 /* Release useless device map if required */
236 if (NewDeviceMap != NULL)
237 {
238 ObDereferenceObject(DirectoryObject);
239 ExFreePoolWithTag(NewDeviceMap, 'mDbO');
240 }
241
242 return Status;
243}

Referenced by SeGetLogonIdDeviceMap().

◆ ObSetSecurityDescriptorInfo()

NTSTATUS NTAPI ObSetSecurityDescriptorInfo ( IN PVOID  Object,
IN PSECURITY_INFORMATION  SecurityInformation,
IN OUT PSECURITY_DESCRIPTOR  SecurityDescriptor,
IN OUT PSECURITY_DESCRIPTOR OutputSecurityDescriptor,
IN POOL_TYPE  PoolType,
IN PGENERIC_MAPPING  GenericMapping 
)

Definition at line 117 of file obsecure.c.

123{
125 POBJECT_HEADER ObjectHeader;
126 PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
127 PEX_FAST_REF FastRef;
128 EX_FAST_REF OldValue;
129 ULONG Count;
130 PAGED_CODE();
131
132 /* Get the object header */
133 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
134 while (TRUE)
135 {
136 /* Reference the old descriptor */
137 OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
138 NewDescriptor = OldDescriptor;
139
140 /* Set the SD information */
145 PoolType,
147 if (!NT_SUCCESS(Status))
148 {
149 /* We failed, dereference the old one */
150 if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
151 break;
152 }
153
154 /* Now add this to the cache */
156 &CachedDescriptor,
157 MAX_FAST_REFS + 1);
158
159 /* Let go of our uncached copy */
161
162 /* Check for success */
163 if (!NT_SUCCESS(Status))
164 {
165 /* We failed, dereference the old one */
166 ObDereferenceSecurityDescriptor(OldDescriptor, 1);
167 break;
168 }
169
170 /* Do the swap */
171 FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
172 OldValue = ExCompareSwapFastReference(FastRef,
173 CachedDescriptor,
174 OldDescriptor);
175
176 /* Make sure the swap worked */
177 if (ExGetObjectFastReference(OldValue) == OldDescriptor)
178 {
179 /* Flush waiters */
180 ObpAcquireObjectLock(ObjectHeader);
181 ObpReleaseObjectLock(ObjectHeader);
182
183 /* And dereference the old one */
184 Count = ExGetCountFastReference(OldValue);
185 ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
186 break;
187 }
188 else
189 {
190 /* Someone changed it behind our back -- try again */
191 ObDereferenceSecurityDescriptor(OldDescriptor, 1);
192 ObDereferenceSecurityDescriptor(CachedDescriptor,
193 MAX_FAST_REFS + 1);
194 }
195 }
196
197 /* Return status */
198 return Status;
199}
static GENERIC_MAPPING GenericMapping
Definition: SeInheritance.c:11
FORCEINLINE EX_FAST_REF ExCompareSwapFastReference(IN PEX_FAST_REF FastRef, IN PVOID Object, IN PVOID OldObject)
Definition: ex.h:747
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815
NTKERNELAPI NTSTATUS NTAPI SeSetSecurityDescriptorInfo(_In_opt_ PVOID Object, _In_ PSECURITY_INFORMATION SecurityInformation, _In_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping)
_In_opt_ PSECURITY_DESCRIPTOR _Out_ PSECURITY_DESCRIPTOR * NewDescriptor
Definition: sefuncs.h:30

Referenced by SeDefaultObjectMethod(), and WmipSecurityMethod().

◆ ObShutdownSystem()

VOID NTAPI ObShutdownSystem ( VOID  )

Variable Documentation

◆ IoCountOperations

BOOLEAN IoCountOperations
extern

Definition at line 38 of file iomgr.c.

Referenced by IopUpdateOperationCount(), and IopUpdateTransferCount().

◆ ObpCreateInfoLookasideList

GENERAL_LOOKASIDE ObpCreateInfoLookasideList

Definition at line 644 of file ob.h.

Referenced by ObInit2(), and ObInitSystem().

◆ ObpDefaultObject

KEVENT ObpDefaultObject
extern

Definition at line 23 of file oblife.c.

Referenced by ObCreateObjectType().

◆ ObpDeviceMapLock

◆ ObpDirectoryObjectType

POBJECT_TYPE ObpDirectoryObjectType
extern

Definition at line 20 of file obdir.c.

Referenced by NtCreateDirectoryObject(), NtOpenDirectoryObject(), and NtQueryDirectoryObject().

◆ ObpDosDevicesShortName

UNICODE_STRING ObpDosDevicesShortName
extern

Definition at line 25 of file obname.c.

Referenced by ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

◆ ObpDosDevicesShortNamePrefix

ALIGNEDNAME ObpDosDevicesShortNamePrefix
extern

Definition at line 23 of file obname.c.

Referenced by ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

◆ ObpDosDevicesShortNameRoot

ALIGNEDNAME ObpDosDevicesShortNameRoot
extern

Definition at line 24 of file obname.c.

Referenced by ObpCreateDosDevicesDirectory(), and ObpLookupObjectName().

◆ ObpKernelHandleTable

◆ ObpLUIDDeviceMapsDisabled

ULONG ObpLUIDDeviceMapsDisabled
extern

Definition at line 17 of file devicemap.c.

Referenced by ObpCreateDosDevicesDirectory().

◆ ObpLUIDDeviceMapsEnabled

◆ ObpNameBufferLookasideList

GENERAL_LOOKASIDE ObpNameBufferLookasideList
extern

Definition at line 26 of file oblife.c.

Referenced by ObInit2(), and ObInitSystem().

◆ ObpObjectSecurityMode

ULONG ObpObjectSecurityMode
extern

Definition at line 56 of file obinit.c.

Referenced by QSI_DEF().

◆ ObpProtectionMode

ULONG ObpProtectionMode
extern

Definition at line 57 of file obinit.c.

Referenced by ObpCreateDosDevicesDirectory(), and ObpGetDosDevicesProtection().

◆ ObpReaperList

volatile PVOID ObpReaperList
extern

Definition at line 29 of file oblife.c.

Referenced by ObpDeferObjectDeletion(), and ObpReapObject().

◆ ObpReaperWorkItem

WORK_QUEUE_ITEM ObpReaperWorkItem
extern

Definition at line 28 of file oblife.c.

Referenced by ObInitSystem(), and ObpDeferObjectDeletion().

◆ ObpRootDirectoryObject

POBJECT_DIRECTORY ObpRootDirectoryObject
extern

◆ ObpSymbolicLinkObjectType

POBJECT_TYPE ObpSymbolicLinkObjectType
extern

◆ ObpTraceLevel

ULONG ObpTraceLevel
extern

Definition at line 47 of file obinit.c.

◆ ObpTypeDirectoryObject

POBJECT_DIRECTORY ObpTypeDirectoryObject
extern

Definition at line 20 of file obname.c.

Referenced by ObCreateObjectType(), and ObInitSystem().

◆ ObpTypeObjectType

POBJECT_TYPE ObpTypeObjectType
extern

Definition at line 22 of file oblife.c.

Referenced by ObCreateObjectType().

◆ ObpUnsecureGlobalNamesBuffer

WCHAR ObpUnsecureGlobalNamesBuffer[128]
extern

Definition at line 32 of file obname.c.

Referenced by ObpIsUnsecureName().

◆ ObpUnsecureGlobalNamesLength

ULONG ObpUnsecureGlobalNamesLength
extern

Definition at line 33 of file obname.c.