ReactOS 0.4.17-dev-579-gd2025ff
oblife.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for oblife.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

VOID FASTCALL ObpDeallocateObject (IN PVOID Object)
 
VOID NTAPI ObpDeleteObject (IN PVOID Object, IN BOOLEAN CalledFromWorkerThread)
 
VOID NTAPI ObpReapObject (IN PVOID Parameter)
 
VOID FASTCALL ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent)
 
PWCHAR NTAPI ObpAllocateObjectNameBuffer (IN ULONG Length, IN BOOLEAN UseLookaside, IN OUT PUNICODE_STRING ObjectName)
 
VOID NTAPI ObpFreeObjectNameBuffer (IN PUNICODE_STRING Name)
 
NTSTATUS NTAPI ObpCaptureObjectName (IN OUT PUNICODE_STRING CapturedName, IN PUNICODE_STRING ObjectName, IN KPROCESSOR_MODE AccessMode, IN BOOLEAN UseLookaside)
 
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)
 
VOID NTAPI ObFreeObjectCreateInfoBuffer (IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
 
NTSTATUS NTAPI ObpAllocateObject (IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN PUNICODE_STRING ObjectName, IN POBJECT_TYPE ObjectType, IN ULONG ObjectSize, IN KPROCESSOR_MODE PreviousMode, IN POBJECT_HEADER *ObjectHeader)
 
static ULONG ObpQueryNameInfoSize (_In_ POBJECT_HEADER ObjectHeader)
 Queries the name info size of a given resource object. The function loops through all the parent directories of the object and computes the name size.
 
NTSTATUS NTAPI ObQueryTypeInfo (_In_ POBJECT_TYPE ObjectType, _Out_writes_bytes_to_(Length, *ReturnLength) POBJECT_TYPE_INFORMATION ObjectTypeInfo, _In_ ULONG Length, _Out_ PULONG ReturnLength)
 
NTSTATUS NTAPI ObCreateObject (IN KPROCESSOR_MODE ProbeMode OPTIONAL, IN POBJECT_TYPE Type, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectSize, IN ULONG PagedPoolCharge OPTIONAL, IN ULONG NonPagedPoolCharge OPTIONAL, OUT PVOID *Object)
 
NTSTATUS NTAPI ObCreateObjectType (IN PUNICODE_STRING TypeName, IN POBJECT_TYPE_INITIALIZER ObjectTypeInitializer, IN PVOID Reserved, OUT POBJECT_TYPE *ObjectType)
 
VOID NTAPI ObDeleteCapturedInsertInfo (IN PVOID Object)
 
VOID NTAPI ObpDeleteObjectType (IN PVOID Object)
 
VOID NTAPI ObMakeTemporaryObject (IN PVOID ObjectBody)
 
NTSTATUS NTAPI NtMakeTemporaryObject (IN HANDLE ObjectHandle)
 
NTSTATUS NTAPI NtMakePermanentObject (IN HANDLE ObjectHandle)
 
NTSTATUS NTAPI NtQueryObject (IN HANDLE ObjectHandle, IN OBJECT_INFORMATION_CLASS ObjectInformationClass, OUT PVOID ObjectInformation, IN ULONG Length, OUT PULONG ResultLength OPTIONAL)
 
NTSTATUS NTAPI NtSetInformationObject (_In_ HANDLE ObjectHandle, _In_ OBJECT_INFORMATION_CLASS ObjectInformationClass, _In_reads_bytes_(Length) PVOID ObjectInformation, _In_ ULONG Length)
 Sets information for an object or for a handle to an object.
 

Variables

ULONG NtGlobalFlag
 
POBJECT_TYPE ObpTypeObjectType = NULL
 
KEVENT ObpDefaultObject
 
KGUARDED_MUTEX ObpDeviceMapLock
 
GENERAL_LOOKASIDE ObpNameBufferLookasideList
 
GENERAL_LOOKASIDE ObpCreateInfoLookasideList
 
WORK_QUEUE_ITEM ObpReaperWorkItem
 
volatile PVOID ObpReaperList
 
ULONG ObpObjectsCreated
 
ULONG ObpObjectsWithName
 
ULONG ObpObjectsWithPoolQuota
 
ULONG ObpObjectsWithHandleDB
 
ULONG ObpObjectsWithCreatorInfo
 
POBJECT_TYPE ObpObjectTypes [32]
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file oblife.c.

Function Documentation

◆ NtMakePermanentObject()

NTSTATUS NTAPI NtMakePermanentObject ( IN HANDLE  ObjectHandle)

Definition at line 1511 of file oblife.c.

1512{
1513 PVOID ObjectBody;
1516 PAGED_CODE();
1517
1518 /* Make sure that the caller has SeCreatePermanentPrivilege */
1520 {
1522 }
1523
1524 /* Reference the object */
1525 Status = ObReferenceObjectByHandle(ObjectHandle,
1526 0,
1527 NULL,
1529 &ObjectBody,
1530 NULL);
1531 if (Status != STATUS_SUCCESS) return Status;
1532
1533 /* Set it as permanent and dereference it */
1534 ObpSetPermanentObject(ObjectBody, TRUE);
1535 ObDereferenceObject(ObjectBody);
1536 return STATUS_SUCCESS;
1537}
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG _In_ KPROCESSOR_MODE PreviousMode
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ExGetPreviousMode
Definition: ex.h:143
Status
Definition: gdiplustypes.h:24
const LUID SeCreatePermanentPrivilege
Definition: priv.c:35
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
VOID FASTCALL ObpSetPermanentObject(IN PVOID ObjectBody, IN BOOLEAN Permanent)
Definition: oblife.c:267
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:493
#define STATUS_SUCCESS
Definition: shellext.h:65
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203

Referenced by CSR_API(), and test_object_permanence().

◆ NtMakeTemporaryObject()

NTSTATUS NTAPI NtMakeTemporaryObject ( IN HANDLE  ObjectHandle)

Definition at line 1474 of file oblife.c.

1475{
1476 PVOID ObjectBody;
1478 PAGED_CODE();
1479
1480 /* Reference the object for DELETE access */
1481 Status = ObReferenceObjectByHandle(ObjectHandle,
1482 DELETE,
1483 NULL,
1485 &ObjectBody,
1486 NULL);
1487 if (Status != STATUS_SUCCESS) return Status;
1488
1489 /* Set it as temporary and dereference it */
1490 ObpSetPermanentObject(ObjectBody, FALSE);
1491 ObDereferenceObject(ObjectBody);
1492 return STATUS_SUCCESS;
1493}
#define FALSE
Definition: types.h:117
#define KeGetPreviousMode()
Definition: ketypes.h:1115
#define DELETE
Definition: nt_native.h:57

Referenced by CSR_API(), DefineDosDeviceW(), IopReassignSystemRoot(), SmpInitializeDosDevices(), and test_object_permanence().

◆ NtQueryObject()

NTSTATUS NTAPI NtQueryObject ( IN HANDLE  ObjectHandle,
IN OBJECT_INFORMATION_CLASS  ObjectInformationClass,
OUT PVOID  ObjectInformation,
IN ULONG  Length,
OUT PULONG ResultLength  OPTIONAL 
)

Definition at line 1567 of file oblife.c.

1572{
1573 OBJECT_HANDLE_INFORMATION HandleInfo;
1574 POBJECT_HEADER ObjectHeader = NULL;
1576 POBJECT_BASIC_INFORMATION BasicInfo;
1577 ULONG InfoLength = 0;
1578 PVOID Object = NULL;
1580 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1584 PAGED_CODE();
1585
1586 /* Check if the caller is from user mode */
1587 if (PreviousMode != KernelMode)
1588 {
1589 /* Protect validation with SEH */
1590 _SEH2_TRY
1591 {
1592 /* Probe the input structure */
1594
1595 /* If we have a result length, probe it too */
1597 }
1599 {
1600 /* Return the exception code */
1602 }
1603 _SEH2_END;
1604 }
1605
1606 /*
1607 * Make sure this isn't a generic type query, since the caller doesn't
1608 * have to give a handle for it
1609 */
1611 {
1612 /* Reference the object */
1613 Status = ObReferenceObjectByHandle(ObjectHandle,
1614 0,
1615 NULL,
1617 &Object,
1618 &HandleInfo);
1619 if (!NT_SUCCESS (Status)) return Status;
1620
1621 /* Get the object header */
1622 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1623 ObjectType = ObjectHeader->Type;
1624 }
1625
1626 _SEH2_TRY
1627 {
1628 /* Check the information class */
1629 switch (ObjectInformationClass)
1630 {
1631 /* Basic info */
1633
1634 /* Validate length */
1635 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1636 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1637 {
1638 /* Fail */
1640 break;
1641 }
1642
1643 /* Fill out the basic information */
1645 BasicInfo->Attributes = HandleInfo.HandleAttributes;
1646 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1647 BasicInfo->HandleCount = ObjectHeader->HandleCount;
1648 BasicInfo->PointerCount = ObjectHeader->PointerCount;
1649
1650 /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1651 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1652 {
1653 /* Set the flag */
1654 BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1655 }
1656 if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1657 {
1658 /* Set the flag */
1659 BasicInfo->Attributes |= OBJ_PERMANENT;
1660 }
1661
1662 /* Copy quota information */
1663 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1664 if (ObjectQuota != NULL)
1665 {
1666 BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1667 BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1668 }
1669 else
1670 {
1671 BasicInfo->PagedPoolCharge = 0;
1672 BasicInfo->NonPagedPoolCharge = 0;
1673 }
1674
1675 /* Copy name information */
1676 BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader);
1677 BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length +
1678 sizeof(UNICODE_NULL);
1679
1680 /* Check if this is a symlink */
1681 if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1682 {
1683 /* Return the creation time */
1684 BasicInfo->CreationTime.QuadPart =
1685 ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1686 }
1687 else
1688 {
1689 /* Otherwise return 0 */
1690 BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1691 }
1692
1693 /* Copy security information */
1694 BasicInfo->SecurityDescriptorSize = 0;
1695 if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1696 ObjectHeader->SecurityDescriptor != NULL)
1697 {
1702
1703 ObjectType->TypeInfo.SecurityProcedure(Object,
1704 QuerySecurityDescriptor,
1706 NULL,
1707 &BasicInfo->SecurityDescriptorSize,
1708 &ObjectHeader->SecurityDescriptor,
1709 ObjectType->TypeInfo.PoolType,
1710 &ObjectType->TypeInfo.GenericMapping,
1712 }
1713
1714 /* Break out with success */
1716 break;
1717
1718 /* Name information */
1720
1721 /* Call the helper and break out */
1725 Length,
1726 &InfoLength);
1727 break;
1728
1729 /* Information about this type */
1731
1732 /* Call the helper and break out */
1733 Status = ObQueryTypeInfo(ObjectHeader->Type,
1736 Length,
1737 &InfoLength);
1738 break;
1739
1740 /* Information about all types */
1742 DPRINT1("NOT IMPLEMENTED!\n");
1743 InfoLength = Length;
1745 break;
1746
1747 /* Information about the handle flags */
1749
1750 /* Validate length */
1751 InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
1753 {
1755 break;
1756 }
1757
1758 /* Get the structure */
1761
1762 /* Set the flags */
1763 HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1764 HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1765 OBJ_PROTECT_CLOSE) != 0;
1766
1767 /* Break out with success */
1769 break;
1770
1771 /* Anything else */
1772 default:
1773
1774 /* Fail it */
1775 InfoLength = Length;
1777 break;
1778 }
1779
1780 /* Check if the caller wanted the return length */
1781 if (ResultLength)
1782 {
1783 /* Write the length */
1784 *ResultLength = InfoLength;
1785 }
1786 }
1788 {
1789 /* Otherwise, get the exception code */
1791 }
1792 _SEH2_END;
1793
1794 /* Dereference the object if we had referenced it */
1796
1797 /* Return status */
1798 return Status;
1799}
@ ObjectTypeInformation
Definition: DriverTester.h:56
@ ObjectBasicInformation
Definition: DriverTester.h:54
@ ObjectNameInformation
Definition: DriverTester.h:55
#define OBJ_PROTECT_CLOSE
#define ObpSymbolicLinkObjectType
Definition: ObTypes.cpp:171
#define DPRINT1
Definition: precomp.h:8
IN CINT ObjectInformationClass
Definition: conport.c:47
IN CINT OUT PVOID ObjectInformation
Definition: conport.c:48
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
VOID NTAPI ProbeForWrite(IN PVOID Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:143
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ SECURITY_INFORMATION SecurityInformation
Definition: fltkernel.h:1340
LONG NTAPI ExSystemExceptionFilter(VOID)
Definition: harderr.c:349
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
ObjectType
Definition: metafile.c:88
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define KernelMode
Definition: asm.h:38
struct _OBJECT_SYMBOLIC_LINK * POBJECT_SYMBOLIC_LINK
#define OB_FLAG_EXCLUSIVE
Definition: obtypes.h:100
#define OBJECT_HEADER_TO_QUOTA_INFO(h)
Definition: obtypes.h:122
struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION * POBJECT_HANDLE_ATTRIBUTE_INFORMATION
#define OB_FLAG_PERMANENT
Definition: obtypes.h:101
#define OBJECT_TO_OBJECT_HEADER(o)
Definition: obtypes.h:111
struct _OBJECT_TYPE_INFORMATION OBJECT_TYPE_INFORMATION
struct _OBJECT_HANDLE_ATTRIBUTE_INFORMATION OBJECT_HANDLE_ATTRIBUTE_INFORMATION
#define READ_CONTROL
Definition: nt_native.h:58
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:333
NTSTATUS NTAPI ObQueryTypeInfo(_In_ POBJECT_TYPE ObjectType, _Out_writes_bytes_to_(Length, *ReturnLength) POBJECT_TYPE_INFORMATION ObjectTypeInfo, _In_ ULONG Length, _Out_ PULONG ReturnLength)
Definition: oblife.c:948
static ULONG ObpQueryNameInfoSize(_In_ POBJECT_HEADER ObjectHeader)
Queries the name info size of a given resource object. The function loops through all the parent dire...
Definition: oblife.c:891
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
#define OBJ_INHERIT
Definition: winternl.h:225
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
ACCESS_MASK GrantedAccess
Definition: winternl.h:2680
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:505
UCHAR Flags
Definition: obtypes.h:499
LONG_PTR HandleCount
Definition: obtypes.h:492
LONG_PTR PointerCount
Definition: obtypes.h:489
POBJECT_TYPE Type
Definition: obtypes.h:495
unsigned char UCHAR
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFCOLLECTION _In_ WDFOBJECT Object
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG _Out_ PULONG ResultLength
Definition: wdfdevice.h:3782
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
@ ObjectHandleFlagInformation
Definition: winternl.h:1876
@ ObjectTypesInformation
Definition: winternl.h:1875
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
#define DACL_SECURITY_INFORMATION
Definition: setypes.h:125
#define OWNER_SECURITY_INFORMATION
Definition: setypes.h:123
#define GROUP_SECURITY_INFORMATION
Definition: setypes.h:124
#define SACL_SECURITY_INFORMATION
Definition: setypes.h:126

◆ NtSetInformationObject()

NTSTATUS NTAPI NtSetInformationObject ( _In_ HANDLE  ObjectHandle,
_In_ OBJECT_INFORMATION_CLASS  ObjectInformationClass,
_In_reads_bytes_(Length) PVOID  ObjectInformation,
_In_ ULONG  Length 
)

Sets information for an object or for a handle to an object.

Parameters
[in]ObjectHandleHandle to the target object. For the ObjectHandleFlagInformation class, this is the handle whose attributes are to be modified. For the ObjectSessionInformation class, this must be a handle to a directory object.
[in]ObjectInformationClassSpecifies the type of information to set. The only supported classes are: ObjectHandleFlagInformation and ObjectSessionInformation. (Windows 10 RS2 added support for ObjectSessionObjectInformation. Windows 11 25H2 added support for ObjectSetRefTraceInformation.)
[in]ObjectInformationPointer to a caller-supplied buffer containing the information to set. For the ObjectHandleFlagInformation class, this buffer must point to an OBJECT_HANDLE_ATTRIBUTE_INFORMATION structure describing the desired handle attributes (inherit and protect-from-close). For the ObjectSessionInformation class, this parameter is ignored.
[in]LengthThe size in bytes, of the buffer pointed to by ObjectInformation. For the ObjectHandleFlagInformation class, this must be sizeof(OBJECT_HANDLE_ATTRIBUTE_INFORMATION). For the ObjectSessionInformation class, this parameter is ignored.
Returns
STATUS_SUCCESS or an appropriate error value.
Remarks
This routine only supports the following classes:
  • ObjectHandleFlagInformation, to set the OBJ_INHERIT and OBJ_PROTECT_CLOSE attributes of a handle.
  • ObjectSessionInformation, to associate a directory object with the caller's current session identifier; this requires the SeTcbPrivilege.

ObjectHandleFlagInformation operates on per-handle state rather than on the underlying object itself.

Definition at line 1846 of file oblife.c.

1851{
1854
1855 PAGED_CODE();
1856
1857 /* Validate the information class */
1858 switch (ObjectInformationClass)
1859 {
1861 {
1863
1864 /* Validate the length */
1865 if (Length != sizeof(HandleFlags))
1867
1868 /* Save the previous mode */
1870
1871 /* If we were called from user mode, probe and capture the
1872 * attribute buffer, otherwise just copy it directly. */
1873 if (PreviousMode != KernelMode)
1874 {
1875 _SEH2_TRY
1876 {
1877 ProbeForRead(ObjectInformation, sizeof(HandleFlags), sizeof(BOOLEAN));
1879 }
1881 {
1882 /* Return the exception code */
1884 }
1885 _SEH2_END;
1886 }
1887 else
1888 {
1890 }
1891
1892 Status = ObSetHandleAttributes(ObjectHandle, &HandleFlags, PreviousMode);
1893 break;
1894 }
1895
1897 {
1899
1902
1903 /* Only a system process can do this */
1906 {
1907 DPRINT1("Privilege not held\n");
1909 }
1910
1911 /* Get the object directory */
1912 Status = ObReferenceObjectByHandle(ObjectHandle,
1913 0,
1916 (PVOID*)&Directory,
1917 NULL);
1918 if (NT_SUCCESS(Status))
1919 {
1920 /* Setup a lookup context */
1921 OBP_LOOKUP_CONTEXT LookupContext;
1922 ObpInitializeLookupContext(&LookupContext);
1923
1924 /* Set the directory session ID */
1927 ObpReleaseDirectoryLock(Directory, &LookupContext);
1928
1929 /* We're done, release the context and dereference the directory */
1930 ObpReleaseLookupContext(&LookupContext);
1932 }
1933 break;
1934 }
1935
1936 default:
1937 /* Unsupported class */
1939 break;
1940 }
1941
1942 return Status;
1943}
#define ObpDirectoryObjectType
Definition: ObTypes.cpp:170
unsigned char BOOLEAN
Definition: actypes.h:127
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
_In_ BOOLEAN _In_ USHORT Directory
Definition: rtlfuncs.h:3942
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
const LUID SeTcbPrivilege
Definition: priv.c:26
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
FORCEINLINE VOID ObpAcquireDirectoryLockExclusive(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Locks a directory for exclusive access. Used for writing/reading members of the directory object.
Definition: ob_x.h:212
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 ObpReleaseDirectoryLock(IN POBJECT_DIRECTORY Directory, IN POBP_LOOKUP_CONTEXT Context)
Unlocks a previously shared or exclusively locked directory.
Definition: ob_x.h:238
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 ObSetHandleAttributes(_In_ HANDLE Handle, _In_ POBJECT_HANDLE_ATTRIBUTE_INFORMATION HandleFlags, _In_ KPROCESSOR_MODE PreviousMode)
Sets the attributes (inheritable and protect-from-close) of an existing object handle.
Definition: obhandle.c:3327
@ ObjectSessionInformation
Definition: winternl.h:1877

Referenced by BaseInitializeStaticServerData(), ProtectHandle(), SetHandleInformation(), SockCreateOrReferenceAsyncThread(), SockGetAsyncSelectHelperAfdHandle(), and UnProtectHandle().

◆ ObCreateObject()

NTSTATUS NTAPI ObCreateObject ( IN KPROCESSOR_MODE ProbeMode  OPTIONAL,
IN POBJECT_TYPE  Type,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN KPROCESSOR_MODE  AccessMode,
IN OUT PVOID ParseContext  OPTIONAL,
IN ULONG  ObjectSize,
IN ULONG PagedPoolCharge  OPTIONAL,
IN ULONG NonPagedPoolCharge  OPTIONAL,
OUT PVOID Object 
)

Definition at line 1040 of file oblife.c.

1049{
1051 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
1054
1055 /* Allocate a capture buffer */
1057 if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
1058
1059 /* Capture all the info */
1061 ProbeMode,
1062 AccessMode,
1063 FALSE,
1064 ObjectCreateInfo,
1065 &ObjectName);
1066 if (NT_SUCCESS(Status))
1067 {
1068 /* Validate attributes */
1069 if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
1070 {
1071 /* Fail */
1073 }
1074 else
1075 {
1076 /* Check if we have a paged charge */
1077 if (!PagedPoolCharge)
1078 {
1079 /* Save it */
1080 PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
1081 }
1082
1083 /* Check for nonpaged charge */
1084 if (!NonPagedPoolCharge)
1085 {
1086 /* Save it */
1087 NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1088 }
1089
1090 /* Write the pool charges */
1091 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1092 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1093
1094 /* Allocate the Object */
1095 Status = ObpAllocateObject(ObjectCreateInfo,
1096 &ObjectName,
1097 Type,
1098 ObjectSize,
1099 AccessMode,
1100 &Header);
1101 if (NT_SUCCESS(Status))
1102 {
1103 /* Return the Object */
1104 *Object = &Header->Body;
1105
1106 /* Check if this is a permanent object */
1107 if (Header->Flags & OB_FLAG_PERMANENT)
1108 {
1109 /* Do the privilege check */
1111 ProbeMode))
1112 {
1113 /* Fail */
1116 }
1117 }
1118
1119 /* Return status */
1120 return Status;
1121 }
1122 }
1123
1124 /* Release the Capture Info, we don't need it */
1125 ObpFreeObjectCreateInformation(ObjectCreateInfo);
1127 return Status;
1128 }
1129
1130 /* We failed, so release the Buffer */
1132 return Status;
1133}
Type
Definition: Type.h:7
Definition: Header.h:9
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
@ LookasideCreateInfoList
Definition: mmtypes.h:171
FORCEINLINE PVOID ObpAllocateObjectCreateInfoBuffer(IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:379
FORCEINLINE VOID ObpFreeCapturedAttributes(IN PVOID Buffer, IN PP_NPAGED_LOOKASIDE_NUMBER Type)
Definition: ob_x.h:416
FORCEINLINE VOID ObpFreeObjectCreateInformation(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)
Definition: ob_x.h:460
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: oblife.c:456
NTSTATUS NTAPI ObpAllocateObject(IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN PUNICODE_STRING ObjectName, IN POBJECT_TYPE ObjectType, IN ULONG ObjectSize, IN KPROCESSOR_MODE PreviousMode, IN POBJECT_HEADER *ObjectHeader)
Definition: oblife.c:612
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:347
VOID FASTCALL ObpDeallocateObject(IN PVOID Object)
Definition: oblife.c:39
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
_Must_inspect_result_ _In_ _In_ ULONG ProbeMode
Definition: mmfuncs.h:561
_In_ PEPROCESS _In_ KPROCESSOR_MODE AccessMode
Definition: mmfuncs.h:396

Referenced by _IRQL_requires_max_(), CmpCreateRegistryRoot(), CmpDoCreateChild(), CmpDoOpen(), CreateClientPort(), ExCreateCallback(), HalpDmaAllocateChildAdapter(), IntCreateWindowStation(), IntDesktopObjectParse(), IoCreateController(), IoCreateDevice(), IoCreateDriver(), IoCreateStreamFileObjectEx(), IoCreateStreamFileObjectLite(), IopInitializeDriverModule(), IopParseDevice(), LpcpCreatePort(), MmCreateArm3Section(), MmCreateDataFileSection(), MmCreateImageSection(), MmCreatePhysicalMemorySection(), NtCreateDebugObject(), NtCreateDirectoryObject(), NtCreateEvent(), NtCreateEventPair(), NtCreateIoCompletion(), NtCreateJobObject(), NtCreateMutant(), NtCreateProfile(), NtCreateSemaphore(), NtCreateSymbolicLinkObject(), NtCreateTimer(), NtSecureConnectPort(), ObtCreateObjects(), PspCreateProcess(), PspCreateThread(), SepCreateToken(), SepDuplicateToken(), SepPerformTokenFiltering(), and WmipCreateGuidObject().

◆ ObCreateObjectType()

NTSTATUS NTAPI ObCreateObjectType ( IN PUNICODE_STRING  TypeName,
IN POBJECT_TYPE_INITIALIZER  ObjectTypeInitializer,
IN PVOID  Reserved,
OUT POBJECT_TYPE ObjectType 
)

Definition at line 1137 of file oblife.c.

1141{
1143 POBJECT_TYPE LocalObjectType;
1144 ULONG HeaderSize;
1147 PWCHAR p;
1148 ULONG i;
1150 ANSI_STRING AnsiName;
1151 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1152
1153 /* Verify parameters */
1154 if (!(TypeName) ||
1155 !(TypeName->Length) ||
1156 (TypeName->Length % sizeof(WCHAR)) ||
1157 !(ObjectTypeInitializer) ||
1158 (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1159 (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1160 (ObjectTypeInitializer->MaintainHandleCount &&
1161 (!(ObjectTypeInitializer->OpenProcedure) &&
1162 !ObjectTypeInitializer->CloseProcedure)) ||
1163 ((!ObjectTypeInitializer->UseDefaultObject) &&
1164 (ObjectTypeInitializer->PoolType != NonPagedPool)))
1165 {
1166 /* Fail */
1168 }
1169
1170 /* Make sure the name doesn't have a separator */
1171 p = TypeName->Buffer;
1172 i = TypeName->Length / sizeof(WCHAR);
1173 while (i--)
1174 {
1175 /* Check for one and fail */
1177 }
1178
1179 /* Setup a lookup context */
1181
1182 /* Check if we've already created the directory of types */
1184 {
1185 /* Lock the lookup context */
1187
1188 /* Do the lookup */
1190 TypeName,
1192 FALSE,
1193 &Context))
1194 {
1195 /* We have already created it, so fail */
1198 }
1199 }
1200
1201 /* Now make a copy of the object name */
1203 TypeName->MaximumLength,
1204 OB_NAME_TAG);
1205 if (!ObjectName.Buffer)
1206 {
1207 /* Out of memory, fail */
1210 }
1211
1212 /* Set the length and copy the name */
1213 ObjectName.MaximumLength = TypeName->MaximumLength;
1214 RtlCopyUnicodeString(&ObjectName, TypeName);
1215
1216 /* Allocate the Object */
1218 &ObjectName,
1220 sizeof(OBJECT_TYPE),
1221 KernelMode,
1222 &Header);
1223 if (!NT_SUCCESS(Status))
1224 {
1225 /* Free the name and fail */
1227 ExFreePool(ObjectName.Buffer);
1228 return Status;
1229 }
1230
1231 /* Setup the flags and name */
1232 LocalObjectType = (POBJECT_TYPE)&Header->Body;
1233 LocalObjectType->Name = ObjectName;
1235
1236 /* Clear accounting data */
1237 LocalObjectType->TotalNumberOfObjects =
1238 LocalObjectType->TotalNumberOfHandles =
1239 LocalObjectType->HighWaterNumberOfObjects =
1240 LocalObjectType->HighWaterNumberOfHandles = 0;
1241
1242 /* Check if this is the first Object Type */
1244 {
1245 /* It is, so set this as the type object */
1246 ObpTypeObjectType = LocalObjectType;
1247 Header->Type = ObpTypeObjectType;
1248
1249 /* Set the hard-coded key and object count */
1250 LocalObjectType->TotalNumberOfObjects = 1;
1251 LocalObjectType->Key = TAG_OBJECT_TYPE;
1252 }
1253 else
1254 {
1255 /* Convert the tag to ASCII */
1256 Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1257 if (NT_SUCCESS(Status))
1258 {
1259 /* For every missing character, use a space */
1260 for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1261
1262 /* Set the key and free the converted name */
1263 LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1264 RtlFreeAnsiString(&AnsiName);
1265 }
1266 else
1267 {
1268 /* Just copy the characters */
1269 LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1270 }
1271 }
1272
1273 /* Set up the type information */
1274 LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1275 LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1276
1277 /* Check if we have to maintain a type list */
1279 {
1280 /* Enable support */
1281 LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1282 }
1283
1284 /* Calculate how much space our header'll take up */
1285 HeaderSize = sizeof(OBJECT_HEADER) +
1286 sizeof(OBJECT_HEADER_NAME_INFO) +
1287 (ObjectTypeInitializer->MaintainHandleCount ?
1288 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1289
1290 /* Check the pool type */
1291 if (ObjectTypeInitializer->PoolType == NonPagedPool)
1292 {
1293 /* Update the NonPaged Pool charge */
1294 LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1295 }
1296 else
1297 {
1298 /* Update the Paged Pool charge */
1299 LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1300 }
1301
1302 /* All objects types need a security procedure */
1303 if (!ObjectTypeInitializer->SecurityProcedure)
1304 {
1306 }
1307
1308 /* Select the Wait Object */
1309 if (LocalObjectType->TypeInfo.UseDefaultObject)
1310 {
1311 /* Add the SYNCHRONIZE access mask since it's waitable */
1312 LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1313
1314 /* Use the "Default Object", a simple event */
1315 LocalObjectType->DefaultObject = &ObpDefaultObject;
1316 }
1317 /* The File Object gets an optimized hack so it can be waited on */
1318 else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1319 {
1320 /* Wait on the File Object's event directly */
1322 Event));
1323 }
1324 else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1325 {
1326 /* Wait on the LPC Port's object directly */
1328 WaitEvent));
1329 }
1330 else
1331 {
1332 /* No default Object */
1333 LocalObjectType->DefaultObject = NULL;
1334 }
1335
1336 /* Initialize Object Type components */
1337 ExInitializeResourceLite(&LocalObjectType->Mutex);
1338 for (i = 0; i < 4; i++)
1339 {
1340 /* Initialize the object locks */
1341 ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1342 }
1343 InitializeListHead(&LocalObjectType->TypeList);
1344
1345 /* Lock the object type */
1347
1348 /* Get creator info and insert it into the type list */
1350 if (CreatorInfo)
1351 {
1353 &CreatorInfo->TypeList);
1354
1355 /* CORE-8423: Avoid inserting this a second time if someone creates a
1356 * handle to the object type (bug in Windows 2003) */
1357 Header->Flags &= ~OB_FLAG_CREATE_INFO;
1358 }
1359
1360 /* Set the index and the entry into the object type array */
1361 LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1362
1363 ASSERT(LocalObjectType->Index != 0);
1364
1365 if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1366 {
1367 /* It fits, insert it */
1368 ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1369 }
1370
1371 /* Release the object type */
1373
1374 /* Check if we're actually creating the directory object itself */
1375 if (!(ObpTypeDirectoryObject) ||
1377 {
1378 /* Check if the type directory exists */
1380 {
1381 /* Reference it */
1383 }
1384
1385 /* Cleanup the lookup context */
1387
1388 /* Return the object type and success */
1389 *ObjectType = LocalObjectType;
1390 return STATUS_SUCCESS;
1391 }
1392
1393 /* If we got here, then we failed */
1396}
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
#define L(x)
Definition: resources.c:13
#define UlongToPtr(u)
Definition: config.h:106
#define InsertTailList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
GLfloat GLfloat p
Definition: glext.h:8902
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
#define FLG_MAINTAIN_OBJECT_TYPELIST
Definition: pstypes.h:64
if(dx< 0)
Definition: linetemp.h:194
#define ASSERT(a)
Definition: mode.c:44
#define OBJECT_HEADER_TO_CREATOR_INFO(h)
Definition: obtypes.h:126
#define OB_FLAG_KERNEL_MODE
Definition: obtypes.h:98
struct _OBJECT_HEADER OBJECT_HEADER
#define OBJ_VALID_KERNEL_ATTRIBUTES
Definition: obtypes.h:92
struct _OBJECT_HEADER_HANDLE_INFO OBJECT_HEADER_HANDLE_INFO
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
struct _OBJECT_TYPE * POBJECT_TYPE
Definition: nt_native.h:34
OBJECT_TYPE
Definition: ntobjenum.h:13
@ FILE_OBJECT
Definition: ntobjenum.h:17
NTSTATUS NTAPI SeDefaultObjectMethod(_In_ PVOID Object, _In_ SECURITY_OPERATION_CODE OperationType, _In_ PSECURITY_INFORMATION SecurityInformation, _Inout_opt_ PSECURITY_DESCRIPTOR SecurityDescriptor, _Inout_opt_ PULONG ReturnLength, _Inout_opt_ PSECURITY_DESCRIPTOR *OldSecurityDescriptor, _In_ POOL_TYPE PoolType, _In_ PGENERIC_MAPPING GenericMapping, _In_ KPROCESSOR_MODE AccessMode)
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN BOOLEAN 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
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 ObpLeaveObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:352
FORCEINLINE VOID ObpEnterObjectTypeMutex(IN POBJECT_TYPE ObjectType)
Definition: ob_x.h:340
POBJECT_TYPE ObpTypeObjectType
Definition: oblife.c:22
POBJECT_TYPE ObpObjectTypes[32]
Definition: oblife.c:33
ULONG NtGlobalFlag
Definition: init.c:54
KEVENT ObpDefaultObject
Definition: oblife.c:23
short WCHAR
Definition: pedump.c:58
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_In_ PVOID Context
Definition: storport.h:2269
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:373
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:367
ULONG TotalNumberOfHandles
Definition: obtypes.h:389
ULONG Index
Definition: obtypes.h:387
LIST_ENTRY TypeList
Definition: obtypes.h:384
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:390
ULONG TotalNumberOfObjects
Definition: obtypes.h:388
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:392
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:394
ERESOURCE Mutex
Definition: obtypes.h:383
ULONG Key
Definition: obtypes.h:393
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:391
UNICODE_STRING Name
Definition: obtypes.h:385
PVOID DefaultObject
Definition: obtypes.h:386
#define OB_NAME_TAG
Definition: tag.h:118
#define TAG_OBJECT_TYPE
Definition: tag.h:122
uint32_t * PULONG
Definition: typedefs.h:59
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define ObReferenceObject
Definition: obfuncs.h:204

