Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

obcreate.c File Reference

#include "obp.h"

Go to the source code of this file.

Functions

NTSTATUS ObCreateObject (IN KPROCESSOR_MODE ProbeMode, IN POBJECT_TYPE ObjectType, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN KPROCESSOR_MODE OwnershipMode, IN OUT PVOID ParseContext OPTIONAL, IN ULONG ObjectBodySize, IN ULONG PagedPoolCharge, IN ULONG NonPagedPoolCharge, OUT PVOID *Object)
NTSTATUS ObpCaptureObjectCreateInformation (IN POBJECT_TYPE ObjectType OPTIONAL, IN KPROCESSOR_MODE ProbeMode, IN POBJECT_ATTRIBUTES ObjectAttributes, IN OUT PUNICODE_STRING CapturedObjectName, IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN LOGICAL UseLookaside)
NTSTATUS ObpCaptureObjectName (IN KPROCESSOR_MODE ProbeMode, IN PUNICODE_STRING ObjectName, IN OUT PUNICODE_STRING CapturedObjectName, IN LOGICAL UseLookaside)
PWCHAR ObpAllocateObjectNameBuffer (IN ULONG Length, IN LOGICAL UseLookaside, IN OUT PUNICODE_STRING ObjectName)
VOID FASTCALL ObpFreeObjectNameBuffer (OUT PUNICODE_STRING ObjectName)
NTKERNELAPI VOID ObDeleteCapturedInsertInfo (IN PVOID Object)
NTSTATUS ObpAllocateObject (IN POBJECT_CREATE_INFORMATION ObjectCreateInfo, IN KPROCESSOR_MODE OwnershipMode, IN POBJECT_TYPE ObjectType OPTIONAL, IN PUNICODE_STRING ObjectName, IN ULONG ObjectBodySize, OUT POBJECT_HEADER *ReturnedObjectHeader)
VOID FASTCALL ObpFreeObject (IN PVOID Object)
VOID FASTCALL ObFreeObjectCreateInfoBuffer (IN POBJECT_CREATE_INFORMATION ObjectCreateInfo)

Variables

ULONG ObpObjectsCreated
ULONG ObpObjectsWithPoolQuota
ULONG ObpObjectsWithHandleDB
ULONG ObpObjectsWithName
ULONG ObpObjectsWithCreatorInfo


Function Documentation

NTSTATUS ObCreateObject IN KPROCESSOR_MODE  ProbeMode,
IN POBJECT_TYPE  ObjectType,
IN POBJECT_ATTRIBUTES ObjectAttributes  OPTIONAL,
IN KPROCESSOR_MODE  OwnershipMode,
IN OUT PVOID ParseContext  OPTIONAL,
IN ULONG  ObjectBodySize,
IN ULONG  PagedPoolCharge,
IN ULONG  NonPagedPoolCharge,
OUT PVOID *  Object
 

Definition at line 55 of file obcreate.c.

References _OBJECT_CREATE_INFORMATION::Attributes, _OBJECT_HEADER::Body, FALSE, _OBJECT_HEADER::Flags, _OBJECT_CREATE_INFORMATION::NonPagedPoolCharge, NT_SUCCESS, NTSTATUS(), NULL, OB_FLAG_PERMANENT_OBJECT, ObjectAttributes, ObpAllocateObject(), ObpAllocateObjectCreateInfoBuffer, ObpCaptureObjectCreateInformation(), ObpFreeObject(), ObpFreeObjectCreateInfoBuffer, ObpFreeObjectNameBuffer(), ObpReleaseObjectCreateInformation, PAGED_CODE, _OBJECT_CREATE_INFORMATION::PagedPoolCharge, SeCreatePermanentPrivilege, SeSinglePrivilegeCheck(), and Status.

Referenced by CmpCreateRegistryRoot(), CmpDoCreateChild(), CmpDoOpen(), ExCreateCallback(), IoCreateController(), IoCreateDevice(), IoCreateDriver(), IoCreateStreamFileObject(), IoCreateStreamFileObjectLite(), IopInitializeAttributesAndCreateObject(), IopLoadDriver(), IopParseDevice(), LpcpCreatePort(), MiSectionInitialization(), MmCreateSection(), NtAcceptConnectPort(), NtCreateChannel(), NtCreateDirectoryObject(), NtCreateEvent(), NtCreateEventPair(), NtCreateIoCompletion(), NtCreateJobObject(), NtCreateMutant(), NtCreateProfile(), NtCreateSemaphore(), NtCreateSuperSection(), NtCreateSymbolicLinkObject(), NtCreateTimer(), NtOpenChannel(), NtSecureConnectPort(), obtest(), PspCreateProcess(), PspCreateThread(), SepCreateToken(), SepDuplicateToken(), SepFilterToken(), xxxCreateDesktop2(), and xxxCreateWindowStation().

