ReactOS 0.4.15-dev-7788-g1ad9096
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 PVOID ObjectInformation, IN ULONG Length)
 

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

1511{
1512 PVOID ObjectBody;
1515 PAGED_CODE();
1516
1517 /* Make sure that the caller has SeCreatePermanentPrivilege */
1519 {
1521 }
1522
1523 /* Reference the object */
1524 Status = ObReferenceObjectByHandle(ObjectHandle,
1525 0,
1526 NULL,
1528 &ObjectBody,
1529 NULL);
1530 if (Status != STATUS_SUCCESS) return Status;
1531
1532 /* Set it as permanent and dereference it */
1533 ObpSetPermanentObject(ObjectBody, TRUE);
1534 ObDereferenceObject(ObjectBody);
1535 return STATUS_SUCCESS;
1536}
#define PAGED_CODE()
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
LONG NTSTATUS
Definition: precomp.h:26
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define ExGetPreviousMode
Definition: ex.h:140
Status
Definition: gdiplustypes.h:25
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:266
NTSTATUS NTAPI ObReferenceObjectByHandle(IN HANDLE Handle, IN ACCESS_MASK DesiredAccess, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, OUT PVOID *Object, OUT POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL)
Definition: obref.c:494
#define STATUS_SUCCESS
Definition: shellext.h:65
CCHAR KPROCESSOR_MODE
Definition: ketypes.h:7
#define ObDereferenceObject
Definition: obfuncs.h:203
_In_ KPROCESSOR_MODE PreviousMode
Definition: sefuncs.h:103

Referenced by CSR_API().

◆ NtMakeTemporaryObject()

NTSTATUS NTAPI NtMakeTemporaryObject ( IN HANDLE  ObjectHandle)

Definition at line 1473 of file oblife.c.

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

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

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