Referenced by _IRQL_requires_max_(), CmpCreateObjectTypes(), DbgkInitialize(), ExpInitializeCallbacks(), ExpInitializeEventImplementation(), ExpInitializeEventPairImplementation(), ExpInitializeMutantImplementation(), ExpInitializeProfileImplementation(), ExpInitializeSemaphoreImplementation(), ExpInitializeTimerImplementation(), ExpWin32kInit(), FltpSetupCommunicationObjects(), IopCreateObjectTypes(), LpcInitSystem(), MmInitSectionImplementation(), ObInitSystem(), ObtCreateObjectTypes(), PspInitPhase0(), SepInitializeTokenImplementation(), and WmipInitializeGuidObjectType().

◆ ObDeleteCapturedInsertInfo()

VOID NTAPI ObDeleteCapturedInsertInfo ( IN PVOID  Object)

Definition at line 1400 of file oblife.c.

1401{
1402 POBJECT_HEADER ObjectHeader;
1403 PAGED_CODE();
1404
1405 /* Check if there is anything to free */
1406 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1407 if ((ObjectHeader->Flags & OB_FLAG_CREATE_INFO) &&
1408 (ObjectHeader->ObjectCreateInfo != NULL))
1409 {
1410 /* Free the create info */
1412 ObjectHeader->ObjectCreateInfo = NULL;
1413 }
1414}
#define OB_FLAG_CREATE_INFO
Definition: obtypes.h:97
POBJECT_CREATE_INFORMATION ObjectCreateInfo
Definition: obtypes.h:502