00069 : 00070 00071 This functions allocates space for an NT Object from either 00072 Paged or NonPaged pool. It captures the optional name and 00073 SECURITY_DESCRIPTOR parameters for later use when the object is 00074 inserted into an object table. No quota is charged at this time. 00075 That occurs when the object is inserted into an object table. 00076 00077 Arguments: 00078 00079 ProbeMode - The processor mode to consider when doing a probe 00080 of the input parameters 00081 00082 ObjectType - A pointer of the type returned by ObCreateObjectType 00083 that gives the type of object being created. 00084 00085 ObjectAttributes - Optionally supplies the attributes of the object 00086 being created (such as its name) 00087 00088 OwnershipMode - The processor mode of who is going to own the object 00089 00090 ParseContext - Ignored 00091 00092 ObjectBodySize - Number of bytes to allocate for the object body. The 00093 object body immediately follows the object header in memory and are 00094 part of a single allocation. 00095 00096 PagedPoolCharge - Supplies the amount of paged pool to charge for the 00097 object. If zero is specified then the default charge for the object 00098 type is used. 00099 00100 NonPagedPoolCharge - Supplies the amount of nonpaged pool to charge for 00101 the object. If zero is specified then the default charge for the 00102 object type is used. 00103 00104 Object - Receives a pointer to the newly created object 00105 00106 Return Value: 00107 00108 Following errors can occur: 00109 00110 - invalid object type 00111 - insufficient memory 00112 00113 --*/ 00114 00115 { 00116 UNICODE_STRING CapturedObjectName; 00117 POBJECT_CREATE_INFORMATION ObjectCreateInfo; 00118 POBJECT_HEADER ObjectHeader; 00119 NTSTATUS Status; 00120 00121 PAGED_CODE(); 00122 00123 // 00124 // Allocate a buffer to capture the object creation information. 00125 // 00126 00127 ObjectCreateInfo = ObpAllocateObjectCreateInfoBuffer(); 00128 00129 if (ObjectCreateInfo == NULL) { 00130 00131 Status = STATUS_INSUFFICIENT_RESOURCES; 00132 00133 } else { 00134 00135 // 00136 // Capture the object attributes, quality of service, and object 00137 // name, if specified. Otherwise, initialize the captured object 00138 // name, the security quality of service, and the create attributes 00139 // to default values. 00140 // 00141 00142 Status = ObpCaptureObjectCreateInformation( ObjectType, 00143 ProbeMode, 00144 ObjectAttributes, 00145 &CapturedObjectName, 00146 ObjectCreateInfo, 00147 FALSE ); 00148 00149 if (NT_SUCCESS(Status)) { 00150 00151 // 00152 // If the creation attributes are invalid, then return an error 00153 // status. 00154 // 00155 00156 if (ObjectType->TypeInfo.InvalidAttributes & ObjectCreateInfo->Attributes) { 00157 00158 Status = STATUS_INVALID_PARAMETER; 00159 00160 } else { 00161 00162 // 00163 // Set the paged and nonpaged pool quota charges for the 00164 // object allocation. 00165 // 00166 00167 if (PagedPoolCharge == 0) { 00168 00169 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge; 00170 } 00171 00172 if (NonPagedPoolCharge == 0) { 00173 00174 NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge; 00175 } 00176 00177 ObjectCreateInfo->PagedPoolCharge = PagedPoolCharge; 00178 ObjectCreateInfo->NonPagedPoolCharge = NonPagedPoolCharge; 00179 00180 // 00181 // Allocate and initialize the object. 00182 // 00183 00184 Status = ObpAllocateObject( ObjectCreateInfo, 00185 OwnershipMode, 00186 ObjectType, 00187 &CapturedObjectName, 00188 ObjectBodySize, 00189 &ObjectHeader ); 00190 00191 if (NT_SUCCESS(Status)) { 00192 00193 // 00194 // If a permanent object is being created, then check if 00195 // the caller has the appropriate privilege. 00196 // 00197 00198 *Object = &ObjectHeader->Body; 00199 00200 if (ObjectHeader->Flags & OB_FLAG_PERMANENT_OBJECT) { 00201 00202 if (!SeSinglePrivilegeCheck( SeCreatePermanentPrivilege, 00203 ProbeMode)) { 00204 00205 ObpFreeObject(*Object); 00206 00207 Status = STATUS_PRIVILEGE_NOT_HELD; 00208 } 00209 } 00210 00211 // 00212 // Here is the only successful path out of this module but 00213 // this path can also return privilege not held. 00214 // 00215 00216 return Status; 00217 } 00218 } 00219 00220 // 00221 // An error path, free the create information. 00222 // 00223 00224 ObpReleaseObjectCreateInformation(ObjectCreateInfo); 00225 00226 if (CapturedObjectName.Buffer != NULL) { 00227 00228 ObpFreeObjectNameBuffer(&CapturedObjectName); 00229 } 00230 } 00231 00232 // 00233 // An error path, free object creation information buffer. 00234 // 00235 00236 ObpFreeObjectCreateInfoBuffer(ObjectCreateInfo); 00237 } 00238 00239 // 00240 // An error path 00241 // 00242 00243 return Status; 00244 }

NTKERNELAPI VOID ObDeleteCapturedInsertInfo IN PVOID  Object  ) 
 

Definition at line 713 of file obcreate.c.

References _OBJECT_HEADER::Flags, NULL, OB_FLAG_NEW_OBJECT, OBJECT_TO_OBJECT_HEADER, _OBJECT_HEADER::ObjectCreateInfo, ObpFreeObjectCreateInformation, and PAGED_CODE.

Referenced by CcInitializeCacheMap(), SepCreateClientSecurity(), and SepCreateToken().

00719 : 00720 00721 This function frees the creation information that could be pointed at 00722 by the object header. 00723 00724 Arguments: 00725 00726 Object - Supplies the object being modified 00727 00728 Return Value: 00729 00730 None. 00731 00732 --*/ 00733 00734 { 00735 POBJECT_HEADER ObjectHeader; 00736 00737 PAGED_CODE(); 00738 00739 // 00740 // Get the address of the object header and free the object create 00741 // information object if the object is being created. 00742 // 00743 00744 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); 00745 00746 if (ObjectHeader->Flags & OB_FLAG_NEW_OBJECT) { 00747 00748 if (ObjectHeader->ObjectCreateInfo != NULL) { 00749 00750 ObpFreeObjectCreateInformation(ObjectHeader->ObjectCreateInfo); 00751 00752 ObjectHeader->ObjectCreateInfo = NULL; 00753 } 00754 } 00755 00756 return; 00757 }

VOID FASTCALL ObFreeObjectCreateInfoBuffer IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo  ) 
 

Definition at line 1279 of file obcreate.c.

References ObpFreeObjectCreateInfoBuffer.

Referenced by IoCreateStreamFileObjectLite().

01285 : 01286 01287 This function frees a create information buffer. Called from IO component 01288 01289 N.B. This function is nonpageable. 01290 01291 Arguments: 01292 01293 ObjectCreateInfo - Supplies a pointer to a create information buffer. 01294 01295 Return Value: 01296 01297 None. 01298 01299 --*/ 01300 01301 { 01302 ObpFreeObjectCreateInfoBuffer( ObjectCreateInfo ); 01303 01304 return; 01305 } }