1571{
1572 OBJECT_HANDLE_INFORMATION HandleInfo;
1573 POBJECT_HEADER ObjectHeader = NULL;
1575 POBJECT_BASIC_INFORMATION BasicInfo;
1576 ULONG InfoLength = 0;
1577 PVOID Object = NULL;
1579 POBJECT_HEADER_QUOTA_INFO ObjectQuota;
1583 PAGED_CODE();
1584
1585 /* Check if the caller is from user mode */
1586 if (PreviousMode != KernelMode)
1587 {
1588 /* Protect validation with SEH */
1589 _SEH2_TRY
1590 {
1591 /* Probe the input structure */
1593
1594 /* If we have a result length, probe it too */
1596 }
1598 {
1599 /* Return the exception code */
1601 }
1602 _SEH2_END;
1603 }
1604
1605 /*
1606 * Make sure this isn't a generic type query, since the caller doesn't
1607 * have to give a handle for it
1608 */
1610 {
1611 /* Reference the object */
1612 Status = ObReferenceObjectByHandle(ObjectHandle,
1613 0,
1614 NULL,
1616 &Object,
1617 &HandleInfo);
1618 if (!NT_SUCCESS (Status)) return Status;
1619
1620 /* Get the object header */
1621 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
1622 ObjectType = ObjectHeader->Type;
1623 }
1624
1625 _SEH2_TRY
1626 {
1627 /* Check the information class */
1628 switch (ObjectInformationClass)
1629 {
1630 /* Basic info */
1632
1633 /* Validate length */
1634 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
1635 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
1636 {
1637 /* Fail */
1639 break;
1640 }
1641
1642 /* Fill out the basic information */
1644 BasicInfo->Attributes = HandleInfo.HandleAttributes;
1645 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
1646 BasicInfo->HandleCount = ObjectHeader->HandleCount;
1647 BasicInfo->PointerCount = ObjectHeader->PointerCount;
1648
1649 /* Permanent/Exclusive Flags are NOT in Handle attributes! */
1650 if (ObjectHeader->Flags & OB_FLAG_EXCLUSIVE)
1651 {
1652 /* Set the flag */
1653 BasicInfo->Attributes |= OBJ_EXCLUSIVE;
1654 }
1655 if (ObjectHeader->Flags & OB_FLAG_PERMANENT)
1656 {
1657 /* Set the flag */
1658 BasicInfo->Attributes |= OBJ_PERMANENT;
1659 }
1660
1661 /* Copy quota information */
1662 ObjectQuota = OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader);
1663 if (ObjectQuota != NULL)
1664 {
1665 BasicInfo->PagedPoolCharge = ObjectQuota->PagedPoolCharge;
1666 BasicInfo->NonPagedPoolCharge = ObjectQuota->NonPagedPoolCharge;
1667 }
1668 else
1669 {
1670 BasicInfo->PagedPoolCharge = 0;
1671 BasicInfo->NonPagedPoolCharge = 0;
1672 }
1673
1674 /* Copy name information */
1675 BasicInfo->NameInfoSize = ObpQueryNameInfoSize(ObjectHeader);
1676 BasicInfo->TypeInfoSize = sizeof(OBJECT_TYPE_INFORMATION) + ObjectType->Name.Length +
1677 sizeof(UNICODE_NULL);
1678
1679 /* Check if this is a symlink */
1680 if (ObjectHeader->Type == ObpSymbolicLinkObjectType)
1681 {
1682 /* Return the creation time */
1683 BasicInfo->CreationTime.QuadPart =
1684 ((POBJECT_SYMBOLIC_LINK)Object)->CreationTime.QuadPart;
1685 }
1686 else
1687 {
1688 /* Otherwise return 0 */
1689 BasicInfo->CreationTime.QuadPart = (ULONGLONG)0;
1690 }
1691
1692 /* Copy security information */
1693 BasicInfo->SecurityDescriptorSize = 0;
1694 if (BooleanFlagOn(HandleInfo.GrantedAccess, READ_CONTROL) &&
1695 ObjectHeader->SecurityDescriptor != NULL)
1696 {
1701
1702 ObjectType->TypeInfo.SecurityProcedure(Object,
1703 QuerySecurityDescriptor,
1705 NULL,
1706 &BasicInfo->SecurityDescriptorSize,
1707 &ObjectHeader->SecurityDescriptor,
1708 ObjectType->TypeInfo.PoolType,
1709 &ObjectType->TypeInfo.GenericMapping);
1710 }
1711
1712 /* Break out with success */
1714 break;
1715
1716 /* Name information */
1718
1719 /* Call the helper and break out */
1723 Length,
1724 &InfoLength);
1725 break;
1726
1727 /* Information about this type */
1729
1730 /* Call the helper and break out */
1731 Status = ObQueryTypeInfo(ObjectHeader->Type,
1734 Length,
1735 &InfoLength);
1736 break;
1737
1738 /* Information about all types */
1740 DPRINT1("NOT IMPLEMENTED!\n");
1741 InfoLength = Length;
1743 break;
1744
1745 /* Information about the handle flags */
1746 case ObjectHandleFlagInformation:
1747
1748 /* Validate length */
1749 InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
1751 {
1753 break;
1754 }
1755
1756 /* Get the structure */
1759
1760 /* Set the flags */
1761 HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT;
1762 HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes &
1763 OBJ_PROTECT_CLOSE) != 0;
1764
1765 /* Break out with success */
1767 break;
1768
1769 /* Anything else */
1770 default:
1771
1772 /* Fail it */
1773 InfoLength = Length;
1775 break;
1776 }
1777
1778 /* Check if the caller wanted the return length */
1779 if (ResultLength)
1780 {
1781 /* Write the length */
1782 *ResultLength = InfoLength;
1783 }
1784 }
1786 {
1787 /* Otherwise, get the exception code */
1789 }
1790 _SEH2_END;
1791
1792 /* Dereference the object if we had referenced it */
1794
1795 /* Return status */
1796 return Status;
1797}
@ ObjectTypeInformation
Definition: DriverTester.h:56
@ ObjectBasicInformation
Definition: DriverTester.h:54
@ ObjectNameInformation
Definition: DriverTester.h:55
#define OBJ_PROTECT_CLOSE
#define ObpSymbolicLinkObjectType
Definition: ObTypes.c:119
#define DPRINT1
Definition: precomp.h:8
IN CINT ObjectInformationClass
Definition: conport.c:47
IN CINT OUT PVOID ObjectInformation
Definition: conport.c:48
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
_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:85
#define OBJ_INHERIT
Definition: winternl.h:225
#define OBJ_EXCLUSIVE
Definition: winternl.h:227
#define OBJ_PERMANENT
Definition: winternl.h:226
struct _OBJECT_BASIC_INFORMATION OBJECT_BASIC_INFORMATION
@ ObjectTypesInformation
Definition: winternl.h:851
struct _OBJECT_BASIC_INFORMATION * POBJECT_BASIC_INFORMATION
ObjectType
Definition: metafile.c:81
DWORD SECURITY_INFORMATION
Definition: ms-dtyp.idl:311
#define KernelMode
Definition: asm.h:34
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_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:240
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:947
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:890
NTSTATUS NTAPI ObQueryNameString(IN PVOID Object, OUT POBJECT_NAME_INFORMATION ObjectNameInfo, IN ULONG Length, OUT PULONG ReturnLength)
Definition: obname.c:1207
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162
#define ProbeForWriteUlong(Ptr)
Definition: probe.h:36
ACCESS_MASK GrantedAccess
Definition: winternl.h:1251
ACCESS_MASK GrantedAccess
Definition: iotypes.h:181
PSECURITY_DESCRIPTOR SecurityDescriptor
Definition: obtypes.h:503
UCHAR Flags
Definition: obtypes.h:497
LONG_PTR HandleCount
Definition: obtypes.h:490
LONG_PTR PointerCount
Definition: obtypes.h:487
POBJECT_TYPE Type
Definition: obtypes.h:493
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#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:3776
#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
unsigned char UCHAR
Definition: xmlstorage.h:181