◆ ObFreeObjectCreateInfoBuffer()

VOID NTAPI ObFreeObjectCreateInfoBuffer ( IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo)

Definition at line 604 of file oblife.c.

605{
606 /* Call the macro. We use this function to isolate Ob internals from Io */
608}

Referenced by IoCreateStreamFileObjectLite().

◆ ObMakeTemporaryObject()

VOID NTAPI ObMakeTemporaryObject ( IN PVOID  ObjectBody)

Definition at line 1450 of file oblife.c.

1451{
1452 PAGED_CODE();
1453
1454 /* Call the internal API */
1455 ObpSetPermanentObject(ObjectBody, FALSE);
1456}

Referenced by FltpSetupCommunicationObjects(), IoCreateDriver(), IoDeleteDevice(), IopInitializeDriverModule(), IopUnloadDevice(), IopUnloadDriver(), KdpDriverReinit(), and ObfDereferenceDeviceMap().

◆ ObpAllocateObject()

NTSTATUS NTAPI ObpAllocateObject ( IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo,
IN PUNICODE_STRING  ObjectName,
IN POBJECT_TYPE  ObjectType,
IN ULONG  ObjectSize,
IN KPROCESSOR_MODE  PreviousMode,
IN POBJECT_HEADER ObjectHeader 
)