NTSTATUS ObpAllocateObject IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo,
IN KPROCESSOR_MODE  OwnershipMode,
IN POBJECT_TYPE ObjectType  OPTIONAL,
IN PUNICODE_STRING  ObjectName,
IN ULONG  ObjectBodySize,
OUT POBJECT_HEADER ReturnedObjectHeader
 

Definition at line 761 of file obcreate.c.

References _OBJECT_HEADER_CREATOR_INFO::CreatorBackTraceIndex, _OBJECT_HEADER_CREATOR_INFO::CreatorUniqueProcess, DbgPrint, _OBJECT_HEADER_NAME_INFO::Directory, ExAllocatePoolWithTag, _OBJECT_HEADER_QUOTA_INFO::ExclusiveProcess, _OBJECT_HEADER::Flags, _OBJECT_HANDLE_COUNT_ENTRY::HandleCount, _OBJECT_HEADER::HandleCount, _OBJECT_HEADER::HandleInfoOffset, KernelMode, _OBJECT_HEADER_NAME_INFO::Name, _OBJECT_HEADER::NameInfoOffset, NonPagedPool, _OBJECT_HEADER_QUOTA_INFO::NonPagedPoolCharge, NTSTATUS(), NULL, OB_FLAG_CREATOR_INFO, OB_FLAG_EXCLUSIVE_OBJECT, OB_FLAG_KERNEL_OBJECT, OB_FLAG_NEW_OBJECT, OB_FLAG_PERMANENT_OBJECT, OB_FLAG_SINGLE_HANDLE_ENTRY, _OBJECT_HEADER::ObjectCreateInfo, ObpObjectsCreated, ObpObjectsWithCreatorInfo, ObpObjectsWithHandleDB, ObpObjectsWithName, ObpObjectsWithPoolQuota, PAGED_CODE, PagedPool, _OBJECT_HEADER_QUOTA_INFO::PagedPoolCharge, _OBJECT_HEADER::PointerCount, POOL_TYPE, PROTECTED_POOL, PsGetCurrentProcess, _OBJECT_HEADER::QuotaInfoOffset, SE_DEFAULT_SECURITY_QUOTA, _OBJECT_HEADER::SecurityDescriptor, _OBJECT_HEADER_QUOTA_INFO::SecurityDescriptorCharge, _OBJECT_HEADER_HANDLE_INFO::SingleEntry, Status, _OBJECT_HEADER::Type, and _OBJECT_HEADER_CREATOR_INFO::TypeList.

Referenced by ObCreateObject(), and ObCreateObjectType().