◆ NtSetInformationObject()

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

Definition at line 1824 of file oblife.c.

1828{
1831 PVOID ObjectTable;
1835 BOOLEAN AttachedToProcess = FALSE;
1836 PAGED_CODE();
1837
1838 /* Validate the information class */
1839 switch (ObjectInformationClass)
1840 {
1841 case ObjectHandleFlagInformation:
1842
1843 /* Validate the length */
1845 {
1846 /* Invalid length */
1848 }
1849
1850 /* Save the previous mode */
1851 Context.PreviousMode = ExGetPreviousMode();
1852
1853 /* Check if we were called from user mode */
1854 if (Context.PreviousMode != KernelMode)
1855 {
1856 /* Enter SEH */
1857 _SEH2_TRY
1858 {
1859 /* Probe and capture the attribute buffer */
1862 sizeof(BOOLEAN));
1865 }
1867 {
1868 /* Return the exception code */
1870 }
1871 _SEH2_END;
1872 }
1873 else
1874 {
1875 /* Just copy the buffer directly */
1878 }
1879
1880 /* Check if this is a kernel handle */
1881 if (ObpIsKernelHandle(ObjectHandle, Context.PreviousMode))
1882 {
1883 /* Get the actual handle */
1884 ObjectHandle = ObKernelHandleToHandle(ObjectHandle);
1885 ObjectTable = ObpKernelHandleTable;
1886
1887 /* Check if we're not in the system process */
1889 {
1890 /* Attach to it */
1892 AttachedToProcess = TRUE;
1893 }
1894 }
1895 else
1896 {
1897 /* Use the current table */
1898 ObjectTable = PsGetCurrentProcess()->ObjectTable;
1899 }
1900
1901 /* Change the handle attributes */
1902 if (!ExChangeHandle(ObjectTable,
1903 ObjectHandle,
1905 (ULONG_PTR)&Context))
1906 {
1907 /* Some failure */
1909 }
1910 else
1911 {
1912 /* We are done */
1914 }
1915
1916 /* De-attach if we were attached, and return status */
1917 if (AttachedToProcess) KeUnstackDetachProcess(&ApcState);
1918 break;
1919
1920 case ObjectSessionInformation:
1921
1922 /* Only a system process can do this */
1925 {
1926 /* Fail */
1927 DPRINT1("Privilege not held\n");
1929 }
1930 else
1931 {
1932 /* Get the object directory */
1933 Status = ObReferenceObjectByHandle(ObjectHandle,
1934 0,
1937 (PVOID*)&Directory,
1938 NULL);
1939 if (NT_SUCCESS(Status))
1940 {
1941 /* Setup a lookup context */
1942 OBP_LOOKUP_CONTEXT LookupContext;
1943 ObpInitializeLookupContext(&LookupContext);
1944
1945 /* Set the directory session ID */
1948 ObpReleaseDirectoryLock(Directory, &LookupContext);
1949
1950 /* We're done, release the context and dereference the directory */
1951 ObpReleaseLookupContext(&LookupContext);
1953 }
1954 }
1955 break;
1956
1957 default:
1958 /* Unsupported class */
1960 break;
1961 }
1962
1963 return Status;
1964}
#define ObpDirectoryObjectType
Definition: ObTypes.c:118
unsigned char BOOLEAN
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
BOOLEAN NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, IN ULONG_PTR Context)
Definition: handle.c:1189
_Out_ PKAPC_STATE ApcState
Definition: mm.h:1765
const LUID SeTcbPrivilege
Definition: priv.c:26
ULONG NTAPI PsGetCurrentProcessSessionId(VOID)
Definition: process.c:1133
BOOLEAN NTAPI ObpSetHandleAttributes(IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, IN ULONG_PTR Context)
Definition: obhandle.c:1859
PHANDLE_TABLE ObpKernelHandleTable
Definition: obhandle.c:20
#define ObpIsKernelHandle(Handle, ProcessorMode)
Definition: ob.h:74
#define ObKernelHandleToHandle(Handle)
Definition: ob.h:83
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
VOID NTAPI KeStackAttachProcess(IN PKPROCESS Process, OUT PRKAPC_STATE ApcState)
Definition: procobj.c:704
VOID NTAPI KeUnstackDetachProcess(IN PRKAPC_STATE ApcState)
Definition: procobj.c:756
PEPROCESS PsInitialSystemProcess
Definition: psmgr.c:50
base for all directory entries
Definition: entries.h:138
KPROCESS Pcb
Definition: pstypes.h:1262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
KAPC_STATE
Definition: ketypes.h:1409
#define PsGetCurrentProcess
Definition: psfuncs.h:17

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