Definition at line 612 of file oblife.c.

618{
620 ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
623 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
626 ULONG FinalSize;
627 ULONG Tag;
628 PAGED_CODE();
629
630 /* Accounting */
632
633 /* Check if we don't have an Object Type yet */
634 if (!ObjectType)
635 {
636 /* Use default tag and non-paged pool */
639 }
640 else
641 {
642 /* Use the pool and tag given */
643 PoolType = ObjectType->TypeInfo.PoolType;
644 Tag = ObjectType->Key;
645 }
646
647 /* Check if we have no create information (ie: we're an object type) */
648 if (!ObjectCreateInfo)
649 {
650 /* Use defaults */
651 QuotaSize = HandleSize = 0;
652 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
653 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
654 }
655 else
656 {
657 /* Check if we have quota */
658 if ((((ObjectCreateInfo->PagedPoolCharge !=
659 ObjectType->TypeInfo.DefaultPagedPoolCharge) ||
660 (ObjectCreateInfo->NonPagedPoolCharge !=
661 ObjectType->TypeInfo.DefaultNonPagedPoolCharge) ||
662 (ObjectCreateInfo->SecurityDescriptorCharge > 2048)) &&
664 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
665 {
666 /* Set quota size */
667 QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO);
669 }
670 else
671 {
672 /* No Quota */
673 QuotaSize = 0;
674 }
675
676 /* Check if we have a handle database */
677 if (ObjectType->TypeInfo.MaintainHandleCount)
678 {
679 /* Set handle database size */
680 HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO);
682 }
683 else
684 {
685 /* None */
686 HandleSize = 0;
687 }
688
689 /* Check if the Object has a name */
690 if (ObjectName->Buffer)
691 {
692 /* Set name size */
693 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
695 }
696 else
697 {
698 /* No name */
699 NameSize = 0;
700 }
701
702 /* Check if the Object maintains type lists */
703 if (ObjectType->TypeInfo.MaintainTypeList)
704 {
705 /* Set owner/creator size */
706 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
708 }
709 else
710 {
711 /* No info */
712 CreatorSize = 0;
713 }
714 }
715
716 /* Set final header size */
717 FinalSize = QuotaSize +
718 HandleSize +
719 NameSize +
720 CreatorSize +
722
723 /* Allocate memory for the Object and Header */
724 Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
726
727 /* Check if we have a quota header */
728 if (QuotaSize)
729 {
730 /* Initialize quota info */
732 QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge;
733 QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge;
734 QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge;
735 QuotaInfo->ExclusiveProcess = NULL;
736 Header = (POBJECT_HEADER)(QuotaInfo + 1);
737 }
738
739 /* Check if we have a handle database header */
740 if (HandleSize)
741 {
742 /* Initialize Handle Info */
744 HandleInfo->SingleEntry.HandleCount = 0;
745 Header = (POBJECT_HEADER)(HandleInfo + 1);
746 }
747
748 /* Check if we have a name header */
749 if (NameSize)
750 {
751 /* Initialize the Object Name Info */
753 NameInfo->Name = *ObjectName;
754 NameInfo->Directory = NULL;
755 NameInfo->QueryReferences = 1;
756
757 /* Check if this is a call with the special protection flag */
758 if ((PreviousMode == KernelMode) &&
759 (ObjectCreateInfo) &&
760 (ObjectCreateInfo->Attributes & OBJ_KERNEL_EXCLUSIVE))
761 {
762 /* Set flag which will make the object protected from user-mode */
764 }
765
766 /* Set the header pointer */
767 Header = (POBJECT_HEADER)(NameInfo + 1);
768 }
769
770 /* Check if we have a creator header */
771 if (CreatorSize)
772 {
773 /* Initialize Creator Info */
774 CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
775 CreatorInfo->CreatorBackTraceIndex = 0;
777 InitializeListHead(&CreatorInfo->TypeList);
778 Header = (POBJECT_HEADER)(CreatorInfo + 1);
779 }
780
781 /* Check for quota information */
782 if (QuotaSize)
783 {
784 /* Set the offset */
785 Header->QuotaInfoOffset = (UCHAR)(QuotaSize +
786 HandleSize +
787 NameSize +
788 CreatorSize);
789 }
790 else
791 {
792 /* No offset */
793 Header->QuotaInfoOffset = 0;
794 }
795
796 /* Check for handle information */
797 if (HandleSize)
798 {
799 /* Set the offset */
800 Header->HandleInfoOffset = (UCHAR)(HandleSize +
801 NameSize +
802 CreatorSize);
803 }
804 else
805 {
806 /* No offset */
807 Header->HandleInfoOffset = 0;
808 }
809
810 /* Check for name information */
811 if (NameSize)
812 {
813 /* Set the offset */
814 Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize);
815 }
816 else
817 {
818 /* No Name */
819 Header->NameInfoOffset = 0;
820 }
821
822 /* Set the new object flag */
824
825 /* Remember if we have creator info */
826 if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO;
827
828 /* Remember if we have handle info */
829 if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS;
830
831 /* Initialize the object header */
832 Header->PointerCount = 1;
833 Header->HandleCount = 0;
834 Header->Type = ObjectType;
835 Header->ObjectCreateInfo = ObjectCreateInfo;
836 Header->SecurityDescriptor = NULL;
837
838 /* Check if this is a permanent object */
839 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
840 {
841 /* Set the needed flag so we can check */
842 Header->Flags |= OB_FLAG_PERMANENT;
843 }
844
845 /* Check if this is an exclusive object */
846 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
847 {
848 /* Set the needed flag so we can check */
849 Header->Flags |= OB_FLAG_EXCLUSIVE;
850 }
851
852 /* Set kernel-mode flag */
854
855 /* Check if we have a type */
856 if (ObjectType)
857 {
858 /* Increase the number of objects of this type */
859 InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfObjects);
860
861 /* Update the high water */
862 ObjectType->HighWaterNumberOfObjects = max(ObjectType->
863 TotalNumberOfObjects,
864 ObjectType->
865 HighWaterNumberOfObjects);
866 }
867
868 /* Return Header */
869 *ObjectHeader = Header;
870 return STATUS_SUCCESS;
871}
#define InterlockedIncrement
Definition: armddk.h:53
#define OB_FLAG_SINGLE_PROCESS
Definition: obtypes.h:103
struct _OBJECT_HEADER_CREATOR_INFO * POBJECT_HEADER_CREATOR_INFO
struct _OBJECT_HEADER_QUOTA_INFO * POBJECT_HEADER_QUOTA_INFO
#define OB_FLAG_KERNEL_EXCLUSIVE
Definition: obtypes.h:109
struct _OBJECT_HEADER_HANDLE_INFO * POBJECT_HEADER_HANDLE_INFO
#define OB_FLAG_CREATOR_INFO
Definition: obtypes.h:99
struct _OBJECT_HEADER_CREATOR_INFO OBJECT_HEADER_CREATOR_INFO
struct _OBJECT_HEADER_NAME_INFO * POBJECT_HEADER_NAME_INFO
struct _OBJECT_HEADER_NAME_INFO OBJECT_HEADER_NAME_INFO
struct _OBJECT_HEADER * POBJECT_HEADER
struct _OBJECT_HEADER_QUOTA_INFO OBJECT_HEADER_QUOTA_INFO
#define OBJ_KERNEL_EXCLUSIVE
Definition: obtypes.h:91
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
ULONG ObpObjectsWithPoolQuota
Definition: oblife.c:31
ULONG ObpObjectsWithCreatorInfo
Definition: oblife.c:32
ULONG ObpObjectsCreated
Definition: oblife.c:31
ULONG ObpObjectsWithHandleDB
Definition: oblife.c:32
ULONG ObpObjectsWithName
Definition: oblife.c:31
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
ULONG HandleCount
Definition: obtypes.h:447
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:461
POBJECT_DIRECTORY Directory
Definition: obtypes.h:434
UNICODE_STRING Name
Definition: obtypes.h:435
PEPROCESS ExclusiveProcess
Definition: obtypes.h:478
#define max(a, b)
Definition: svc.c:63
INT POOL_TYPE
Definition: typedefs.h:78
int32_t * PLONG
Definition: typedefs.h:58
_Must_inspect_result_ _In_ WDFDEVICE _In_ BOOLEAN _In_opt_ PVOID Tag
Definition: wdfdevice.h:4071
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3821
#define PsGetCurrentProcess
Definition: psfuncs.h:17

