Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1419 lines
34 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. obp.h
  5. Abstract:
  6. Private include file for the OB subcomponent of the NTOS project
  7. Author:
  8. Steve Wood (stevewo) 31-Mar-1989
  9. Revision History:
  10. --*/
  11. #pragma warning(disable:4214) // bit field types other than int
  12. #pragma warning(disable:4201) // nameless struct/union
  13. #pragma warning(disable:4324) // alignment sensitive to declspec
  14. #pragma warning(disable:4127) // condition expression is constant
  15. #pragma warning(disable:4115) // named type definition in parentheses
  16. #pragma warning(disable:4053) // one void operand
  17. #pragma warning(disable:4706) // assignment within conditional
  18. #include "ntos.h"
  19. #include "seopaque.h"
  20. #include <zwapi.h>
  21. #ifdef _WIN64
  22. #define ObpInterlockedExchangeAdd InterlockedExchangeAdd64
  23. #define ObpInterlockedIncrement InterlockedIncrement64
  24. #define ObpInterlockedDecrement InterlockedDecrement64
  25. #define ObpInterlockedCompareExchange InterlockedCompareExchange64
  26. #else
  27. #define ObpInterlockedExchangeAdd InterlockedExchangeAdd
  28. #define ObpInterlockedIncrement InterlockedIncrement
  29. #define ObpInterlockedDecrement InterlockedDecrement
  30. #define ObpInterlockedCompareExchange InterlockedCompareExchange
  31. #endif
  32. #define OBP_PAGEDPOOL_NAMESPACE
  33. //
  34. // The Object Header structures are private, but are defined in ob.h
  35. // so that various macros can directly access header fields.
  36. //
  37. struct _OBJECT_HEADER;
  38. struct _OBJECT_BODY_HEADER;
  39. //
  40. // Setup default pool tags
  41. //
  42. #ifdef POOL_TAGGING
  43. #define ExAllocatePool(a,b) ExAllocatePoolWithTag(a,b,' bO')
  44. #define ExAllocatePoolWithQuota(a,b) ExAllocatePoolWithQuotaTag(a,b,' bO')
  45. #endif
  46. //
  47. // Define some macros that will verify that our callbacks don't give us a bad irql
  48. //
  49. #if DBG
  50. #define ObpBeginTypeSpecificCallOut( IRQL ) (IRQL)=KeGetCurrentIrql()
  51. #define ObpEndTypeSpecificCallOut( IRQL, str, ot, o ) { \
  52. if ((IRQL)!=KeGetCurrentIrql()) { \
  53. DbgPrint( "OB: ObjectType: %wZ Procedure: %s Object: %08x\n", &ot->Name, str, o ); \
  54. DbgPrint( " Returned at %x IRQL, but was called at %x IRQL\n", KeGetCurrentIrql(), IRQL ); \
  55. DbgBreakPoint(); \
  56. } \
  57. }
  58. #else
  59. #define ObpBeginTypeSpecificCallOut( IRQL )
  60. #define ObpEndTypeSpecificCallOut( IRQL, str, ot, o )
  61. #endif // DBG
  62. //
  63. // Define some more macros to validate the current irql
  64. //
  65. #if DBG
  66. #define ObpValidateIrql( str ) \
  67. if (KeGetCurrentIrql() > APC_LEVEL) { \
  68. DbgPrint( "OB: %s called at IRQL %d\n", (str), KeGetCurrentIrql() ); \
  69. DbgBreakPoint(); \
  70. }
  71. #else
  72. #define ObpValidateIrql( str )
  73. #endif // DBG
  74. //
  75. // This global lock protects the granted access lists when we are collecting stack traces
  76. //
  77. EX_PUSH_LOCK ObpLock;
  78. KEVENT ObpDefaultObject;
  79. WORK_QUEUE_ITEM ObpRemoveObjectWorkItem;
  80. PVOID ObpRemoveObjectList;
  81. //
  82. // This global lock is used to protect the device map tear down and build up
  83. // We can no longer use an individual lock in the device map itself because
  84. // that wasn't sufficient to protect the device map itself.
  85. //
  86. #ifdef OBP_PAGEDPOOL_NAMESPACE
  87. #define OB_NAMESPACE_POOL_TYPE PagedPool
  88. KGUARDED_MUTEX ObpDeviceMapLock;
  89. #define OBP_DECLARE_OLDIRQL
  90. #define ObpLockDeviceMap() \
  91. KeAcquireGuardedMutex( &ObpDeviceMapLock )
  92. #define ObpUnlockDeviceMap() \
  93. KeReleaseGuardedMutex( &ObpDeviceMapLock )
  94. #else // !OBP_PAGEDPOOL_NAMESPACE
  95. #define OB_NAMESPACE_POOL_TYPE NonPagedPool
  96. KSPIN_LOCK ObpDeviceMapLock;
  97. #define ObpLockDeviceMap() \
  98. ExAcquireSpinLock( &ObpDeviceMapLock, &OldIrql )
  99. #define ObpUnlockDeviceMap() \
  100. ExReleaseSpinLock( &ObpDeviceMapLock, OldIrql )
  101. #endif // OBP_PAGEDPOOL_NAMESPACE
  102. #define ObpIncrPointerCountEx(np,Count) (ObpInterlockedExchangeAdd (&np->PointerCount, Count) + Count)
  103. #define ObpDecrPointerCountEx(np,Count) (ObpInterlockedExchangeAdd (&np->PointerCount, -(LONG_PTR)(Count)) - Count)
  104. #ifndef POOL_TAGGING
  105. #define ObpIncrPointerCount(np) ObpInterlockedIncrement( &np->PointerCount )
  106. #define ObpDecrPointerCount(np) ObpInterlockedDecrement( &np->PointerCount )
  107. #define ObpDecrPointerCountWithResult(np) (ObpInterlockedDecrement( &np->PointerCount ) == 0)
  108. #define ObpPushStackInfo(np, inc)
  109. #else //POOL_TAGGING
  110. VOID
  111. ObpInitStackTrace();
  112. VOID
  113. ObpRegisterObject (
  114. POBJECT_HEADER ObjectHeader
  115. );
  116. VOID
  117. ObpDeregisterObject (
  118. POBJECT_HEADER ObjectHeader
  119. );
  120. VOID
  121. ObpPushStackInfo (
  122. POBJECT_HEADER ObjectHeader,
  123. BOOLEAN IsRef
  124. );
  125. extern BOOLEAN ObpTraceEnabled;
  126. #define ObpIncrPointerCount(np) ((ObpTraceEnabled ? ObpPushStackInfo(np,TRUE) : 0),ObpInterlockedIncrement( &np->PointerCount ))
  127. #define ObpDecrPointerCount(np) ((ObpTraceEnabled ? ObpPushStackInfo(np,FALSE) : 0),ObpInterlockedDecrement( &np->PointerCount ))
  128. #define ObpDecrPointerCountWithResult(np) ((ObpTraceEnabled ? ObpPushStackInfo(np,FALSE) : 0),(ObpInterlockedDecrement( &np->PointerCount ) == 0))
  129. #endif //POOL_TAGGING
  130. #define ObpIncrHandleCount(np) ObpInterlockedIncrement( &np->HandleCount )
  131. #define ObpDecrHandleCount(np) (ObpInterlockedDecrement( &np->HandleCount ) == 0)
  132. //
  133. // Define macros to acquire and release an object type fast mutex.
  134. //
  135. //
  136. // VOID
  137. // ObpEnterObjectTypeMutex (
  138. // IN POBJECT_TYPE ObjectType
  139. // )
  140. //
  141. #define ObpEnterObjectTypeMutex(_ObjectType) { \
  142. ObpValidateIrql("ObpEnterObjectTypeMutex"); \
  143. KeEnterCriticalRegion(); \
  144. ExAcquireResourceExclusiveLite(&(_ObjectType)->Mutex, TRUE); \
  145. }
  146. //
  147. // VOID
  148. // ObpLeaveObjectTypeMutex (
  149. // IN POBJECT_TYPE ObjectType
  150. // )
  151. //
  152. #define ObpLeaveObjectTypeMutex(_ObjectType) { \
  153. ExReleaseResourceLite(&(_ObjectType)->Mutex); \
  154. KeLeaveCriticalRegion(); \
  155. ObpValidateIrql("ObpLeaveObjectTypeMutex"); \
  156. }
  157. #define LOCK_HASH_MASK (OBJECT_LOCK_COUNT - 1)
  158. #define ObpHashObjectHeader(_ObjectHeader) \
  159. ((((ULONG_PTR)(_ObjectHeader)) >> 8) & LOCK_HASH_MASK)
  160. #define ObpLockObject(_ObjectHeader) { \
  161. ULONG_PTR LockIndex = ObpHashObjectHeader(_ObjectHeader); \
  162. ObpValidateIrql("ObpEnterObjectTypeMutex"); \
  163. KeEnterCriticalRegion(); \
  164. ExAcquireResourceExclusiveLite(&((_ObjectHeader)->Type->ObjectLocks[LockIndex]), TRUE); \
  165. }
  166. #define ObpLockObjectShared(_ObjectHeader) { \
  167. ULONG_PTR LockIndex = ObpHashObjectHeader(_ObjectHeader); \
  168. ObpValidateIrql("ObpEnterObjectTypeMutex"); \
  169. KeEnterCriticalRegion(); \
  170. ExAcquireResourceSharedLite(&((_ObjectHeader)->Type->ObjectLocks[LockIndex]), TRUE); \
  171. }
  172. #define ObpUnlockObject(_ObjectHeader) { \
  173. ULONG_PTR LockIndex = ObpHashObjectHeader(_ObjectHeader); \
  174. ExReleaseResourceLite(&((_ObjectHeader)->Type->ObjectLocks[LockIndex])); \
  175. KeLeaveCriticalRegion(); \
  176. ObpValidateIrql("ObpLeaveObjectTypeMutex"); \
  177. }
  178. //
  179. // A Macro to return the object table for the current process
  180. //
  181. #define ObpGetObjectTable() (PsGetCurrentProcess()->ObjectTable)
  182. //
  183. // Macro to test whether or not the object manager is responsible for
  184. // an object's security descriptor, or if the object has its own
  185. // security management routines.
  186. //
  187. #define ObpCentralizedSecurity(_ObjectType) \
  188. ((_ObjectType)->TypeInfo.SecurityProcedure == SeDefaultObjectMethod)
  189. //
  190. // Declare a global table of object types.
  191. //
  192. #define OBP_MAX_DEFINED_OBJECT_TYPES 48
  193. POBJECT_TYPE ObpObjectTypes[ OBP_MAX_DEFINED_OBJECT_TYPES ];
  194. //
  195. // This is some special purpose code to keep a table of access masks correlated with
  196. // back traces. If used these routines replace the GrantedAccess mask in the
  197. // preceding object table entry with a granted access index and a call back index.
  198. //
  199. #if i386
  200. ACCESS_MASK
  201. ObpTranslateGrantedAccessIndex (
  202. USHORT GrantedAccessIndex
  203. );
  204. USHORT
  205. ObpComputeGrantedAccessIndex (
  206. ACCESS_MASK GrantedAccess
  207. );
  208. USHORT ObpCurCachedGrantedAccessIndex;
  209. USHORT ObpMaxCachedGrantedAccessIndex;
  210. PACCESS_MASK ObpCachedGrantedAccesses;
  211. #endif // i386
  212. //
  213. // The three low order bits of the object table entry are used for handle
  214. // attributes.
  215. //
  216. //
  217. // We moved the PROTECT_CLOSE in the granted access mask
  218. //
  219. extern ULONG ObpAccessProtectCloseBit;
  220. //
  221. // The bit mask for inherit MUST be 0x2.
  222. //
  223. #if (OBJ_INHERIT != 0x2)
  224. #error Object inheritance bit definition conflicts
  225. #endif
  226. //
  227. // Define the bit mask for the generate audit on close attribute.
  228. //
  229. // When a handle to an object with security is created, audit routines will
  230. // be called to perform any auditing that may be required. The audit routines
  231. // will return a boolean indicating whether or not audits should be generated
  232. // on close.
  233. //
  234. #define OBJ_AUDIT_OBJECT_CLOSE 0x00000004L
  235. //
  236. // The following three bits are available for handle attributes in the
  237. // Object field of an ObjectTableEntry.
  238. //
  239. #define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE | OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)
  240. #define ObpDecodeGrantedAccess(Access) \
  241. ((Access) & ~ObpAccessProtectCloseBit)
  242. #define ObpGetHandleAttributes(HandleTableEntry) \
  243. ((((HandleTableEntry)->GrantedAccess) & ObpAccessProtectCloseBit) ? \
  244. ((((HandleTableEntry)->ObAttributes) & OBJ_HANDLE_ATTRIBUTES) | OBJ_PROTECT_CLOSE) : \
  245. (((HandleTableEntry)->ObAttributes) & (OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)) )
  246. #define ObpEncodeProtectClose(ObjectTableEntry) \
  247. if ( (ObjectTableEntry).ObAttributes & OBJ_PROTECT_CLOSE ) { \
  248. \
  249. (ObjectTableEntry).ObAttributes &= ~OBJ_PROTECT_CLOSE; \
  250. (ObjectTableEntry).GrantedAccess |= ObpAccessProtectCloseBit; \
  251. }
  252. //
  253. // Security Descriptor Cache
  254. //
  255. // Cache entry header.
  256. //
  257. typedef struct _SECURITY_DESCRIPTOR_HEADER {
  258. LIST_ENTRY Link;
  259. ULONG RefCount;
  260. ULONG FullHash;
  261. #if defined (_WIN64)
  262. PVOID Spare; // Align to 16 byte boundary.
  263. #endif
  264. QUAD SecurityDescriptor;
  265. } SECURITY_DESCRIPTOR_HEADER, *PSECURITY_DESCRIPTOR_HEADER;
  266. //
  267. // Macro to convert a security descriptor into its security descriptor header
  268. //
  269. #define SD_TO_SD_HEADER(_sd) \
  270. CONTAINING_RECORD( (_sd), SECURITY_DESCRIPTOR_HEADER, SecurityDescriptor )
  271. //
  272. // Macro to convert a header link into its security descriptor header
  273. //
  274. #define LINK_TO_SD_HEADER(_link) \
  275. CONTAINING_RECORD( (_link), SECURITY_DESCRIPTOR_HEADER, Link )
  276. //
  277. // Number of minor hash entries
  278. //
  279. #define SECURITY_DESCRIPTOR_CACHE_ENTRIES 257
  280. //
  281. // Lock state signatures
  282. //
  283. #define OBP_LOCK_WAITEXCLUSIVE_SIGNATURE 0xAAAA1234
  284. #define OBP_LOCK_WAITSHARED_SIGNATURE 0xBBBB1234
  285. #define OBP_LOCK_OWNEDEXCLUSIVE_SIGNATURE 0xCCCC1234
  286. #define OBP_LOCK_OWNEDSHARED_SIGNATURE 0xDDDD1234
  287. #define OBP_LOCK_RELEASED_SIGNATURE 0xEEEE1234
  288. #define OBP_LOCK_UNUSED_SIGNATURE 0xFFFF1234
  289. //
  290. // Lookup directories
  291. //
  292. typedef struct _OBP_LOOKUP_CONTEXT {
  293. POBJECT_DIRECTORY Directory;
  294. PVOID Object;
  295. USHORT HashIndex;
  296. BOOLEAN DirectoryLocked;
  297. volatile ULONG LockStateSignature;
  298. } OBP_LOOKUP_CONTEXT, *POBP_LOOKUP_CONTEXT;
  299. //
  300. // Context for the sweep routine. Passed through handle enumeration.
  301. //
  302. typedef struct _OBP_SWEEP_CONTEXT {
  303. PHANDLE_TABLE HandleTable;
  304. KPROCESSOR_MODE PreviousMode;
  305. } OBP_SWEEP_CONTEXT, *POBP_SWEEP_CONTEXT;
  306. //
  307. // Global data
  308. //
  309. POBJECT_TYPE ObpTypeObjectType;
  310. POBJECT_TYPE ObpDirectoryObjectType;
  311. POBJECT_TYPE ObpSymbolicLinkObjectType;
  312. POBJECT_TYPE ObpDeviceMapObjectType;
  313. POBJECT_DIRECTORY ObpRootDirectoryObject;
  314. POBJECT_DIRECTORY ObpTypeDirectoryObject;
  315. typedef union {
  316. WCHAR Name[sizeof(ULARGE_INTEGER)/sizeof(WCHAR)];
  317. ULARGE_INTEGER Alignment;
  318. } ALIGNEDNAME;
  319. extern const ALIGNEDNAME ObpDosDevicesShortNamePrefix;
  320. extern const ALIGNEDNAME ObpDosDevicesShortNameRoot;
  321. extern const UNICODE_STRING ObpDosDevicesShortName;
  322. ERESOURCE SecurityDescriptorCacheLock;
  323. //
  324. // Define date structures for the object creation information region.
  325. //
  326. extern GENERAL_LOOKASIDE ObpCreateInfoLookasideList;
  327. //
  328. // Define data structures for the object name buffer lookaside list.
  329. //
  330. #define OBJECT_NAME_BUFFER_SIZE 248
  331. extern GENERAL_LOOKASIDE ObpNameBufferLookasideList;
  332. //
  333. // There is one global kernel handle table accessed via negative handle
  334. // and only in kernel mode
  335. //
  336. PHANDLE_TABLE ObpKernelHandleTable;
  337. //
  338. // The following macros are used to test and manipulate special kernel
  339. // handles. A kernel handle is just a regular handle with its sign
  340. // bit set. But must exclude -1 and -2 values which are the current
  341. // process and current thread constants.
  342. //
  343. #define KERNEL_HANDLE_MASK ((ULONG_PTR)((LONG)0x80000000))
  344. #define IsKernelHandle(H,M) \
  345. (((KERNEL_HANDLE_MASK & (ULONG_PTR)(H)) == KERNEL_HANDLE_MASK) && \
  346. ((M) == KernelMode) && \
  347. ((H) != NtCurrentThread()) && \
  348. ((H) != NtCurrentProcess()))
  349. #define EncodeKernelHandle(H) (HANDLE)(KERNEL_HANDLE_MASK | (ULONG_PTR)(H))
  350. #define DecodeKernelHandle(H) (HANDLE)(KERNEL_HANDLE_MASK ^ (ULONG_PTR)(H))
  351. //
  352. // Test macro for overflow
  353. //
  354. #define ObpIsOverflow(A,B) ((A) > ((A) + (B)))
  355. //
  356. // Internal Entry Points defined in obcreate.c and some associated macros
  357. //
  358. #define ObpFreeObjectCreateInformation(_ObjectCreateInfo) { \
  359. ObpReleaseObjectCreateInformation((_ObjectCreateInfo)); \
  360. ObpFreeObjectCreateInfoBuffer((_ObjectCreateInfo)); \
  361. }
  362. #define ObpReleaseObjectCreateInformation(_ObjectCreateInfo) { \
  363. if ((_ObjectCreateInfo)->SecurityDescriptor != NULL) { \
  364. SeReleaseSecurityDescriptor((_ObjectCreateInfo)->SecurityDescriptor, \
  365. (_ObjectCreateInfo)->ProbeMode, \
  366. TRUE); \
  367. (_ObjectCreateInfo)->SecurityDescriptor = NULL; \
  368. } \
  369. }
  370. NTSTATUS
  371. ObpCaptureObjectCreateInformation (
  372. IN POBJECT_TYPE ObjectType OPTIONAL,
  373. IN KPROCESSOR_MODE ProbeMode,
  374. IN KPROCESSOR_MODE CreatorMode,
  375. IN POBJECT_ATTRIBUTES ObjectAttributes,
  376. OUT PUNICODE_STRING CapturedObjectName,
  377. IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
  378. IN LOGICAL UseLookaside
  379. );
  380. NTSTATUS
  381. ObpCaptureObjectName (
  382. IN KPROCESSOR_MODE ProbeMode,
  383. IN PUNICODE_STRING ObjectName,
  384. IN OUT PUNICODE_STRING CapturedObjectName,
  385. IN LOGICAL UseLookaside
  386. );
  387. PWCHAR
  388. ObpAllocateObjectNameBuffer (
  389. IN ULONG Length,
  390. IN LOGICAL UseLookaside,
  391. IN OUT PUNICODE_STRING ObjectName
  392. );
  393. VOID
  394. FASTCALL
  395. ObpFreeObjectNameBuffer (
  396. IN PUNICODE_STRING ObjectName
  397. );
  398. NTSTATUS
  399. ObpAllocateObject (
  400. IN POBJECT_CREATE_INFORMATION ObjectCreateInfo,
  401. IN KPROCESSOR_MODE OwnershipMode,
  402. IN POBJECT_TYPE ObjectType,
  403. IN PUNICODE_STRING ObjectName,
  404. IN ULONG ObjectBodySize,
  405. OUT POBJECT_HEADER *ReturnedObjectHeader
  406. );
  407. VOID
  408. FASTCALL
  409. ObpFreeObject (
  410. IN PVOID Object
  411. );
  412. /*++
  413. POBJECT_CREATE_INFORMATION
  414. ObpAllocateObjectCreateInfoBuffer (
  415. VOID
  416. )
  417. Routine Description:
  418. This function allocates a created information buffer.
  419. N.B. This function is nonpageable.
  420. Arguments:
  421. None.
  422. Return Value:
  423. If the allocation is successful, then the address of the allocated
  424. create information buffer is is returned as the function value.
  425. Otherwise, a value of NULL is returned.
  426. --*/
  427. #define ObpAllocateObjectCreateInfoBuffer() \
  428. (POBJECT_CREATE_INFORMATION)ExAllocateFromPPLookasideList(LookasideCreateInfoList)
  429. /*++
  430. VOID
  431. FASTCALL
  432. ObpFreeObjectCreateInfoBuffer (
  433. IN POBJECT_CREATE_INFORMATION ObjectCreateInfo
  434. )
  435. Routine Description:
  436. This function frees a create information buffer.
  437. N.B. This function is nonpageable.
  438. Arguments:
  439. ObjectCreateInfo - Supplies a pointer to a create information buffer.
  440. Return Value:
  441. None.
  442. --*/
  443. #define ObpFreeObjectCreateInfoBuffer(ObjectCreateInfo) \
  444. ExFreeToPPLookasideList(LookasideCreateInfoList, ObjectCreateInfo)
  445. //
  446. // Internal Entry Points defined in oblink.c
  447. //
  448. NTSTATUS
  449. ObpParseSymbolicLink (
  450. IN PVOID ParseObject,
  451. IN PVOID ObjectType,
  452. IN PACCESS_STATE AccessState,
  453. IN KPROCESSOR_MODE AccessMode,
  454. IN ULONG Attributes,
  455. IN OUT PUNICODE_STRING CompleteName,
  456. IN OUT PUNICODE_STRING RemainingName,
  457. IN OUT PVOID Context OPTIONAL,
  458. IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
  459. OUT PVOID *Object
  460. );
  461. VOID
  462. ObpDeleteSymbolicLink (
  463. IN PVOID Object
  464. );
  465. VOID
  466. ObpCreateSymbolicLinkName (
  467. POBJECT_SYMBOLIC_LINK SymbolicLink
  468. );
  469. VOID
  470. ObpDeleteSymbolicLinkName (
  471. POBJECT_SYMBOLIC_LINK SymbolicLink
  472. );
  473. //
  474. // Internal Entry Points defined in obdir.c
  475. //
  476. PVOID
  477. ObpLookupDirectoryEntry (
  478. IN POBJECT_DIRECTORY Directory,
  479. IN PUNICODE_STRING Name,
  480. IN ULONG Attributes,
  481. IN BOOLEAN SearchShadow,
  482. OUT POBP_LOOKUP_CONTEXT LookupContext
  483. );
  484. BOOLEAN
  485. ObpInsertDirectoryEntry (
  486. IN POBJECT_DIRECTORY Directory,
  487. IN POBP_LOOKUP_CONTEXT LookupContext,
  488. IN POBJECT_HEADER ObjectHeader
  489. );
  490. BOOLEAN
  491. ObpDeleteDirectoryEntry (
  492. IN POBP_LOOKUP_CONTEXT LookupContext
  493. );
  494. NTSTATUS
  495. ObpLookupObjectName (
  496. IN HANDLE RootDirectoryHandle,
  497. IN PUNICODE_STRING ObjectName,
  498. IN ULONG Attributes,
  499. IN POBJECT_TYPE ObjectType,
  500. IN KPROCESSOR_MODE AccessMode,
  501. IN PVOID ParseContext OPTIONAL,
  502. IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
  503. IN PVOID InsertObject OPTIONAL,
  504. IN OUT PACCESS_STATE AccessState,
  505. OUT POBP_LOOKUP_CONTEXT LookupContext,
  506. OUT PVOID *FoundObject
  507. );
  508. VOID
  509. ObpUnlockObjectDirectoryPath (
  510. IN POBJECT_DIRECTORY LockedDirectory
  511. );
  512. PDEVICE_MAP
  513. ObpReferenceDeviceMap(
  514. );
  515. VOID
  516. FASTCALL
  517. ObfDereferenceDeviceMap(
  518. IN PDEVICE_MAP DeviceMap
  519. );
  520. //
  521. // Internal entry points defined in obref.c
  522. //
  523. VOID
  524. ObpDeleteNameCheck (
  525. IN PVOID Object
  526. );
  527. VOID
  528. ObpProcessRemoveObjectQueue (
  529. PVOID Parameter
  530. );
  531. VOID
  532. ObpRemoveObjectRoutine (
  533. IN PVOID Object,
  534. IN BOOLEAN CalledOnWorkerThread
  535. );
  536. //
  537. // Internal entry points defined in obhandle.c
  538. //
  539. POBJECT_HANDLE_COUNT_ENTRY
  540. ObpInsertHandleCount (
  541. POBJECT_HEADER ObjectHeader
  542. );
  543. NTSTATUS
  544. ObpIncrementHandleCount (
  545. OB_OPEN_REASON OpenReason,
  546. PEPROCESS Process,
  547. PVOID Object,
  548. POBJECT_TYPE ObjectType,
  549. PACCESS_STATE AccessState OPTIONAL,
  550. KPROCESSOR_MODE AccessMode,
  551. ULONG Attributes
  552. );
  553. VOID
  554. ObpDecrementHandleCount (
  555. PEPROCESS Process,
  556. POBJECT_HEADER ObjectHeader,
  557. POBJECT_TYPE ObjectType,
  558. ACCESS_MASK GrantedAccess
  559. );
  560. NTSTATUS
  561. ObpCreateHandle (
  562. IN OB_OPEN_REASON OpenReason,
  563. IN PVOID Object,
  564. IN POBJECT_TYPE ExpectedObjectType OPTIONAL,
  565. IN PACCESS_STATE AccessState,
  566. IN ULONG ObjectPointerBias OPTIONAL,
  567. IN ULONG Attributes,
  568. IN POBP_LOOKUP_CONTEXT LookupContext,
  569. IN KPROCESSOR_MODE AccessMode,
  570. OUT PVOID *ReferencedNewObject OPTIONAL,
  571. OUT PHANDLE Handle
  572. );
  573. NTSTATUS
  574. ObpIncrementUnnamedHandleCount (
  575. PACCESS_MASK DesiredAccess,
  576. PEPROCESS Process,
  577. PVOID Object,
  578. POBJECT_TYPE ObjectType,
  579. KPROCESSOR_MODE AccessMode,
  580. ULONG Attributes
  581. );
  582. NTSTATUS
  583. ObpCreateUnnamedHandle (
  584. IN PVOID Object,
  585. IN ACCESS_MASK DesiredAccess,
  586. IN ULONG ObjectPointerBias OPTIONAL,
  587. IN ULONG Attributes,
  588. IN KPROCESSOR_MODE AccessMode,
  589. OUT PVOID *ReferencedNewObject OPTIONAL,
  590. OUT PHANDLE Handle
  591. );
  592. NTSTATUS
  593. ObpChargeQuotaForObject (
  594. IN POBJECT_HEADER ObjectHeader,
  595. IN POBJECT_TYPE ObjectType,
  596. OUT PBOOLEAN NewObject
  597. );
  598. NTSTATUS
  599. ObpValidateDesiredAccess (
  600. IN ACCESS_MASK DesiredAccess
  601. );
  602. //
  603. // Internal entry points defined in obse.c
  604. //
  605. BOOLEAN
  606. ObpCheckPseudoHandleAccess (
  607. IN PVOID Object,
  608. IN ACCESS_MASK DesiredAccess,
  609. OUT PNTSTATUS AccessStatus,
  610. IN BOOLEAN TypeMutexLocked
  611. );
  612. BOOLEAN
  613. ObpCheckTraverseAccess (
  614. IN PVOID DirectoryObject,
  615. IN ACCESS_MASK TraverseAccess,
  616. IN PACCESS_STATE AccessState,
  617. IN BOOLEAN TypeMutexLocked,
  618. IN KPROCESSOR_MODE PreviousMode,
  619. OUT PNTSTATUS AccessStatus
  620. );
  621. BOOLEAN
  622. ObpCheckObjectReference (
  623. IN PVOID Object,
  624. IN OUT PACCESS_STATE AccessState,
  625. IN BOOLEAN TypeMutexLocked,
  626. IN KPROCESSOR_MODE AccessMode,
  627. OUT PNTSTATUS AccessStatus
  628. );
  629. //
  630. // Internal entry points defined in obsdata.c
  631. //
  632. NTSTATUS
  633. ObpInitSecurityDescriptorCache (
  634. VOID
  635. );
  636. ULONG
  637. ObpHashSecurityDescriptor (
  638. PSECURITY_DESCRIPTOR SecurityDescriptor,
  639. ULONG Length
  640. );
  641. ULONG
  642. ObpHashBuffer (
  643. PVOID Data,
  644. ULONG Length
  645. );
  646. PSECURITY_DESCRIPTOR_HEADER
  647. ObpCreateCacheEntry (
  648. PSECURITY_DESCRIPTOR InputSecurityDescriptor,
  649. ULONG Length,
  650. ULONG FullHash,
  651. ULONG RefBias
  652. );
  653. PSECURITY_DESCRIPTOR
  654. ObpReferenceSecurityDescriptor (
  655. POBJECT_HEADER ObjectHeader
  656. );
  657. PVOID
  658. ObpDestroySecurityDescriptorHeader (
  659. IN PSECURITY_DESCRIPTOR_HEADER Header
  660. );
  661. BOOLEAN
  662. ObpCompareSecurityDescriptors (
  663. IN PSECURITY_DESCRIPTOR SD1,
  664. ULONG Length,
  665. IN PSECURITY_DESCRIPTOR SD2
  666. );
  667. NTSTATUS
  668. ObpValidateAccessMask (
  669. PACCESS_STATE AccessState
  670. );
  671. NTSTATUS
  672. ObpCloseHandleTableEntry (
  673. IN PHANDLE_TABLE ObjectTable,
  674. IN PHANDLE_TABLE_ENTRY ObjectTableEntry,
  675. IN HANDLE Handle,
  676. IN KPROCESSOR_MODE PreviousMode,
  677. IN BOOLEAN Rundown
  678. );
  679. NTSTATUS
  680. ObpCloseHandle (
  681. IN HANDLE Handle,
  682. IN KPROCESSOR_MODE PreviousMode
  683. );
  684. VOID
  685. ObpDeleteObjectType (
  686. IN PVOID Object
  687. );
  688. VOID
  689. ObpAuditObjectAccess(
  690. IN HANDLE Handle,
  691. IN PHANDLE_TABLE_ENTRY_INFO ObjectTableEntryInfo,
  692. IN PUNICODE_STRING ObjectTypeName,
  693. IN ACCESS_MASK DesiredAccess
  694. );
  695. NTSTATUS
  696. ObpQueryNameString (
  697. IN PVOID Object,
  698. OUT POBJECT_NAME_INFORMATION ObjectNameInfo,
  699. IN ULONG Length,
  700. OUT PULONG ReturnLength,
  701. IN KPROCESSOR_MODE Mode
  702. );
  703. //
  704. // Inline functions
  705. //
  706. FORCEINLINE
  707. BOOLEAN
  708. ObpSafeInterlockedIncrement(
  709. IN OUT PLONG_PTR lpValue
  710. )
  711. /*
  712. Routine Description:
  713. This function increments the LONG value passed in.
  714. Unlike the InterlockedIncrement function, this will not increment from 0 to 1.
  715. It will return FALSE if it's trying to reference from 0.
  716. Arguments:
  717. lpValue - The pointer to the LONG value that should be safe incremented
  718. Return Value:
  719. Returns FALSE if the current value is 0 (so it cannot increment to 1). TRUE means the LONG
  720. value was increnemted
  721. */
  722. {
  723. LONG_PTR PointerCount, NewPointerCount;
  724. //
  725. // If the object is being deleted then the reference count is zero. So the idea here is to reference
  726. // the long value but avoid the 0 -> 1 transition that would cause a double delete.
  727. //
  728. PointerCount = *(volatile *) lpValue;
  729. do {
  730. if (PointerCount == 0) {
  731. return FALSE;
  732. }
  733. NewPointerCount = ObpInterlockedCompareExchange (lpValue,
  734. PointerCount+1,
  735. PointerCount);
  736. //
  737. // If the exchange compare completed ok then we did a reference so return true.
  738. //
  739. if (NewPointerCount == PointerCount) {
  740. return TRUE;
  741. }
  742. //
  743. // We failed because somebody else got in and changed the refence count on us. Use the new value to
  744. // prime the exchange again.
  745. //
  746. PointerCount = NewPointerCount;
  747. } while (TRUE);
  748. return TRUE;
  749. }
  750. #define OBP_NAME_LOCKED ((LONG)0x80000000)
  751. FORCEINLINE
  752. BOOLEAN
  753. ObpSafeInterlockedIncrementLong(
  754. IN OUT PLONG lpValue
  755. )
  756. /*
  757. Routine Description:
  758. This function increments the LONG value passed in.
  759. Unlike the InterlockedIncrement function, this will not increment from 0 to 1.
  760. It will return FALSE if it's trying to reference from 0.
  761. Arguments:
  762. lpValue - The pointer to the LONG value that should be safe incremented
  763. Return Value:
  764. Returns FALSE if the current value is 0 (so it cannot increment to 1). TRUE means the LONG
  765. value was increnemted
  766. */
  767. {
  768. LONG PointerCount, NewPointerCount;
  769. //
  770. // If the object is being deleted then the reference count is zero. So the idea here is to reference
  771. // the long value but avoid the 0 -> 1 transition that would cause a double delete.
  772. //
  773. PointerCount = *(volatile *) lpValue;
  774. do {
  775. if (PointerCount == 0) {
  776. return FALSE;
  777. }
  778. NewPointerCount = InterlockedCompareExchange (lpValue,
  779. PointerCount+1,
  780. PointerCount);
  781. //
  782. // If the exchange compare completed ok then we did a reference so return true.
  783. //
  784. if (NewPointerCount == PointerCount) {
  785. return TRUE;
  786. }
  787. //
  788. // We failed because somebody else got in and changed the refence count on us. Use the new value to
  789. // prime the exchange again.
  790. //
  791. PointerCount = NewPointerCount;
  792. } while (TRUE);
  793. return TRUE;
  794. }
  795. POBJECT_HEADER_NAME_INFO
  796. FORCEINLINE
  797. ObpReferenceNameInfo(
  798. IN POBJECT_HEADER ObjectHeader
  799. )
  800. /*
  801. Routine Description:
  802. This function references the name information structure. This is a substitute
  803. for the previous global locking mechanism that used the RootDirectoryMutex to protect
  804. the fields inside the NAME_INFO as well.
  805. If the function returnes a non-NULL name info, the name buffer and Directory will not go away
  806. until the ObpDereferenceNameInfo call.
  807. Arguments:
  808. ObjectHeader - The object header whose name should be safe-referenced
  809. Return Value:
  810. Returns NULL if the object doesn't have a name information structure, or if the name info is being deleted
  811. Returns a pointer to the POBJECT_HEADER_NAME_INFO if it's safe to use the fields inside it.
  812. */
  813. {
  814. POBJECT_HEADER_NAME_INFO NameInfo;
  815. NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
  816. if ((NameInfo != NULL)
  817. &&
  818. ObpSafeInterlockedIncrementLong((PLONG) &NameInfo->QueryReferences )) {
  819. if (NameInfo->QueryReferences & OBP_NAME_LOCKED) {
  820. //
  821. // The name is locked this means that the directory entry must be valid
  822. //
  823. ExAcquireReleasePushLockExclusive(&NameInfo->Directory->Lock);
  824. }
  825. return NameInfo;
  826. }
  827. return NULL;
  828. }
  829. VOID
  830. FORCEINLINE
  831. ObpDereferenceNameInfo(
  832. IN POBJECT_HEADER_NAME_INFO NameInfo
  833. )
  834. /*
  835. Routine Description:
  836. This function dereferences the name information structure. If the number of references
  837. drops to 0, the name is freed and the directory dereferenced
  838. Arguments:
  839. NameInfo - The pointer to the name info structure, as returned by ObpReferenceNameInfo.
  840. (NULL value is allowed)
  841. Return Value:
  842. None
  843. */
  844. {
  845. if ( (NameInfo != NULL)
  846. &&
  847. (InterlockedDecrement((PLONG)&NameInfo->QueryReferences) == 0)) {
  848. PVOID DirObject;
  849. //
  850. // Free the name buffer and zero out the name data fields
  851. //
  852. if (NameInfo->Name.Buffer != NULL) {
  853. ExFreePool( NameInfo->Name.Buffer );
  854. NameInfo->Name.Buffer = NULL;
  855. NameInfo->Name.Length = 0;
  856. NameInfo->Name.MaximumLength = 0;
  857. }
  858. DirObject = NameInfo->Directory;
  859. if (DirObject != NULL) {
  860. NameInfo->Directory = NULL;
  861. ObDereferenceObjectDeferDelete( DirObject );
  862. }
  863. }
  864. }
  865. VOID
  866. FORCEINLINE
  867. ObpLockDirectoryExclusive(
  868. IN POBJECT_DIRECTORY Directory,
  869. IN POBP_LOOKUP_CONTEXT LockContext
  870. )
  871. /*
  872. Routine Description:
  873. This Function locks exclusively the Directory. It is used for write access to
  874. the directory structure.
  875. Arguments:
  876. Directory - The directory being locked
  877. Return Value:
  878. None
  879. */
  880. {
  881. LockContext->LockStateSignature = OBP_LOCK_WAITEXCLUSIVE_SIGNATURE;
  882. KeEnterCriticalRegion();
  883. ExAcquirePushLockExclusive( &Directory->Lock );
  884. LockContext->LockStateSignature = OBP_LOCK_OWNEDEXCLUSIVE_SIGNATURE;
  885. }
  886. VOID
  887. FORCEINLINE
  888. ObpLockDirectoryShared (
  889. IN POBJECT_DIRECTORY Directory,
  890. IN POBP_LOOKUP_CONTEXT LockContext
  891. )
  892. /*
  893. Routine Description:
  894. This Function locks shared the Directory. It is used to read fields inside
  895. the directory structure.
  896. Arguments:
  897. Directory - The directory being locked
  898. Return Value:
  899. None
  900. */
  901. {
  902. LockContext->LockStateSignature = OBP_LOCK_WAITSHARED_SIGNATURE;
  903. KeEnterCriticalRegion();
  904. ExAcquirePushLockShared( &Directory->Lock );
  905. LockContext->LockStateSignature = OBP_LOCK_OWNEDSHARED_SIGNATURE;
  906. }
  907. VOID
  908. FORCEINLINE
  909. ObpUnlockDirectory(
  910. IN POBJECT_DIRECTORY Directory,
  911. IN POBP_LOOKUP_CONTEXT LockContext
  912. )
  913. /*
  914. Routine Description:
  915. This Function unlocks a Directory (previously locked exclusive or shared).
  916. Arguments:
  917. Directory - The directory that needs to be unlocked
  918. Return Value:
  919. None
  920. */
  921. {
  922. ExReleasePushLock( &Directory->Lock );
  923. LockContext->LockStateSignature = OBP_LOCK_RELEASED_SIGNATURE;
  924. KeLeaveCriticalRegion();
  925. }
  926. VOID
  927. FORCEINLINE
  928. ObpInitializeLookupContext(
  929. IN POBP_LOOKUP_CONTEXT LookupContext
  930. )
  931. /*
  932. Routine Description:
  933. This Function initialize a lookup context structure.
  934. Arguments:
  935. LookupContext - The LookupContext to be initialized
  936. Return Value:
  937. None
  938. */
  939. {
  940. LookupContext->DirectoryLocked = FALSE;
  941. LookupContext->Object = NULL;
  942. LookupContext->Directory = NULL;
  943. LookupContext->LockStateSignature = OBP_LOCK_UNUSED_SIGNATURE;
  944. }
  945. VOID
  946. FORCEINLINE
  947. ObpLockLookupContext (
  948. IN POBP_LOOKUP_CONTEXT LookupContext,
  949. IN POBJECT_DIRECTORY Directory
  950. )
  951. /*
  952. Routine Description:
  953. This function locks a lookup context. The directory
  954. is exclusively owned after this call and it's safe to access
  955. the directory in write mode. This function is intended to be used in
  956. insertion / deletion into/from the specified directory.
  957. The directory is unlocked at the next ObpReleaseLookupContext.
  958. Arguments:
  959. LookupContext - The LookupContext to be initialized
  960. Directory - The directory beling locked for exclusive access.
  961. Return Value:
  962. None
  963. */
  964. {
  965. ObpLockDirectoryExclusive(Directory, LookupContext);
  966. LookupContext->DirectoryLocked = TRUE;
  967. LookupContext->Directory = Directory;
  968. }
  969. VOID
  970. FORCEINLINE
  971. ObpReleaseLookupContext (
  972. IN POBP_LOOKUP_CONTEXT LookupContext
  973. )
  974. /*
  975. Routine Description:
  976. This function undoes the references and locking changes during these calls:
  977. ObpLockLookupContext and ObpLookupDirectoryEntry.
  978. N.B. If ObpLookupDirectoryEntry is called several times in a loop, each call
  979. will undo the references done at the previous call. ObpReleaseLookupContext
  980. should be called only ones at the end.
  981. Arguments:
  982. LookupContext - The LookupContext to be released
  983. Return Value:
  984. None
  985. */
  986. {
  987. //
  988. // If the context was locked we need to unlock the directory
  989. //
  990. if (LookupContext->DirectoryLocked) {
  991. ObpUnlockDirectory( LookupContext->Directory, LookupContext );
  992. LookupContext->Directory = NULL;
  993. LookupContext->DirectoryLocked = FALSE;
  994. }
  995. //
  996. // Remove the references added to the name info and object
  997. //
  998. if (LookupContext->Object) {
  999. POBJECT_HEADER_NAME_INFO NameInfo;
  1000. NameInfo = OBJECT_HEADER_TO_NAME_INFO(OBJECT_TO_OBJECT_HEADER(LookupContext->Object));
  1001. ObpDereferenceNameInfo( NameInfo );
  1002. ObDereferenceObject(LookupContext->Object);
  1003. LookupContext->Object = NULL;
  1004. }
  1005. }
  1006. NTSTATUS
  1007. ObpReferenceProcessObjectByHandle (
  1008. IN HANDLE Handle,
  1009. IN PEPROCESS Process,
  1010. IN PHANDLE_TABLE HandleTable,
  1011. IN KPROCESSOR_MODE AccessMode,
  1012. OUT PVOID *Object,
  1013. OUT POBJECT_HANDLE_INFORMATION HandleInformation,
  1014. OUT PACCESS_MASK AuditMask
  1015. );
  1016. VOID
  1017. FORCEINLINE
  1018. ObpLockAllObjects (
  1019. IN POBJECT_TYPE ObjectType
  1020. )
  1021. {
  1022. LONG i;
  1023. KeEnterCriticalRegion();
  1024. for (i = 0; i < OBJECT_LOCK_COUNT; i++) {
  1025. ExAcquireResourceExclusiveLite(&(ObjectType->ObjectLocks[i]), TRUE);
  1026. }
  1027. }
  1028. VOID
  1029. FORCEINLINE
  1030. ObpUnlockAllObjects (
  1031. IN POBJECT_TYPE ObjectType
  1032. )
  1033. {
  1034. LONG i;
  1035. for (i = OBJECT_LOCK_COUNT - 1; i >= 0; i--) {
  1036. ExReleaseResourceLite(&(ObjectType->ObjectLocks[i]));
  1037. }
  1038. KeLeaveCriticalRegion();
  1039. }