1048{
1050 POBJECT_CREATE_INFORMATION ObjectCreateInfo;
1053
1054 /* Allocate a capture buffer */
1056 if (!ObjectCreateInfo) return STATUS_INSUFFICIENT_RESOURCES;
1057
1058 /* Capture all the info */
1060 ProbeMode,
1061 AccessMode,
1062 FALSE,
1063 ObjectCreateInfo,
1064 &ObjectName);
1065 if (NT_SUCCESS(Status))
1066 {
1067 /* Validate attributes */
1068 if (Type->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes)
1069 {
1070 /* Fail */
1072 }
1073 else
1074 {
1075 /* Check if we have a paged charge */
1076 if (!PagedPoolCharge)
1077 {
1078 /* Save it */
1079 PagedPoolCharge = Type->TypeInfo.DefaultPagedPoolCharge;
1080 }
1081
1082 /* Check for nonpaged charge */
1083 if (!NonPagedPoolCharge)
1084 {
1085 /* Save it */
1086 NonPagedPoolCharge = Type->TypeInfo.DefaultNonPagedPoolCharge;
1087 }
1088
1089 /* Write the pool charges */
1090 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge;
1091 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge;
1092
1093 /* Allocate the Object */
1094 Status = ObpAllocateObject(ObjectCreateInfo,
1095 &ObjectName,
1096 Type,
1097 ObjectSize,
1098 AccessMode,
1099 &Header);
1100 if (NT_SUCCESS(Status))
1101 {
1102 /* Return the Object */
1103 *Object = &Header->Body;
1104
1105 /* Check if this is a permanent object */
1106 if (Header->Flags & OB_FLAG_PERMANENT)
1107 {
1108 /* Do the privilege check */
1110 ProbeMode))
1111 {
1112 /* Fail */
1115 }
1116 }
1117
1118 /* Return status */
1119 return Status;
1120 }
1121 }
1122
1123 /* Release the Capture Info, we don't need it */
1124 ObpFreeObjectCreateInformation(ObjectCreateInfo);
1126 return Status;
1127 }
1128
1129 /* We failed, so release the Buffer */
1131 return Status;
1132}
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:455
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:611
VOID NTAPI ObpFreeObjectNameBuffer(IN PUNICODE_STRING Name)
Definition: oblife.c:346
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 1136 of file oblife.c.