Referenced by ObCreateObject(), and ObCreateObjectType().

◆ ObpAllocateObjectNameBuffer()

PWCHAR NTAPI ObpAllocateObjectNameBuffer ( IN ULONG  Length,
IN BOOLEAN  UseLookaside,
IN OUT PUNICODE_STRING  ObjectName 
)

Definition at line 302 of file oblife.c.

305{
308
309 /* Set the maximum length to the length plus the terminator */
311
312 /* Check if we should use the lookaside buffer */
313 if (!(UseLookaside) || (MaximumLength > OBP_NAME_LOOKASIDE_MAX_SIZE))
314 {
315 /* Nope, allocate directly from pool */
316 /* Since we later use MaximumLength to detect that we're not allocating
317 * from a list, we need at least MaximumLength + sizeof(UNICODE_NULL)
318 * here.
319 *
320 * People do call this with UseLookasideList FALSE so the distinction
321 * is critical.
322 */
324 {
326 }
330 }
331 else
332 {
333 /* Allocate from the lookaside */
336 }
337
338 /* Setup the string */
339 ObjectName->MaximumLength = (USHORT)MaximumLength;
340 ObjectName->Length = (USHORT)Length;
341 ObjectName->Buffer = Buffer;
342 return Buffer;
343}
Definition: bufpool.h:45
@ LookasideNameBufferList
Definition: mmtypes.h:172
#define OBP_NAME_LOOKASIDE_MAX_SIZE
Definition: ob_x.h:18
unsigned short USHORT
Definition: pedump.c:61
_In_ WDFDMATRANSACTION _In_ size_t MaximumLength