00772 : 00773 00774 This routine allocates a new object including the object header 00775 and body from pool and fill in the appropriate fields. 00776 00777 Arguments: 00778 00779 ObjectCreateInfo - Supplies the create information for the new object 00780 00781 OwnershipMode - Supplies the processor mode of who is going to own 00782 the object 00783 00784 ObjectType - Optionally supplies the object type of the object being 00785 created. If the object create info not null then this field must 00786 be supplied. 00787 00788 ObjectName - Supplies the name of the object being created 00789 00790 ObjectBodySize - Specifies the size, in bytes, of the body of the object 00791 being created 00792 00793 ReturnedObjectHeader - Receives a pointer to the object header for the 00794 newly created objet. 00795 00796 Return Value: 00797 00798 An appropriate status value. 00799 00800 --*/ 00801 00802 { 00803 ULONG HeaderSize; 00804 POBJECT_HEADER ObjectHeader; 00805 NTSTATUS Status; 00806 PVOID ZoneSegment; 00807 ULONG QuotaInfoSize; 00808 ULONG HandleInfoSize; 00809 ULONG NameInfoSize; 00810 ULONG CreatorInfoSize; 00811 POBJECT_HEADER_QUOTA_INFO QuotaInfo; 00812 POBJECT_HEADER_HANDLE_INFO HandleInfo; 00813 POBJECT_HEADER_NAME_INFO NameInfo; 00814 POBJECT_HEADER_CREATOR_INFO CreatorInfo; 00815 POOL_TYPE PoolType; 00816 00817 PAGED_CODE(); 00818 00819 ObpObjectsCreated += 1; 00820 00821 // 00822 // Compute the sizes of the optional object header components. 00823 // 00824 00825 if (ObjectCreateInfo == NULL) { 00826 00827 QuotaInfoSize = 0; 00828 HandleInfoSize = 0; 00829 NameInfoSize = sizeof( OBJECT_HEADER_NAME_INFO ); 00830 CreatorInfoSize = sizeof( OBJECT_HEADER_CREATOR_INFO ); 00831 00832 } else { 00833 00834 // 00835 // The caller specified some additional object create info 00836 // 00837 // First check to see if we need to set the quota 00838 // 00839 00840 if (ObjectCreateInfo->PagedPoolCharge != ObjectType->TypeInfo.DefaultPagedPoolCharge || 00841 ObjectCreateInfo->NonPagedPoolCharge != ObjectType->TypeInfo.DefaultNonPagedPoolCharge || 00842 ObjectCreateInfo->SecurityDescriptorCharge > SE_DEFAULT_SECURITY_QUOTA || 00843 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)) { 00844 00845 QuotaInfoSize = sizeof( OBJECT_HEADER_QUOTA_INFO ); 00846 ObpObjectsWithPoolQuota += 1; 00847 00848 } else { 00849 00850 QuotaInfoSize = 0; 00851 } 00852 00853 // 00854 // Check if we are to allocate space to maintain handle counts 00855 // 00856 00857 if (ObjectType->TypeInfo.MaintainHandleCount) { 00858 00859 HandleInfoSize = sizeof( OBJECT_HEADER_HANDLE_INFO ); 00860 ObpObjectsWithHandleDB += 1; 00861 00862 } else { 00863 00864 HandleInfoSize = 0; 00865 } 00866 00867 // 00868 // Check if we are to allocate space for the name 00869 // 00870 00871 if (ObjectName->Buffer != NULL) { 00872 00873 NameInfoSize = sizeof( OBJECT_HEADER_NAME_INFO ); 00874 ObpObjectsWithName += 1; 00875 00876 } else { 00877 00878 NameInfoSize = 0; 00879 } 00880 00881 // 00882 // Finally check if we are to maintain the creator info 00883 // 00884 00885 if (ObjectType->TypeInfo.MaintainTypeList) { 00886 00887 CreatorInfoSize = sizeof( OBJECT_HEADER_CREATOR_INFO ); 00888 ObpObjectsWithCreatorInfo += 1; 00889 00890 } else { 00891 00892 CreatorInfoSize = 0; 00893 } 00894 } 00895 00896 // 00897 // Now compute the total header size 00898 // 00899 00900 HeaderSize = QuotaInfoSize + 00901 HandleInfoSize + 00902 NameInfoSize + 00903 CreatorInfoSize + 00904 FIELD_OFFSET( OBJECT_HEADER, Body ); 00905 00906 // 00907 // Allocate and initialize the object. 00908 // 00909 // If the object type is not specified or specifies nonpaged pool, 00910 // then allocate the object from nonpaged pool. 00911 // Otherwise, allocate the object from paged pool. 00912 // 00913 00914 if ((ObjectType == NULL) || (ObjectType->TypeInfo.PoolType == NonPagedPool)) { 00915 00916 PoolType = NonPagedPool; 00917 00918 } else { 00919 00920 PoolType = PagedPool; 00921 } 00922 00923 ObjectHeader = ExAllocatePoolWithTag( PoolType, 00924 HeaderSize + ObjectBodySize, 00925 (ObjectType == NULL ? 'TjbO' : ObjectType->Key) | 00926 PROTECTED_POOL ); 00927 00928 if (ObjectHeader == NULL) { 00929 00930 return STATUS_INSUFFICIENT_RESOURCES; 00931 } 00932 00933 // 00934 // Now based on if we are to put in the quota, handle, name, or creator info we 00935 // will do the extra work. This order is very important because we rely on 00936 // it to free the object. 00937 // 00938 00939 if (QuotaInfoSize != 0) { 00940 00941 QuotaInfo = (POBJECT_HEADER_QUOTA_INFO)ObjectHeader; 00942 QuotaInfo->PagedPoolCharge = ObjectCreateInfo->PagedPoolCharge; 00943 QuotaInfo->NonPagedPoolCharge = ObjectCreateInfo->NonPagedPoolCharge; 00944 QuotaInfo->SecurityDescriptorCharge = ObjectCreateInfo->SecurityDescriptorCharge; 00945 QuotaInfo->ExclusiveProcess = NULL; 00946 ObjectHeader = (POBJECT_HEADER)(QuotaInfo + 1); 00947 } 00948 00949 if (HandleInfoSize != 0) { 00950 00951 HandleInfo = (POBJECT_HEADER_HANDLE_INFO)ObjectHeader; 00952 HandleInfo->SingleEntry.HandleCount = 0; 00953 ObjectHeader = (POBJECT_HEADER)(HandleInfo + 1); 00954 } 00955 00956 if (NameInfoSize != 0) { 00957 00958 NameInfo = (POBJECT_HEADER_NAME_INFO)ObjectHeader; 00959 NameInfo->Name = *ObjectName; 00960 NameInfo->Directory = NULL; 00961 ObjectHeader = (POBJECT_HEADER)(NameInfo + 1); 00962 } 00963 00964 if (CreatorInfoSize != 0) { 00965 00966 CreatorInfo = (POBJECT_HEADER_CREATOR_INFO)ObjectHeader; 00967 CreatorInfo->CreatorBackTraceIndex = 0; 00968 CreatorInfo->CreatorUniqueProcess = PsGetCurrentProcess()->UniqueProcessId; 00969 InitializeListHead( &CreatorInfo->TypeList ); 00970 ObjectHeader = (POBJECT_HEADER)(CreatorInfo + 1); 00971 } 00972 00973 // 00974 // Compute the proper offsets based on what we have 00975 // 00976 00977 if (QuotaInfoSize != 0) { 00978 00979 ObjectHeader->QuotaInfoOffset = (UCHAR)(QuotaInfoSize + HandleInfoSize + NameInfoSize + CreatorInfoSize); 00980 00981 } else { 00982 00983 ObjectHeader->QuotaInfoOffset = 0; 00984 } 00985 00986 if (HandleInfoSize != 0) { 00987 00988 ObjectHeader->HandleInfoOffset = (UCHAR)(HandleInfoSize + NameInfoSize + CreatorInfoSize); 00989 00990 } else { 00991 00992 ObjectHeader->HandleInfoOffset = 0; 00993 } 00994 00995 if (NameInfoSize != 0) { 00996 00997 ObjectHeader->NameInfoOffset = (UCHAR)(NameInfoSize + CreatorInfoSize); 00998 00999 } else { 01000 01001 ObjectHeader->NameInfoOffset = 0; 01002 } 01003 01004 // 01005 // Say that this is a new object, and conditionally set the other flags 01006 // 01007 01008 ObjectHeader->Flags = OB_FLAG_NEW_OBJECT; 01009 01010 if (CreatorInfoSize != 0) { 01011 01012 ObjectHeader->Flags |= OB_FLAG_CREATOR_INFO; 01013 } 01014 01015 if (HandleInfoSize != 0) { 01016 01017 ObjectHeader->Flags |= OB_FLAG_SINGLE_HANDLE_ENTRY; 01018 } 01019 01020 // 01021 // Set the counters and its type 01022 // 01023 01024 ObjectHeader->PointerCount = 1; 01025 ObjectHeader->HandleCount = 0; 01026 ObjectHeader->Type = ObjectType; 01027 01028 // 01029 // Initialize the object header. 01030 // 01031 // N.B. The initialization of the object header is done field by 01032 // field rather than zeroing the memory and then initializing 01033 // the pertinent fields. 01034 // 01035 // N.B. It is assumed that the caller will initialize the object 01036 // attributes, object ownership, and parse context. 01037 // 01038 01039 if (OwnershipMode == KernelMode) { 01040 01041 ObjectHeader->Flags |= OB_FLAG_KERNEL_OBJECT; 01042 } 01043 01044 if (ObjectCreateInfo != NULL && 01045 ObjectCreateInfo->Attributes & OBJ_PERMANENT ) { 01046 01047 ObjectHeader->Flags |= OB_FLAG_PERMANENT_OBJECT; 01048 } 01049 01050 if ((ObjectCreateInfo != NULL) && 01051 (ObjectCreateInfo->Attributes & OBJ_EXCLUSIVE)) { 01052 01053 ObjectHeader->Flags |= OB_FLAG_EXCLUSIVE_OBJECT; 01054 } 01055 01056 ObjectHeader->ObjectCreateInfo = ObjectCreateInfo; 01057 ObjectHeader->SecurityDescriptor = NULL; 01058 01059 if (ObjectType != NULL) { 01060 01061 ObjectType->TotalNumberOfObjects += 1; 01062 01063 if (ObjectType->TotalNumberOfObjects > ObjectType->HighWaterNumberOfObjects) { 01064 01065 ObjectType->HighWaterNumberOfObjects = ObjectType->TotalNumberOfObjects; 01066 } 01067 } 01068 01069 #if DBG 01070 01071 // 01072 // On a checked build echo out allocs 01073 // 01074 01075 if (ObpShowAllocAndFree) { 01076 01077 DbgPrint( "OB: Alloc %lx (%lx) %04lu", ObjectHeader, ObjectHeader, ObjectBodySize ); 01078 01079 if (ObjectType) { 01080 01081 DbgPrint(" - %wZ\n", &ObjectType->Name ); 01082 01083 } else { 01084 01085 DbgPrint(" - Type\n" ); 01086 } 01087 } 01088 #endif 01089 01090 *ReturnedObjectHeader = ObjectHeader; 01091 01092 return STATUS_SUCCESS; 01093 }

PWCHAR ObpAllocateObjectNameBuffer IN ULONG  Length,
IN LOGICAL  UseLookaside,
IN OUT PUNICODE_STRING  ObjectName
 

Definition at line 583 of file obcreate.c.

References Buffer, ExAllocateFromPPNPagedLookasideList(), ExAllocatePoolWithTag, FALSE, LookasideNameBufferList, NonPagedPool, OBJECT_NAME_BUFFER_SIZE, and USHORT.

Referenced by ObpCaptureObjectName().

00591 : 00592 00593 This function allocates an object name buffer. 00594 00595 N.B. This function is nonpageable. 00596 00597 Arguments: 00598 00599 Length - Supplies the length of the required buffer in bytes. 00600 00601 UseLookaside - Supplies a logical variable that determines whether an 00602 attempt is made to allocate the name buffer from the lookaside list. 00603 00604 ObjectName - Supplies a pointer to a name buffer string descriptor. 00605 00606 Return Value: 00607 00608 If the allocation is successful, then name buffer string descriptor 00609 is initialized and the address of the name buffer is returned as the 00610 function value. Otherwise, a value of NULL is returned. 00611 00612 --*/ 00613 00614 { 00615 PVOID Buffer; 00616 ULONG Maximum; 00617 KIRQL OldIrql; 00618 PKPRCB Prcb; 00619 00620 // 00621 // If allocation from the lookaside lists is specified and the buffer 00622 // size is less than the size of lookaside list entries, then attempt 00623 // to allocate the name buffer from the lookaside lists. Otherwise, 00624 // attempt to allocate the name buffer from nonpaged pool. 00625 // 00626 00627 Maximum = Length + sizeof(WCHAR); 00628 00629 if ((UseLookaside == FALSE) || (Maximum > OBJECT_NAME_BUFFER_SIZE)) { 00630 00631 // 00632 // Attempt to allocate the buffer from nonpaged pool. 00633 // 00634 00635 Buffer = ExAllocatePoolWithTag(NonPagedPool, Maximum, 'mNbO'); 00636 00637 } else { 00638 00639 // 00640 // Attempt to allocate the name buffer from the lookaside list. If 00641 // the allocation attempt fails, then attempt to allocate the name 00642 // buffer from pool. 00643 // 00644 00645 Maximum = OBJECT_NAME_BUFFER_SIZE; 00646 Buffer = ExAllocateFromPPNPagedLookasideList(LookasideNameBufferList); 00647 } 00648 00649 // 00650 // Initialize the string descriptor and return the buffer address. 00651 // 00652 00653 ObjectName->Length = (USHORT)Length; 00654 ObjectName->MaximumLength = (USHORT)Maximum; 00655 ObjectName->Buffer = Buffer; 00656 00657 return (PWCHAR)Buffer; 00658 }

NTSTATUS ObpCaptureObjectCreateInformation IN POBJECT_TYPE ObjectType  OPTIONAL,
IN KPROCESSOR_MODE  ProbeMode,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN OUT PUNICODE_STRING  CapturedObjectName,
IN POBJECT_CREATE_INFORMATION  ObjectCreateInfo,
IN LOGICAL  UseLookaside
 

Definition at line 248 of file obcreate.c.

References ExSystemExceptionFilter(), KernelMode, NT_SUCCESS, NTSTATUS(), NULL, ObjectAttributes, ObpCaptureObjectName(), ObpReleaseObjectCreateInformation, PAGED_CODE, PagedPool, ProbeForRead, SeCaptureSecurityDescriptor(), SeComputeQuotaInformationSize(), SeComputeSecurityQuota, SecurityQos, Size, Status, and TRUE.

00259 : 00260 00261 This function captures the object creation information and stuff 00262 it into the input variable ObjectCreateInfo 00263 00264 Arguments: 00265 00266 ObjectType - Specifies the type of object we expect to capture, 00267 currently ignored. 00268 00269 ProbeMode - Specifies the processor mode for doing our parameter 00270 probes 00271 00272 ObjectAttributes - Supplies the object attributes we are trying 00273 to capture 00274 00275 CapturedObjectName - Recieves the name of the object being created 00276 00277 ObjectCreateInfo - Receives the create information for the object 00278 like its root, attributes, and security information 00279 00280 UseLookaside - Specifies if we are to allocate the captured name 00281 buffer from the lookaside list or from straight pool. 00282 00283 Return Value: 00284 00285 An appropriate status value 00286 00287 --*/ 00288 00289 { 00290 PUNICODE_STRING ObjectName; 00291 PSECURITY_DESCRIPTOR SecurityDescriptor; 00292 PSECURITY_QUALITY_OF_SERVICE SecurityQos; 00293 NTSTATUS Status; 00294 ULONG Size; 00295 00296 PAGED_CODE(); 00297 00298 // 00299 // Capture the object attributes, the security quality of service, if 00300 // specified, and object name, if specified. 00301 // 00302 00303 Status = STATUS_SUCCESS; 00304 00305 RtlZeroMemory(ObjectCreateInfo, sizeof(OBJECT_CREATE_INFORMATION)); 00306 00307 try { 00308 00309 if (ARGUMENT_PRESENT(ObjectAttributes)) { 00310 00311 // 00312 // Probe the object attributes if necessary. 00313 // 00314 00315 if (ProbeMode != KernelMode) { 00316 00317 ProbeForRead( ObjectAttributes, 00318 sizeof(OBJECT_ATTRIBUTES), 00319 sizeof(ULONG) ); 00320 } 00321 00322 if (ObjectAttributes->Length != sizeof(OBJECT_ATTRIBUTES) || 00323 (ObjectAttributes->Attributes & ~OBJ_VALID_ATTRIBUTES)) { 00324 00325 Status = STATUS_INVALID_PARAMETER; 00326 00327 goto failureExit; 00328 } 00329 00330 // 00331 // Capture the object attributes. 00332 // 00333 00334 ObjectCreateInfo->RootDirectory = ObjectAttributes->RootDirectory; 00335 ObjectCreateInfo->Attributes = ObjectAttributes->Attributes & OBJ_VALID_ATTRIBUTES; 00336 ObjectName = ObjectAttributes->ObjectName; 00337 SecurityDescriptor = ObjectAttributes->SecurityDescriptor; 00338 SecurityQos = ObjectAttributes->SecurityQualityOfService; 00339 00340 if (ARGUMENT_PRESENT(SecurityDescriptor)) { 00341 00342 Status = SeCaptureSecurityDescriptor( SecurityDescriptor, 00343 ProbeMode, 00344 PagedPool, 00345 TRUE, 00346 &ObjectCreateInfo->SecurityDescriptor ); 00347 00348 if (!NT_SUCCESS(Status)) { 00349 00350 KdPrint(( "OB: Failed to capture security descriptor at %08x - Status == %08x\n", 00351 SecurityDescriptor, 00352 Status) ); 00353 00354 // 00355 // The cleanup routine depends on this being NULL if it isn't 00356 // allocated. SeCaptureSecurityDescriptor may modify this 00357 // parameter even if it fails. 00358 // 00359 00360 ObjectCreateInfo->SecurityDescriptor = NULL; 00361 00362 goto failureExit; 00363 } 00364 00365 SeComputeQuotaInformationSize( ObjectCreateInfo->SecurityDescriptor, 00366 &Size ); 00367 00368 ObjectCreateInfo->SecurityDescriptorCharge = SeComputeSecurityQuota( Size ); 00369 ObjectCreateInfo->ProbeMode = ProbeMode; 00370 } 00371 00372 if (ARGUMENT_PRESENT(SecurityQos)) { 00373 00374 if (ProbeMode != KernelMode) { 00375 00376 ProbeForRead( SecurityQos, sizeof(*SecurityQos), sizeof(ULONG)); 00377 } 00378 00379 ObjectCreateInfo->SecurityQualityOfService = *SecurityQos; 00380 ObjectCreateInfo->SecurityQos = &ObjectCreateInfo->SecurityQualityOfService; 00381 } 00382 00383 } else { 00384 00385 ObjectName = NULL; 00386 } 00387 00388 } except (ExSystemExceptionFilter()) { 00389 00390 Status = GetExceptionCode(); 00391 00392 goto failureExit; 00393 } 00394 00395 // 00396 // If an object name is specified, then capture the object name. 00397 // Otherwise, initialize the object name descriptor and check for 00398 // an incorrectly specified root directory. 00399 // 00400 00401 if (ARGUMENT_PRESENT(ObjectName)) { 00402 00403 Status = ObpCaptureObjectName( ProbeMode, 00404 ObjectName, 00405 CapturedObjectName, 00406 UseLookaside ); 00407 00408 } else { 00409 00410 CapturedObjectName->Buffer = NULL; 00411 CapturedObjectName->Length = 0; 00412 CapturedObjectName->MaximumLength = 0; 00413 00414 if (ARGUMENT_PRESENT(ObjectCreateInfo->RootDirectory)) { 00415 00416 Status = STATUS_OBJECT_NAME_INVALID; 00417 } 00418 } 00419 00420 // 00421 // If the completion status is not successful, and a security quality 00422 // of service parameter was specified, then free the security quality 00423 // of service memory. 00424 // 00425 00426 failureExit: 00427 00428 if (!NT_SUCCESS(Status)) { 00429 00430 ObpReleaseObjectCreateInformation(ObjectCreateInfo); 00431 } 00432 00433 return Status; 00434 }

NTSTATUS ObpCaptureObjectName IN KPROCESSOR_MODE  ProbeMode,
IN PUNICODE_STRING  ObjectName,
IN OUT PUNICODE_STRING  CapturedObjectName,
IN LOGICAL  UseLookaside
 

Definition at line 438 of file obcreate.c.

References ExFreePool(), ExSystemExceptionFilter(), KernelMode, NTSTATUS(), NULL, ObpAllocateObjectNameBuffer(), PAGED_CODE, ProbeAndReadUnicodeString, ProbeForRead, and Status.

Referenced by ObpCaptureObjectCreateInformation(), and ObReferenceObjectByName().

00447 : 00448 00449 This function captures the object name but first verifies that 00450 it is at least properly sized. 00451 00452 Arguments: 00453 00454 ProbeMode - Supplies the processor mode to use when probing 00455 the object name 00456 00457 ObjectName - Supplies the caller's version of the object name 00458 00459 CapturedObjectName - Receives the captured verified version 00460 of the object name 00461 00462 UseLookaside - Indicates if the captured name buffer should be 00463 allocated from the lookaside list or from straight pool 00464 00465 Return Value: 00466 00467 An appropriate status value 00468 00469 --*/ 00470 00471 { 00472 PWCH FreeBuffer; 00473 UNICODE_STRING InputObjectName; 00474 ULONG Length; 00475 NTSTATUS Status; 00476 00477 PAGED_CODE(); 00478 00479 // 00480 // Initialize the object name descriptor and capture the specified name 00481 // string. 00482 // 00483 00484 CapturedObjectName->Buffer = NULL; 00485 CapturedObjectName->Length = 0; 00486 CapturedObjectName->MaximumLength = 0; 00487 00488 Status = STATUS_SUCCESS; 00489 00490 try { 00491 00492 // 00493 // Probe and capture the name string descriptor and probe the 00494 // name string, if necessary. 00495 // 00496 00497 FreeBuffer = NULL; 00498 00499 if (ProbeMode != KernelMode) { 00500 00501 InputObjectName = ProbeAndReadUnicodeString(ObjectName); 00502 00503 ProbeForRead( InputObjectName.Buffer, 00504 InputObjectName.Length, 00505 sizeof(WCHAR) ); 00506 00507 } else { 00508 00509 InputObjectName = *ObjectName; 00510 } 00511 00512 // 00513 // If the length of the string is not zero, then capture the string. 00514 // 00515 00516 if (InputObjectName.Length != 0) { 00517 00518 // 00519 // If the length of the string is not an even multiple of the 00520 // size of a UNICODE character or cannot be zero terminated, 00521 // then return an error. 00522 // 00523 00524 Length = InputObjectName.Length; 00525 00526 if (((Length & (sizeof(WCHAR) - 1)) != 0) || 00527 (Length == (MAXUSHORT - sizeof(WCHAR) + 1))) { 00528 00529 Status = STATUS_OBJECT_NAME_INVALID; 00530 00531 } else { 00532 00533 // 00534 // Allocate a buffer for the specified name string. 00535 // 00536 // N.B. The name buffer allocation routine adds one 00537 // UNICODE character to the length and initializes 00538 // the string descriptor. 00539 // 00540 00541 FreeBuffer = ObpAllocateObjectNameBuffer( Length, 00542 UseLookaside, 00543 CapturedObjectName ); 00544 00545 if (FreeBuffer == NULL) { 00546 00547 Status = STATUS_INSUFFICIENT_RESOURCES; 00548 00549 } else { 00550 00551 // 00552 // Copy the specified name string to the destination 00553 // buffer. 00554 // 00555 00556 RtlMoveMemory(FreeBuffer, InputObjectName.Buffer, Length); 00557 00558 // 00559 // Zero terminate the name string and initialize the 00560 // string descriptor. 00561 // 00562 00563 FreeBuffer[Length / sizeof(WCHAR)] = UNICODE_NULL; 00564 } 00565 } 00566 } 00567 00568 } except(ExSystemExceptionFilter()) { 00569 00570 Status = GetExceptionCode(); 00571 00572 if (FreeBuffer != NULL) { 00573 00574 ExFreePool(FreeBuffer); 00575 } 00576 } 00577 00578 return Status; 00579 }

VOID FASTCALL ObpFreeObject IN PVOID  Object  ) 
 

Definition at line 1098 of file obcreate.c.

References DbgPrint, _OBJECT_TYPE_INITIALIZER::DefaultNonPagedPoolCharge, _OBJECT_TYPE_INITIALIZER::DefaultPagedPoolCharge, ExFreePool(), ExFreePoolWithTag, _OBJECT_HEADER_HANDLE_INFO::HandleCountDataBase, _OBJECT_TYPE::Name, _OBJECT_HEADER_NAME_INFO::Name, _OBJECT_HEADER_QUOTA_INFO::NonPagedPoolCharge, NULL, OB_FLAG_DEFAULT_SECURITY_QUOTA, OB_FLAG_NEW_OBJECT, OB_FLAG_SINGLE_HANDLE_ENTRY, OBJECT_HEADER_TO_CREATOR_INFO, OBJECT_HEADER_TO_HANDLE_INFO, OBJECT_HEADER_TO_NAME_INFO, OBJECT_HEADER_TO_QUOTA_INFO, OBJECT_TO_OBJECT_HEADER, ObpFreeObjectCreateInformation, PAGED_CODE, _OBJECT_HEADER_QUOTA_INFO::PagedPoolCharge, PROTECTED_POOL, PsReturnSharedPoolQuota(), SE_DEFAULT_SECURITY_QUOTA, _OBJECT_HEADER_QUOTA_INFO::SecurityDescriptorCharge, _OBJECT_TYPE::TotalNumberOfObjects, _OBJECT_HEADER::Type, and _OBJECT_TYPE::TypeInfo.

Referenced by ObCreateObject(), and ObpRemoveObjectRoutine().

01104 : 01105 01106 This routine undoes ObpAllocateObject. It returns the object back to free pool. 01107 01108 Arguments: 01109 01110 Object - Supplies a pointer to the body of the object being freed. 01111 01112 Return Value: 01113 01114 None. 01115 01116 --*/ 01117 01118 { 01119 POBJECT_HEADER ObjectHeader; 01120 POBJECT_TYPE ObjectType; 01121 POBJECT_HEADER_QUOTA_INFO QuotaInfo; 01122 POBJECT_HEADER_HANDLE_INFO HandleInfo; 01123 POBJECT_HEADER_NAME_INFO NameInfo; 01124 POBJECT_HEADER_CREATOR_INFO CreatorInfo; 01125 PVOID FreeBuffer; 01126 ULONG NonPagedPoolCharge; 01127 ULONG PagedPoolCharge; 01128 01129 PAGED_CODE(); 01130 01131 // 01132 // Get the address of the object header. 01133 // 01134 01135 ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object); 01136 ObjectType = ObjectHeader->Type; 01137 01138 // 01139 // Now from the header determine the start of the allocation. We need 01140 // to backup based on what precedes the header. The order is very 01141 // important and must be the inverse of that used by ObpAllocateObject 01142 // 01143 01144 FreeBuffer = ObjectHeader; 01145 01146 CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader ); 01147 01148 if (CreatorInfo != NULL) { 01149 01150 FreeBuffer = CreatorInfo; 01151 } 01152 01153 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader ); 01154 01155 if (NameInfo != NULL) { 01156 01157 FreeBuffer = NameInfo; 01158 } 01159 01160 HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO( ObjectHeader ); 01161 01162 if (HandleInfo != NULL) { 01163 01164 FreeBuffer = HandleInfo; 01165 } 01166 01167 QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader ); 01168 01169 if (QuotaInfo != NULL) { 01170 01171 FreeBuffer = QuotaInfo; 01172 } 01173 01174 #if DBG 01175 01176 // 01177 // On a checked build echo out frees 01178 // 01179 01180 if (ObpShowAllocAndFree) { 01181 01182 DbgPrint( "OB: Free %lx (%lx) - Type: %wZ\n", ObjectHeader, ObjectHeader, &ObjectType->Name ); 01183 } 01184 #endif 01185 01186 // 01187 // Decrement the number of objects of this type 01188 // 01189 01190 ObjectType->TotalNumberOfObjects -= 1; 01191 01192 // 01193 // Check where we were in the object initialization phase. This 01194 // flag really only tests if we have charged quota for this object. 01195 // This is because the object create info and the quota block charged 01196 // are unioned together. 01197 // 01198 01199 if (ObjectHeader->Flags & OB_FLAG_NEW_OBJECT) { 01200 01201 if (ObjectHeader->ObjectCreateInfo != NULL) { 01202 01203 ObpFreeObjectCreateInformation( ObjectHeader->ObjectCreateInfo ); 01204 01205 ObjectHeader->ObjectCreateInfo = NULL; 01206 } 01207 01208 } else { 01209 01210 if (ObjectHeader->QuotaBlockCharged != NULL) { 01211 01212 if (QuotaInfo != NULL) { 01213 01214 PagedPoolCharge = QuotaInfo->PagedPoolCharge + 01215 QuotaInfo->SecurityDescriptorCharge; 01216 01217 NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge; 01218 01219 } else { 01220 01221 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge; 01222 01223 if (ObjectHeader->Flags & OB_FLAG_DEFAULT_SECURITY_QUOTA ) { 01224 01225 PagedPoolCharge += SE_DEFAULT_SECURITY_QUOTA; 01226 } 01227 01228 NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge; 01229 } 01230 01231 PsReturnSharedPoolQuota( ObjectHeader->QuotaBlockCharged, 01232 PagedPoolCharge, 01233 NonPagedPoolCharge ); 01234 } 01235 } 01236 01237 if ((HandleInfo != NULL) && 01238 ((ObjectHeader->Flags & OB_FLAG_SINGLE_HANDLE_ENTRY) == 0)) { 01239 01240 // 01241 // If a handle database has been allocated, then free the memory. 01242 // 01243 01244 ExFreePool( HandleInfo->HandleCountDataBase ); 01245 01246 HandleInfo->HandleCountDataBase = NULL; 01247 } 01248 01249 // 01250 // If a name string buffer has been allocated, then free the memory. 01251 // 01252 01253 if (NameInfo != NULL && NameInfo->Name.Buffer != NULL) { 01254 01255 ExFreePool( NameInfo->Name.Buffer ); 01256 01257 NameInfo->Name.Buffer = NULL; 01258 } 01259 01260 // 01261 // Trash type field so we don't get far if we attempt to 01262 // use a stale object pointer to this object. 01263 // 01264 // Sundown Note: trash it by zero-extended it. 01265 // sign-extension will create a valid kernel address. 01266 01267 01268 ObjectHeader->Type = UIntToPtr(0xBAD0B0B0); 01269 ExFreePoolWithTag( FreeBuffer, 01270 (ObjectType == NULL ? 'TjbO' : ObjectType->Key) | 01271 PROTECTED_POOL ); 01272 01273 return; 01274 }

VOID FASTCALL ObpFreeObjectNameBuffer OUT PUNICODE_STRING  ObjectName  ) 
 

Definition at line 663 of file obcreate.c.

References Buffer, ExFreePool(), ExFreeToPPNPagedLookasideList(), LookasideNameBufferList, and OBJECT_NAME_BUFFER_SIZE.

00669 : 00670 00671 This function frees an object name buffer. 00672 00673 N.B. This function is nonpageable. 00674 00675 Arguments: 00676 00677 ObjectName - Supplies a pointer to a name buffer string descriptor. 00678 00679 Return Value: 00680 00681 None. 00682 00683 --*/ 00684 00685 { 00686 PVOID Buffer; 00687 KIRQL OldIrql; 00688 PKPRCB Prcb; 00689 00690 // 00691 // If the size of the buffer is not equal to the size of lookaside list 00692 // entries, then free the buffer to pool. Otherwise, free the buffer to 00693 // the lookaside list. 00694 // 00695 00696 Buffer = ObjectName->Buffer; 00697 00698 if (ObjectName->MaximumLength != OBJECT_NAME_BUFFER_SIZE) { 00699 00700 ExFreePool(Buffer); 00701 00702 } else { 00703 00704 ExFreeToPPNPagedLookasideList(LookasideNameBufferList, Buffer); 00705 } 00706 00707 return; 00708 }


Variable Documentation

ULONG ObpObjectsCreated
 

Definition at line 47 of file obcreate.c.

Referenced by ObpAllocateObject().

ULONG ObpObjectsWithCreatorInfo
 

Definition at line 51 of file obcreate.c.

Referenced by ObpAllocateObject().

ULONG ObpObjectsWithHandleDB
 

Definition at line 49 of file obcreate.c.

Referenced by ObpAllocateObject().

ULONG ObpObjectsWithName
 

Definition at line 50 of file obcreate.c.

Referenced by ObpAllocateObject().

ULONG ObpObjectsWithPoolQuota
 

Definition at line 48 of file obcreate.c.

Referenced by ObpAllocateObject().


Generated on Sat May 15 19:44:57 2004 for test by doxygen 1.3.7