1140{
1142 POBJECT_TYPE LocalObjectType;
1143 ULONG HeaderSize;
1146 PWCHAR p;
1147 ULONG i;
1149 ANSI_STRING AnsiName;
1150 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
1151
1152 /* Verify parameters */
1153 if (!(TypeName) ||
1154 !(TypeName->Length) ||
1155 (TypeName->Length % sizeof(WCHAR)) ||
1156 !(ObjectTypeInitializer) ||
1157 (ObjectTypeInitializer->Length != sizeof(*ObjectTypeInitializer)) ||
1158 (ObjectTypeInitializer->InvalidAttributes & ~OBJ_VALID_KERNEL_ATTRIBUTES) ||
1159 (ObjectTypeInitializer->MaintainHandleCount &&
1160 (!(ObjectTypeInitializer->OpenProcedure) &&
1161 !ObjectTypeInitializer->CloseProcedure)) ||
1162 ((!ObjectTypeInitializer->UseDefaultObject) &&
1163 (ObjectTypeInitializer->PoolType != NonPagedPool)))
1164 {
1165 /* Fail */
1167 }
1168
1169 /* Make sure the name doesn't have a separator */
1170 p = TypeName->Buffer;
1171 i = TypeName->Length / sizeof(WCHAR);
1172 while (i--)
1173 {
1174 /* Check for one and fail */
1176 }
1177
1178 /* Setup a lookup context */
1180
1181 /* Check if we've already created the directory of types */
1183 {
1184 /* Lock the lookup context */
1186
1187 /* Do the lookup */
1189 TypeName,
1191 FALSE,
1192 &Context))
1193 {
1194 /* We have already created it, so fail */
1197 }
1198 }
1199
1200 /* Now make a copy of the object name */
1202 TypeName->MaximumLength,
1203 OB_NAME_TAG);
1204 if (!ObjectName.Buffer)
1205 {
1206 /* Out of memory, fail */
1209 }
1210
1211 /* Set the length and copy the name */
1212 ObjectName.MaximumLength = TypeName->MaximumLength;
1213 RtlCopyUnicodeString(&ObjectName, TypeName);
1214
1215 /* Allocate the Object */
1217 &ObjectName,
1219 sizeof(OBJECT_TYPE),
1220 KernelMode,
1221 &Header);
1222 if (!NT_SUCCESS(Status))
1223 {
1224 /* Free the name and fail */
1226 ExFreePool(ObjectName.Buffer);
1227 return Status;
1228 }
1229
1230 /* Setup the flags and name */
1231 LocalObjectType = (POBJECT_TYPE)&Header->Body;
1232 LocalObjectType->Name = ObjectName;
1234
1235 /* Clear accounting data */
1236 LocalObjectType->TotalNumberOfObjects =
1237 LocalObjectType->TotalNumberOfHandles =
1238 LocalObjectType->HighWaterNumberOfObjects =
1239 LocalObjectType->HighWaterNumberOfHandles = 0;
1240
1241 /* Check if this is the first Object Type */
1243 {
1244 /* It is, so set this as the type object */
1245 ObpTypeObjectType = LocalObjectType;
1246 Header->Type = ObpTypeObjectType;
1247
1248 /* Set the hard-coded key and object count */
1249 LocalObjectType->TotalNumberOfObjects = 1;
1250 LocalObjectType->Key = TAG_OBJECT_TYPE;
1251 }
1252 else
1253 {
1254 /* Convert the tag to ASCII */
1255 Status = RtlUnicodeStringToAnsiString(&AnsiName, TypeName, TRUE);
1256 if (NT_SUCCESS(Status))
1257 {
1258 /* For every missing character, use a space */
1259 for (i = 3; i >= AnsiName.Length; i--) AnsiName.Buffer[i] = ' ';
1260
1261 /* Set the key and free the converted name */
1262 LocalObjectType->Key = *(PULONG)AnsiName.Buffer;
1263 RtlFreeAnsiString(&AnsiName);
1264 }
1265 else
1266 {
1267 /* Just copy the characters */
1268 LocalObjectType->Key = *(PULONG)TypeName->Buffer;
1269 }
1270 }
1271
1272 /* Set up the type information */
1273 LocalObjectType->TypeInfo = *ObjectTypeInitializer;
1274 LocalObjectType->TypeInfo.PoolType = ObjectTypeInitializer->PoolType;
1275
1276 /* Check if we have to maintain a type list */
1278 {
1279 /* Enable support */
1280 LocalObjectType->TypeInfo.MaintainTypeList = TRUE;
1281 }
1282
1283 /* Calculate how much space our header'll take up */
1284 HeaderSize = sizeof(OBJECT_HEADER) +
1285 sizeof(OBJECT_HEADER_NAME_INFO) +
1286 (ObjectTypeInitializer->MaintainHandleCount ?
1287 sizeof(OBJECT_HEADER_HANDLE_INFO) : 0);
1288
1289 /* Check the pool type */
1290 if (ObjectTypeInitializer->PoolType == NonPagedPool)
1291 {
1292 /* Update the NonPaged Pool charge */
1293 LocalObjectType->TypeInfo.DefaultNonPagedPoolCharge += HeaderSize;
1294 }
1295 else
1296 {
1297 /* Update the Paged Pool charge */
1298 LocalObjectType->TypeInfo.DefaultPagedPoolCharge += HeaderSize;
1299 }
1300
1301 /* All objects types need a security procedure */
1302 if (!ObjectTypeInitializer->SecurityProcedure)
1303 {
1305 }
1306
1307 /* Select the Wait Object */
1308 if (LocalObjectType->TypeInfo.UseDefaultObject)
1309 {
1310 /* Add the SYNCHRONIZE access mask since it's waitable */
1311 LocalObjectType->TypeInfo.ValidAccessMask |= SYNCHRONIZE;
1312
1313 /* Use the "Default Object", a simple event */
1314 LocalObjectType->DefaultObject = &ObpDefaultObject;
1315 }
1316 /* The File Object gets an optimized hack so it can be waited on */
1317 else if ((TypeName->Length == 8) && !(wcscmp(TypeName->Buffer, L"File")))
1318 {
1319 /* Wait on the File Object's event directly */
1321 Event));
1322 }
1323 else if ((TypeName->Length == 24) && !(wcscmp(TypeName->Buffer, L"WaitablePort")))
1324 {
1325 /* Wait on the LPC Port's object directly */
1327 WaitEvent));
1328 }
1329 else
1330 {
1331 /* No default Object */
1332 LocalObjectType->DefaultObject = NULL;
1333 }
1334
1335 /* Initialize Object Type components */
1336 ExInitializeResourceLite(&LocalObjectType->Mutex);
1337 for (i = 0; i < 4; i++)
1338 {
1339 /* Initialize the object locks */
1340 ExInitializeResourceLite(&LocalObjectType->ObjectLocks[i]);
1341 }
1342 InitializeListHead(&LocalObjectType->TypeList);
1343
1344 /* Lock the object type */
1346
1347 /* Get creator info and insert it into the type list */
1349 if (CreatorInfo)
1350 {
1352 &CreatorInfo->TypeList);
1353
1354 /* CORE-8423: Avoid inserting this a second time if someone creates a
1355 * handle to the object type (bug in Windows 2003) */
1356 Header->Flags &= ~OB_FLAG_CREATE_INFO;
1357 }
1358
1359 /* Set the index and the entry into the object type array */
1360 LocalObjectType->Index = ObpTypeObjectType->TotalNumberOfObjects;
1361
1362 ASSERT(LocalObjectType->Index != 0);
1363
1364 if (LocalObjectType->Index < RTL_NUMBER_OF(ObpObjectTypes))
1365 {
1366 /* It fits, insert it */
1367 ObpObjectTypes[LocalObjectType->Index - 1] = LocalObjectType;
1368 }
1369
1370 /* Release the object type */
1372
1373 /* Check if we're actually creating the directory object itself */
1374 if (!(ObpTypeDirectoryObject) ||
1376 {
1377 /* Check if the type directory exists */
1379 {
1380 /* Reference it */
1382 }
1383
1384 /* Cleanup the lookup context */
1386
1387 /* Return the object type and success */
1388 *ObjectType = LocalObjectType;
1389 return STATUS_SUCCESS;
1390 }
1391
1392 /* If we got here, then we failed */
1395}
static OB_SECURITY_METHOD SeDefaultObjectMethod
Definition: ObTypes.c:134
#define RTL_NUMBER_OF(x)
Definition: RtlRegistry.c:12
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#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:69
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
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
#define L(x)
Definition: ntvdm.h:50
POBJECT_DIRECTORY ObpTypeDirectoryObject
Definition: obname.c:20
PVOID NTAPI ObpLookupEntryDirectory(IN POBJECT_DIRECTORY Directory, IN PUNICODE_STRING Name, IN ULONG Attributes, IN UCHAR SearchShadow, IN POBP_LOOKUP_CONTEXT Context)
Definition: obdir.c:158
BOOLEAN NTAPI ObpInsertEntryDirectory(IN POBJECT_DIRECTORY Parent, IN POBP_LOOKUP_CONTEXT Context, IN POBJECT_HEADER ObjectHeader)
Definition: obdir.c:45
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
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
OB_SECURITY_METHOD SecurityProcedure
Definition: obtypes.h:371
ULONG DefaultNonPagedPoolCharge
Definition: obtypes.h:365
ULONG TotalNumberOfHandles
Definition: obtypes.h:387
ULONG Index
Definition: obtypes.h:385
LIST_ENTRY TypeList
Definition: obtypes.h:382
ULONG HighWaterNumberOfObjects
Definition: obtypes.h:388
ULONG TotalNumberOfObjects
Definition: obtypes.h:386
OBJECT_TYPE_INITIALIZER TypeInfo
Definition: obtypes.h:390
ERESOURCE ObjectLocks[4]
Definition: obtypes.h:392
ERESOURCE Mutex
Definition: obtypes.h:381
ULONG Key
Definition: obtypes.h:391
ULONG HighWaterNumberOfHandles
Definition: obtypes.h:389
UNICODE_STRING Name
Definition: obtypes.h:383
PVOID DefaultObject
Definition: obtypes.h:384
#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
__wchar_t WCHAR
Definition: xmlstorage.h:180

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

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