Referenced by ObpCaptureObjectName().

◆ 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 456 of file oblife.c.

462{
463 ULONG SdCharge, QuotaInfoSize;
467 PUNICODE_STRING LocalObjectName = NULL;
468 PAGED_CODE();
469
470 /* Zero out the Capture Data */
471 RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION));
472
473 /* SEH everything here for protection */
475 {
476 /* Check if we got attributes */
478 {
479 /* Check if we're in user mode */
480 if (AccessMode != KernelMode)
481 {
482 /* Probe the attributes */
484 sizeof(OBJECT_ATTRIBUTES),
485 sizeof(ULONG));
486 }
487
488 /* Validate the Size and Attributes */
489 if ((ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES)) ||
491 {
492 /* Invalid combination, fail */
494 }
495
496 /* Set some Create Info and do not allow user-mode kernel handles */
497 ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory;
498 ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_KERNEL_ATTRIBUTES;
499 if (CreatorMode != KernelMode) ObjectCreateInfo->Attributes &= ~OBJ_KERNEL_HANDLE;
500 LocalObjectName = ObjectAttributes->ObjectName;
501 SecurityDescriptor = ObjectAttributes->SecurityDescriptor;
502 SecurityQos = ObjectAttributes->SecurityQualityOfService;
503
504 /* Check if we have a security descriptor */
506 {
507 /* Capture it. Note: This has an implicit memory barrier due
508 to the function call, so cleanup is safe here.) */
512 TRUE,
513 &ObjectCreateInfo->
515 if (!NT_SUCCESS(Status))
516 {
517 /* Capture failed, quit */
518 ObjectCreateInfo->SecurityDescriptor = NULL;
519 _SEH2_YIELD(return Status);
520 }
521
522 /*
523 * By default, assume a SD size of 1024 and allow twice its
524 * size.
525 * If SD size happen to be bigger than that, then allow it
526 */
527 SdCharge = 2048;
528 SeComputeQuotaInformationSize(ObjectCreateInfo->SecurityDescriptor,
529 &QuotaInfoSize);
530 if ((2 * QuotaInfoSize) > 2048)
531 {
532 SdCharge = 2 * QuotaInfoSize;
533 }
534
535 /* Save the probe mode and security descriptor size */
536 ObjectCreateInfo->SecurityDescriptorCharge = SdCharge;
537 ObjectCreateInfo->ProbeMode = AccessMode;
538 }
539
540 /* Check if we have QoS */
541 if (SecurityQos)
542 {
543 /* Check if we came from user mode */
544 if (AccessMode != KernelMode)
545 {
546 /* Validate the QoS */
547 ProbeForRead(SecurityQos,
549 sizeof(ULONG));
550 }
551
552 /* Save Info */
553 ObjectCreateInfo->SecurityQualityOfService = *SecurityQos;
554 ObjectCreateInfo->SecurityQos =
555 &ObjectCreateInfo->SecurityQualityOfService;
556 }
557 }
558 else
559 {
560 /* We don't have a name */
561 LocalObjectName = NULL;
562 }
563 }
565 {
566 /* Cleanup and return the exception code */
567 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
569 }
570 _SEH2_END;
571
572 /* Now check if the Object Attributes had an Object Name */
573 if (LocalObjectName)
574 {
576 LocalObjectName,
578 AllocateFromLookaside);
579 }
580 else
581 {
582 /* Clear the string */
583 RtlInitEmptyUnicodeString(ObjectName, NULL, 0);
584
585 /* It cannot have specified a Root Directory */
586 if (ObjectCreateInfo->RootDirectory)
587 {
589 }
590 }
591
592 /* Cleanup if we failed */
593 if (!NT_SUCCESS(Status))
594 {
595 ObpReleaseObjectCreateInformation(ObjectCreateInfo);
596 }
597
598 /* Return status to caller */
599 return Status;
600}
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:377
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
_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 ObCreateObject(), and ObOpenObjectByName().

◆ ObpCaptureObjectName()

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

Definition at line 377 of file oblife.c.