◆ ObFreeObjectCreateInfoBuffer()

VOID NTAPI ObFreeObjectCreateInfoBuffer ( IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo)

Definition at line 603 of file oblife.c.

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

Referenced by IoCreateStreamFileObjectLite().

◆ ObMakeTemporaryObject()

VOID NTAPI ObMakeTemporaryObject ( IN PVOID  ObjectBody)

Definition at line 1449 of file oblife.c.

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

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

617{
619 ULONG QuotaSize, HandleSize, NameSize, CreatorSize;
622 POBJECT_HEADER_CREATOR_INFO CreatorInfo;
625 ULONG FinalSize;
626 ULONG Tag;
627 PAGED_CODE();
628
629 /* Accounting */
631
632 /* Check if we don't have an Object Type yet */
633 if (!ObjectType)
634 {
635 /* Use default tag and non-paged pool */
638 }
639 else
640 {
641 /* Use the pool and tag given */
642 PoolType = ObjectType->TypeInfo.PoolType;
643 Tag = ObjectType->Key;
644 }
645
646 /* Check if we have no create information (ie: we're an object type) */
647 if (!ObjectCreateInfo)
648 {
649 /* Use defaults */
650 QuotaSize = HandleSize = 0;
651 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
652 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
653 }
654 else
655 {
656 /* Check if we have quota */
657 if ((((ObjectCreateInfo->PagedPoolCharge !=
658 ObjectType->TypeInfo.DefaultPagedPoolCharge) ||
659 (ObjectCreateInfo->NonPagedPoolCharge !=
660 ObjectType->TypeInfo.DefaultNonPagedPoolCharge) ||
661 (ObjectCreateInfo->SecurityDescriptorCharge > 2048)) &&
663 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
664 {
665 /* Set quota size */
666 QuotaSize = sizeof(OBJECT_HEADER_QUOTA_INFO);
668 }
669 else
670 {
671 /* No Quota */
672 QuotaSize = 0;
673 }
674
675 /* Check if we have a handle database */
676 if (ObjectType->TypeInfo.MaintainHandleCount)
677 {
678 /* Set handle database size */
679 HandleSize = sizeof(OBJECT_HEADER_HANDLE_INFO);
681 }
682 else
683 {
684 /* None */
685 HandleSize = 0;
686 }
687
688 /* Check if the Object has a name */
689 if (ObjectName->Buffer)
690 {
691 /* Set name size */
692 NameSize = sizeof(OBJECT_HEADER_NAME_INFO);
694 }
695 else
696 {
697 /* No name */
698 NameSize = 0;
699 }
700
701 /* Check if the Object maintains type lists */
702 if (ObjectType->TypeInfo.MaintainTypeList)
703 {
704 /* Set owner/creator size */
705 CreatorSize = sizeof(OBJECT_HEADER_CREATOR_INFO);
707 }
708 else
709 {
710 /* No info */
711 CreatorSize = 0;
712 }
713 }
714
715 /* Set final header size */
716 FinalSize = QuotaSize +
717 HandleSize +
718 NameSize +
719 CreatorSize +
721
722 /* Allocate memory for the Object and Header */
723 Header = ExAllocatePoolWithTag(PoolType, FinalSize + ObjectSize, Tag);
725
726 /* Check if we have a quota header */
727 if (QuotaSize)
728 {
729 /* Initialize quota info */
731 QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge;
732 QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge;
733 QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge;
734 QuotaInfo->ExclusiveProcess = NULL;
735 Header = (POBJECT_HEADER)(QuotaInfo + 1);
736 }
737
738 /* Check if we have a handle database header */
739 if (HandleSize)
740 {
741 /* Initialize Handle Info */
743 HandleInfo->SingleEntry.HandleCount = 0;
744 Header = (POBJECT_HEADER)(HandleInfo + 1);
745 }
746
747 /* Check if we have a name header */
748 if (NameSize)
749 {
750 /* Initialize the Object Name Info */
752 NameInfo->Name = *ObjectName;
753 NameInfo->Directory = NULL;
754 NameInfo->QueryReferences = 1;
755
756 /* Check if this is a call with the special protection flag */
757 if ((PreviousMode == KernelMode) &&
758 (ObjectCreateInfo) &&
759 (ObjectCreateInfo->Attributes & OBJ_KERNEL_EXCLUSIVE))
760 {
761 /* Set flag which will make the object protected from user-mode */
763 }
764
765 /* Set the header pointer */
766 Header = (POBJECT_HEADER)(NameInfo + 1);
767 }
768
769 /* Check if we have a creator header */
770 if (CreatorSize)
771 {
772 /* Initialize Creator Info */
773 CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)Header;
774 CreatorInfo->CreatorBackTraceIndex = 0;
776 InitializeListHead(&CreatorInfo->TypeList);
777 Header = (POBJECT_HEADER)(CreatorInfo + 1);
778 }
779
780 /* Check for quota information */
781 if (QuotaSize)
782 {
783 /* Set the offset */
784 Header->QuotaInfoOffset = (UCHAR)(QuotaSize +
785 HandleSize +
786 NameSize +
787 CreatorSize);
788 }
789 else
790 {
791 /* No offset */
792 Header->QuotaInfoOffset = 0;
793 }
794
795 /* Check for handle information */
796 if (HandleSize)
797 {
798 /* Set the offset */
799 Header->HandleInfoOffset = (UCHAR)(HandleSize +
800 NameSize +
801 CreatorSize);
802 }
803 else
804 {
805 /* No offset */
806 Header->HandleInfoOffset = 0;
807 }
808
809 /* Check for name information */
810 if (NameSize)
811 {
812 /* Set the offset */
813 Header->NameInfoOffset = (UCHAR)(NameSize + CreatorSize);
814 }
815 else
816 {
817 /* No Name */
818 Header->NameInfoOffset = 0;
819 }
820
821 /* Set the new object flag */
823
824 /* Remember if we have creator info */
825 if (CreatorSize) Header->Flags |= OB_FLAG_CREATOR_INFO;
826
827 /* Remember if we have handle info */
828 if (HandleSize) Header->Flags |= OB_FLAG_SINGLE_PROCESS;
829
830 /* Initialize the object header */
831 Header->PointerCount = 1;
832 Header->HandleCount = 0;
833 Header->Type = ObjectType;
834 Header->ObjectCreateInfo = ObjectCreateInfo;
835 Header->SecurityDescriptor = NULL;
836
837 /* Check if this is a permanent object */
838 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_PERMANENT))
839 {
840 /* Set the needed flag so we can check */
841 Header->Flags |= OB_FLAG_PERMANENT;
842 }
843
844 /* Check if this is an exclusive object */
845 if ((ObjectCreateInfo) && (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE))
846 {
847 /* Set the needed flag so we can check */
848 Header->Flags |= OB_FLAG_EXCLUSIVE;
849 }
850
851 /* Set kernel-mode flag */
853
854 /* Check if we have a type */
855 if (ObjectType)
856 {
857 /* Increase the number of objects of this type */
858 InterlockedIncrement((PLONG)&ObjectType->TotalNumberOfObjects);
859
860 /* Update the high water */
861 ObjectType->HighWaterNumberOfObjects = max(ObjectType->
862 TotalNumberOfObjects,
863 ObjectType->
864 HighWaterNumberOfObjects);
865 }
866
867 /* Return Header */
868 *ObjectHeader = Header;
869 return STATUS_SUCCESS;
870}
#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
ULONG HandleCount
Definition: obtypes.h:445
OBJECT_HANDLE_COUNT_ENTRY SingleEntry
Definition: obtypes.h:459
POBJECT_DIRECTORY Directory
Definition: obtypes.h:432
UNICODE_STRING Name
Definition: obtypes.h:433
PEPROCESS ExclusiveProcess
Definition: obtypes.h:476
#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:4065
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3815