381{
383 ULONG StringLength;
385 UNICODE_STRING LocalName;
386 PAGED_CODE();
387
388 /* Initialize the Input String */
389 RtlInitEmptyUnicodeString(CapturedName, NULL, 0);
390
391 /* Protect everything */
393 {
394 /* Check if we came from user mode */
395 if (AccessMode != KernelMode)
396 {
397 /* First Probe the String */
399 ProbeForRead(LocalName.Buffer, LocalName.Length, sizeof(WCHAR));
400 }
401 else
402 {
403 /* No probing needed */
404 LocalName = *ObjectName;
405 }
406
407 /* Make sure there really is a string */
408 StringLength = LocalName.Length;
409 if (StringLength)
410 {
411 /* Check that the size is a valid WCHAR multiple */
412 if ((StringLength & (sizeof(WCHAR) - 1)) ||
413 /* Check that the NULL-termination below will work */
414 (StringLength == (MAXUSHORT - sizeof(UNICODE_NULL) + 1)))
415 {
416 /* PS: Please keep the checks above expanded for clarity */
418 }
419 else
420 {
421 /* Allocate the string buffer */
423 UseLookaside,
424 CapturedName);
425 if (!StringBuffer)
426 {
427 /* Set failure code */
429 }
430 else
431 {
432 /* Copy the name */
433 RtlCopyMemory(StringBuffer, LocalName.Buffer, StringLength);
434 StringBuffer[StringLength / sizeof(WCHAR)] = UNICODE_NULL;
435 }
436 }
437 }
438 }
440 {
441 /* Handle exception and free the string buffer */
443 if (StringBuffer)
444 {
445 ObpFreeObjectNameBuffer(CapturedName);
446 }
447 }
448 _SEH2_END;
449
450 /* Return */
451 return Status;
452}
WCHAR StringBuffer[156]
Definition: ldrinit.c:41
PWCHAR NTAPI ObpAllocateObjectNameBuffer(IN ULONG Length, IN BOOLEAN UseLookaside, IN OUT PUNICODE_STRING ObjectName)
Definition: oblife.c:302
#define _SEH2_VOLATILE
Definition: pseh2_64.h:208
#define ProbeForReadUnicodeString(Ptr)
Definition: probe.h:77
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define MAXUSHORT
Definition: typedefs.h:83

Referenced by ObpCaptureObjectCreateInformation().

◆ ObpDeallocateObject()

VOID FASTCALL ObpDeallocateObject ( IN PVOID  Object)

Definition at line 39 of file oblife.c.

40{
41 PVOID HeaderLocation;
48 ULONG PagedPoolCharge, NonPagedPoolCharge;
49 PAGED_CODE();
50
51 /* Get the header and assume this is what we'll free */
53 ObjectType = Header->Type;
54 HeaderLocation = Header;
55
56 /* To find the header, walk backwards from how we allocated */
57 if ((CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO(Header)))
58 {
59 HeaderLocation = CreatorInfo;
60 }
61 if ((NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header)))
62 {
63 HeaderLocation = NameInfo;
64 }
65 if ((HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO(Header)))
66 {
67 HeaderLocation = HandleInfo;
68 }
69 if ((QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO(Header)))
70 {
71 HeaderLocation = QuotaInfo;
72 }
73
74 /* Decrease the total */
75 InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfObjects);
76
77 /* Check if we have create info */
78 if (Header->Flags & OB_FLAG_CREATE_INFO)
79 {
80 /* Double-check that it exists */
81 if (Header->ObjectCreateInfo)
82 {
83 /* Free it */
84 ObpFreeObjectCreateInformation(Header->ObjectCreateInfo);
85 Header->ObjectCreateInfo = NULL;
86 }
87 }
88 else
89 {
90 /* Check if it has a quota block */
91 if (Header->QuotaBlockCharged)
92 {
93 /* Check if we have quota information */
94 if (QuotaInfo)
95 {
96 /* Get charges from quota information */
97 PagedPoolCharge = QuotaInfo->PagedPoolCharge +
98 QuotaInfo->SecurityDescriptorCharge;
99 NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;
100 }
101 else
102 {
103 /* Get charges from object type */
104 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
105 NonPagedPoolCharge = ObjectType->
106 TypeInfo.DefaultNonPagedPoolCharge;
107
108 /* Add the SD charge too */
109 if (Header->Flags & OB_FLAG_SECURITY) PagedPoolCharge += 2048;
110 }
111
112 /* Return the quota */
113 if (Header->QuotaBlockCharged != OBP_SYSTEM_PROCESS_QUOTA)
114 {
115 PsReturnSharedPoolQuota(Header->QuotaBlockCharged,
116 PagedPoolCharge,
117 NonPagedPoolCharge);
118 }
119 }
120 }
121
122 /* Check if a handle database was active */
123 if ((HandleInfo) && !(Header->Flags & OB_FLAG_SINGLE_PROCESS))
124 {
125 /* Free it */
126 ExFreePool(HandleInfo->HandleCountDatabase);
127 HandleInfo->HandleCountDatabase = NULL;
128 }
129
130 /* Check if we have a name */
131 if ((NameInfo) && (NameInfo->Name.Buffer))
132 {
133 /* Free it */
134 ExFreePool(NameInfo->Name.Buffer);
135 NameInfo->Name.Buffer = NULL;
136 }
137
138 /* Catch invalid access */
139 Header->Type = (POBJECT_TYPE)(ULONG_PTR)0xBAADB0B0BAADB0B0ULL;
140
141 /* Free the object using the same allocation tag */
142 ExFreePoolWithTag(HeaderLocation, ObjectType->Key);
143}
#define InterlockedDecrement
Definition: armddk.h:52
__in WDFOBJECT __in PCWDF_OBJECT_CONTEXT_TYPE_INFO TypeInfo
Definition: handleapi.cpp:601
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define OBJECT_HEADER_TO_HANDLE_INFO(h)
Definition: obtypes.h:118
#define OBJECT_HEADER_TO_NAME_INFO(h)
Definition: obtypes.h:114
#define OB_FLAG_SECURITY
Definition: obtypes.h:102
#define OBP_SYSTEM_PROCESS_QUOTA
Definition: ob.h:64
VOID NTAPI PsReturnSharedPoolQuota(_In_ PEPROCESS_QUOTA_BLOCK QuotaBlock, _In_ SIZE_T AmountToReturnPaged, _In_ SIZE_T AmountToReturnNonPaged)
Returns the shared (paged and non paged) pool quotas. The function is used exclusively by the Object ...
Definition: quota.c:621
POBJECT_HANDLE_COUNT_DATABASE HandleCountDatabase
Definition: obtypes.h:460
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by ObCreateObject(), and ObpDeleteObject().

◆ 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,
200 ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object);
201 }
202
203 /* Check if we have a delete procedure */
204 if (ObjectType->TypeInfo.DeleteProcedure)
205 {
206 /* Save whether we were deleted from worker thread or not */
207 if (!CalledFromWorkerThread) Header->Flags |= OB_FLAG_DEFER_DELETE;
208
209 /* Call it */
210 ObpCalloutStart(&CalloutIrql);
211 ObjectType->TypeInfo.DeleteProcedure(Object);
212 ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object);
213 }
214
215 /* Now de-allocate all object members */
217}
#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 OB_FLAG_DEFER_DELETE
Definition: obtypes.h:104
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

Referenced by ObfDereferenceObject(), and ObpReapObject().

◆ ObpDeleteObjectType()

VOID NTAPI ObpDeleteObjectType ( IN PVOID  Object)

Definition at line 1418 of file oblife.c.

1419{
1420 ULONG i;
1422
1423 /* Loop our locks */
1424 for (i = 0; i < 4; i++)
1425 {
1426 /* Delete each one */
1427 ExDeleteResourceLite(&ObjectType->ObjectLocks[i]);
1428 }
1429
1430 /* Delete our main mutex */
1432}
#define ExDeleteResourceLite(res)
Definition: env_spec_w32.h:647
void * PVOID
Definition: typedefs.h:50

Referenced by ObInitSystem().

◆ ObpFreeObjectNameBuffer()

VOID NTAPI ObpFreeObjectNameBuffer ( IN PUNICODE_STRING  Name)

Definition at line 347 of file oblife.c.

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

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

◆ ObpQueryNameInfoSize()

static ULONG ObpQueryNameInfoSize ( _In_ POBJECT_HEADER  ObjectHeader)
static

Queries the name info size of a given resource object. The function loops through all the parent directories of the object and computes the name size.

Parameters
[in]ObjectHeaderA pointer to an object header, of which name and directory info are to be retrieved.
Returns
Returns the name info size that is pointed by the given object by the caller of this function. If an object does not have a name or no directories, it returns 0.

Definition at line 891 of file oblife.c.