Referenced by ObCreateObject(), and ObCreateObjectType().

◆ ObpAllocateObjectNameBuffer()

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

Definition at line 301 of file oblife.c.

304{
307
308 /* Set the maximum length to the length plus the terminator */
310
311 /* Check if we should use the lookaside buffer */
312 if (!(UseLookaside) || (MaximumLength > OBP_NAME_LOOKASIDE_MAX_SIZE))
313 {
314 /* Nope, allocate directly from pool */
315 /* Since we later use MaximumLength to detect that we're not allocating
316 * from a list, we need at least MaximumLength + sizeof(UNICODE_NULL)
317 * here.
318 *
319 * People do call this with UseLookasideList FALSE so the distinction
320 * is critical.
321 */
323 {
325 }
329 }
330 else
331 {
332 /* Allocate from the lookaside */
335 }
336
337 /* Setup the string */
338 ObjectName->MaximumLength = (USHORT)MaximumLength;
339 ObjectName->Length = (USHORT)Length;
340 ObjectName->Buffer = Buffer;
341 return Buffer;
342}
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 455 of file oblife.c.

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

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

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);
199 ObpCalloutEnd(CalloutIrql, "Security", ObjectType, Object);
200 }
201
202 /* Check if we have a delete procedure */
203 if (ObjectType->TypeInfo.DeleteProcedure)
204 {
205 /* Save whether we were deleted from worker thread or not */
206 if (!CalledFromWorkerThread) Header->Flags |= OB_FLAG_DEFER_DELETE;
207
208 /* Call it */
209 ObpCalloutStart(&CalloutIrql);
210 ObjectType->TypeInfo.DeleteProcedure(Object);
211 ObpCalloutEnd(CalloutIrql, "Delete", ObjectType, Object);
212 }
213
214 /* Now de-allocate all object members */
216}
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define 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 1417 of file oblife.c.

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

Referenced by ObInitSystem().

◆ ObpFreeObjectNameBuffer()

VOID NTAPI ObpFreeObjectNameBuffer ( IN PUNICODE_STRING  Name)

Definition at line 346 of file oblife.c.

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

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

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

Referenced by NtQueryObject().

◆ ObpReapObject()

VOID NTAPI ObpReapObject ( IN PVOID  Parameter)

Definition at line 220 of file oblife.c.

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

Referenced by ObInitSystem().

◆ ObpSetPermanentObject()

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

Definition at line 266 of file oblife.c.

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

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

◆ 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().