893{
894 ULONG NameSize = 0;
897 PAGED_CODE();
898
899 /* Get the name info */
900 NameInfo = OBJECT_HEADER_TO_NAME_INFO(ObjectHeader);
901 if (!NameInfo)
902 {
903 return 0;
904 }
905
906 /* Get the parent directory from the object name too */
907 ParentDirectory = NameInfo->Directory;
908 if (!ParentDirectory)
909 {
910 return 0;
911 }
912
913 /* Take into account the name size of this object and loop for all parent directories */
914 NameSize = sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
915 for (;;)
916 {
917 /* Get the name info from the parent directory */
920 if (!NameInfo)
921 {
922 /* Stop looking if this is the last one */
923 break;
924 }
925
926 /* Get the parent directory */
927 ParentDirectory = NameInfo->Directory;
928 if (!ParentDirectory)
929 {
930 /* This is the last directory, stop looking */
931 break;
932 }
933
934 /*
935 * Take into account the size of this name info,
936 * keep looking for other parent directories.
937 */
938 NameSize += sizeof(OBJ_NAME_PATH_SEPARATOR) + NameInfo->Name.Length;
939 }
940
941 /* Include the size of the object name information as well as the NULL terminator */
942 NameSize += sizeof(OBJECT_NAME_INFORMATION) + sizeof(UNICODE_NULL);
943 return NameSize;
944}
IN PDCB ParentDirectory
Definition: fatprocs.h:699
struct _OBJECT_NAME_INFORMATION OBJECT_NAME_INFORMATION
for(i=0;i< sizeof(testsuite)/sizeof(testsuite[0]);++i) ok(call_test(testsuite[i].func)

Referenced by NtQueryObject().

◆ ObpReapObject()

VOID NTAPI ObpReapObject ( IN PVOID  Parameter)

Definition at line 221 of file oblife.c.

222{
223 POBJECT_HEADER ReapObject, NextObject;
224
225 /* Start reaping */
226 do
227 {
228 /* Get the reap object */
230
231 /* Start deletion loop */
232 do
233 {
234 /* Get the next object */
235 NextObject = ReapObject->NextToFree;
236
237 /* Delete the object */
238 ObpDeleteObject(&ReapObject->Body, TRUE);
239
240 /* Move to the next one */
241 ReapObject = NextObject;
242 } while ((ReapObject) && (ReapObject != (PVOID)1));
243 } while ((ObpReaperList != (PVOID)1) ||
245}
#define InterlockedExchangePointer(Target, Value)
Definition: dshow.h:45
#define InterlockedCompareExchange
Definition: interlocked.h:119
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:493

Referenced by ObInitSystem().

◆ ObpSetPermanentObject()

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

Definition at line 267 of file oblife.c.

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

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

◆ ObQueryTypeInfo()

NTSTATUS NTAPI ObQueryTypeInfo ( _In_ POBJECT_TYPE  ObjectType,
_Out_writes_bytes_to_(Length, *ReturnLength) POBJECT_TYPE_INFORMATION  ObjectTypeInfo,
_In_ ULONG  Length,
_Out_ PULONG  ReturnLength 
)

Definition at line 948 of file oblife.c.

954{
956 PWSTR InfoBuffer;
957
958 /* The string of the object type name has to be NULL-terminated */
959 ASSERT(ObjectType->Name.MaximumLength >= ObjectType->Name.Length + sizeof(UNICODE_NULL));
960
961 /* Enter SEH */
963 {
964 /*
965 * Set return length aligned to 4-byte or 8-byte boundary. Windows has a bug
966 * where the returned length pointer is always aligned to a 4-byte boundary.
967 * If one were to allocate a pool of memory in kernel mode to retrieve all
968 * the object types info with this return length, Windows will bugcheck with
969 * BAD_POOL_HEADER in 64-bit upon you free the said allocated memory.
970 *
971 * More than that, Windows uses MaximumLength for the calculation of the returned
972 * length and MaximumLength does not always guarantee the name type is NULL-terminated
973 * leading the ObQueryTypeInfo function to overrun the buffer.
974 */
975 *ReturnLength += sizeof(*ObjectTypeInfo) +
976 ALIGN_UP(ObjectType->Name.Length + sizeof(UNICODE_NULL), ULONG_PTR);
977
978 /* Check if that is too much */
979 if (Length < *ReturnLength)
980 {
982 }
983
984 /* Build the data */
985 ObjectTypeInfo->TotalNumberOfHandles =
986 ObjectType->TotalNumberOfHandles;
987 ObjectTypeInfo->TotalNumberOfObjects =
988 ObjectType->TotalNumberOfObjects;
989 ObjectTypeInfo->HighWaterNumberOfHandles =
990 ObjectType->HighWaterNumberOfHandles;
991 ObjectTypeInfo->HighWaterNumberOfObjects =
992 ObjectType->HighWaterNumberOfObjects;
993 ObjectTypeInfo->PoolType =
994 ObjectType->TypeInfo.PoolType;
995 ObjectTypeInfo->DefaultNonPagedPoolCharge =
996 ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
997 ObjectTypeInfo->DefaultPagedPoolCharge =
998 ObjectType->TypeInfo.DefaultPagedPoolCharge;
999 ObjectTypeInfo->ValidAccessMask =
1000 ObjectType->TypeInfo.ValidAccessMask;
1001 ObjectTypeInfo->SecurityRequired =
1002 ObjectType->TypeInfo.SecurityRequired;
1003 ObjectTypeInfo->InvalidAttributes =
1004 ObjectType->TypeInfo.InvalidAttributes;
1005 ObjectTypeInfo->GenericMapping =
1006 ObjectType->TypeInfo.GenericMapping;
1007 ObjectTypeInfo->MaintainHandleCount =
1008 ObjectType->TypeInfo.MaintainHandleCount;
1009
1010 /* Setup the name buffer */
1011 InfoBuffer = (PWSTR)(ObjectTypeInfo + 1);
1012 ObjectTypeInfo->TypeName.Buffer = InfoBuffer;
1013 ObjectTypeInfo->TypeName.MaximumLength = ObjectType->Name.MaximumLength;
1014 ObjectTypeInfo->TypeName.Length = ObjectType->Name.Length;
1015
1016 /* Copy it */
1017 RtlCopyMemory(InfoBuffer,
1018 ObjectType->Name.Buffer,
1019 ObjectType->Name.Length);
1020
1021 /* Null-terminate it */
1022 (InfoBuffer)[ObjectType->Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
1023 }
1025 {
1026 /* Otherwise, get the exception code */
1028 }
1029 _SEH2_END;
1030
1031 /* Return status to caller */
1032 return Status;
1033}
_In_ PVOID _In_ ULONG _Out_ PVOID _In_ ULONG _Inout_ PULONG ReturnLength
uint16_t * PWSTR
Definition: typedefs.h:56
#define ALIGN_UP(size, type)
Definition: umtypes.h:91

Referenced by NtQueryObject().

Variable Documentation

◆ NtGlobalFlag

ULONG NtGlobalFlag
extern

Definition at line 54 of file init.c.

Referenced by ObCreateObjectType().

◆ ObpCreateInfoLookasideList

GENERAL_LOOKASIDE ObpCreateInfoLookasideList

Definition at line 26 of file oblife.c.

◆ ObpDefaultObject

KEVENT ObpDefaultObject

Definition at line 23 of file oblife.c.

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

◆ ObpDeviceMapLock

◆ ObpNameBufferLookasideList

GENERAL_LOOKASIDE ObpNameBufferLookasideList

Definition at line 26 of file oblife.c.

Referenced by ObInit2(), and ObInitSystem().

◆ ObpObjectsCreated

ULONG ObpObjectsCreated

Definition at line 31 of file oblife.c.

Referenced by ObpAllocateObject().

◆ ObpObjectsWithCreatorInfo

ULONG ObpObjectsWithCreatorInfo

Definition at line 32 of file oblife.c.

Referenced by ObpAllocateObject().

◆ ObpObjectsWithHandleDB

ULONG ObpObjectsWithHandleDB

Definition at line 32 of file oblife.c.

Referenced by ObpAllocateObject().

◆ ObpObjectsWithName

ULONG ObpObjectsWithName

Definition at line 31 of file oblife.c.

Referenced by ObpAllocateObject().

◆ ObpObjectsWithPoolQuota

ULONG ObpObjectsWithPoolQuota

Definition at line 31 of file oblife.c.

Referenced by ObpAllocateObject().

◆ ObpObjectTypes

POBJECT_TYPE ObpObjectTypes[32]

Definition at line 33 of file oblife.c.

Referenced by ObCreateObjectType().

◆ ObpReaperList

volatile PVOID ObpReaperList

Definition at line 29 of file oblife.c.

Referenced by ObpDeferObjectDeletion(), and ObpReapObject().

◆ ObpReaperWorkItem

WORK_QUEUE_ITEM ObpReaperWorkItem

Definition at line 28 of file oblife.c.

Referenced by ObInitSystem(), and ObpDeferObjectDeletion().

◆ ObpTypeObjectType

POBJECT_TYPE ObpTypeObjectType = NULL

Definition at line 22 of file oblife.c.

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