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

obinit.c File Reference

#include "obp.h"

Go to the source code of this file.

Classes

struct  _OBP_FIND_HANDLE_DATA

Typedefs

typedef _OBP_FIND_HANDLE_DATA OBP_FIND_HANDLE_DATA
typedef _OBP_FIND_HANDLE_DATAPOBP_FIND_HANDLE_DATA

Functions

NTSTATUS ObpCreateDosDevicesDirectory (VOID)
NTSTATUS ObpGetDosDevicesProtection (PSECURITY_DESCRIPTOR SecurityDescriptor)
VOID ObpFreeDosDevicesProtection (PSECURITY_DESCRIPTOR SecurityDescriptor)
BOOLEAN ObInitSystem (VOID)
BOOLEAN ObDupHandleProcedure (PEPROCESS Process, PHANDLE_TABLE_ENTRY ObjectTableEntry)
BOOLEAN ObAuditInheritedHandleProcedure (IN PHANDLE_TABLE_ENTRY ObjectTableEntry, IN HANDLE HandleId, IN PVOID EnumParameter)
NTSTATUS ObInitProcess (PEPROCESS ParentProcess OPTIONAL, PEPROCESS NewProcess)
VOID ObInitProcess2 (PEPROCESS NewProcess)
VOID ObDestroyHandleProcedure (IN HANDLE HandleIndex)
VOID ObKillProcess (BOOLEAN AcquireLock, PEPROCESS Process)
BOOLEAN ObpEnumFindHandleProcedure (PHANDLE_TABLE_ENTRY ObjectTableEntry, HANDLE HandleId, PVOID EnumParameter)
BOOLEAN ObFindHandleForObject (IN PEPROCESS Process, IN PVOID Object OPTIONAL, IN POBJECT_TYPE ObjectType OPTIONAL, IN POBJECT_HANDLE_INFORMATION HandleInformation OPTIONAL, OUT PHANDLE Handle)

Variables

GENERIC_MAPPING ObpTypeMapping
GENERIC_MAPPING ObpDirectoryMapping
GENERIC_MAPPING ObpSymbolicLinkMapping
EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
KMUTANT ObpInitKillMutant
ULONG ObpProtectionMode
ULONG ObpAuditBaseDirectories
ULONG ObpAuditBaseObjects
UNICODE_STRING ObpDosDevicesShortName
ULARGE_INTEGER ObpDosDevicesShortNamePrefix
ULARGE_INTEGER ObpDosDevicesShortNameRoot
PDEVICE_MAP ObSystemDeviceMap


Typedef Documentation

typedef struct _OBP_FIND_HANDLE_DATA OBP_FIND_HANDLE_DATA
 

typedef struct _OBP_FIND_HANDLE_DATA * POBP_FIND_HANDLE_DATA
 

Referenced by ObpEnumFindHandleProcedure().


Function Documentation

BOOLEAN ObAuditInheritedHandleProcedure IN PHANDLE_TABLE_ENTRY  ObjectTableEntry,
IN HANDLE  HandleId,
IN PVOID  EnumParameter
 

Definition at line 759 of file obinit.c.

References FALSE, OBJ_AUDIT_OBJECT_CLOSE, _SE_PROCESS_AUDIT_INFO::Parent, _SE_PROCESS_AUDIT_INFO::Process, PSE_PROCESS_AUDIT_INFO, and SeAuditHandleDuplication().

Referenced by ObInitProcess().

00767 : 00768 00769 ExEnumHandleTable worker routine to generate audits when handles are 00770 inherited. An audit is generated if the handle attributes indicate 00771 that the handle is to be audited on close. 00772 00773 Arguments: 00774 00775 ObjectTableEntry - Points to the handle table entry of interest. 00776 00777 HandleId - Supplies the handle. 00778 00779 EnumParameter - Supplies information about the source and target processes. 00780 00781 Return Value: 00782 00783 FALSE, which tells ExEnumHandleTable to continue iterating through the 00784 handle table. 00785 00786 --*/ 00787 00788 { 00789 PSE_PROCESS_AUDIT_INFO ProcessAuditInfo = EnumParameter; 00790 00791 // 00792 // Check if we have to do an audit 00793 // 00794 00795 if (!(ObjectTableEntry->ObAttributes & OBJ_AUDIT_OBJECT_CLOSE)) { 00796 00797 return( FALSE ); 00798 } 00799 00800 // 00801 // Do the audit then return for more 00802 // 00803 00804 SeAuditHandleDuplication( HandleId, 00805 HandleId, 00806 ProcessAuditInfo->Parent, 00807 ProcessAuditInfo->Process ); 00808 00809 return( FALSE ); 00810 }

VOID ObDestroyHandleProcedure IN HANDLE  HandleIndex  ) 
 

Definition at line 991 of file obinit.c.

Referenced by ObKillProcess().

00997 : 00998 00999 This function is used to close a handle but takes as input a 01000 handle table index that it first translates to an handle 01001 before calling close. Note that the handle index is really 01002 just the offset within the handle table entries. 01003 01004 Arguments: 01005 01006 HandleIndex - Supplies a handle index for the handle being closed. 01007 01008 Return Value: 01009 01010 None. 01011 01012 --*/ 01013 01014 { 01015 ZwClose( HandleIndex ); 01016 01017 return; 01018 }

BOOLEAN ObDupHandleProcedure PEPROCESS  Process,
PHANDLE_TABLE_ENTRY  ObjectTableEntry
 

Definition at line 658 of file obinit.c.

References _OBJECT_HEADER::Body, FALSE, _HANDLE_TABLE_ENTRY::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccessIndex, KernelMode, NT_SUCCESS, NtGlobalFlag, NTSTATUS(), _HANDLE_TABLE_ENTRY::ObAttributes, ObInheritHandle, OBJ_HANDLE_ATTRIBUTES, _HANDLE_TABLE_ENTRY::Object, ObpIncrementHandleCount(), ObpIncrPointerCount, _ACCESS_STATE::PreviouslyGrantedAccess, Status, TRUE, and _OBJECT_HEADER::Type.

Referenced by ObInitProcess().

00665 : 00666 00667 This is the worker routine for ExDupHandleTable and 00668 is invoked via ObInitProcess. 00669 00670 Arguments: 00671 00672 Process - Supplies a pointer to the new process 00673 00674 ObjectTableEntry - Supplies a pointer to the newly 00675 created handle table entry 00676 00677 Return Value: 00678 00679 TRUE if the item can be inserted in the new table 00680 and FALSE otherwise 00681 00682 --*/ 00683 00684 { 00685 NTSTATUS Status; 00686 POBJECT_HEADER ObjectHeader; 00687 PVOID Object; 00688 ACCESS_STATE AccessState; 00689 00690 // 00691 // If the object table should not inherited then return false 00692 // 00693 00694 if (!(ObjectTableEntry->ObAttributes & OBJ_INHERIT)) { 00695 00696 return( FALSE ); 00697 } 00698 00699 // 00700 // Get a pointer to the object header and body 00701 // 00702 00703 ObjectHeader = (POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~OBJ_HANDLE_ATTRIBUTES); 00704 00705 Object = &ObjectHeader->Body; 00706 00707 // 00708 // If we are tracing the call stacks for cached security indices then we do got a 00709 // translation to do otherwise the table entry contains straight away the granted 00710 // access mask 00711 // 00712 00713 #if i386 && !FPO 00714 00715 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) { 00716 00717 AccessState.PreviouslyGrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex ); 00718 00719 } else { 00720 00721 AccessState.PreviouslyGrantedAccess = ObjectTableEntry->GrantedAccess; 00722 } 00723 00724 #else 00725 00726 AccessState.PreviouslyGrantedAccess = ObjectTableEntry->GrantedAccess; 00727 00728 #endif // i386 && !FPO 00729 00730 // 00731 // Increment the handle count on the object because we've just added 00732 // another handle to it. 00733 // 00734 00735 Status = ObpIncrementHandleCount( ObInheritHandle, 00736 Process, 00737 Object, 00738 ObjectHeader->Type, 00739 &AccessState, 00740 KernelMode, // BUGBUG this is probably wrong 00741 0 ); 00742 00743 if (!NT_SUCCESS( Status )) { 00744 00745 return( FALSE ); 00746 } 00747 00748 // 00749 // Likewise we need to increment the pointer count to the object 00750 // 00751 00752 ObpIncrPointerCount( ObjectHeader ); 00753 00754 return( TRUE ); 00755 }

BOOLEAN ObFindHandleForObject IN PEPROCESS  Process,
IN PVOID Object  OPTIONAL,
IN POBJECT_TYPE ObjectType  OPTIONAL,
IN POBJECT_HANDLE_INFORMATION HandleInformation  OPTIONAL,
OUT PHANDLE  Handle
 

Definition at line 1234 of file obinit.c.

References Executive, ExEnumHandleTable(), FALSE, Handle, _OBP_FIND_HANDLE_DATA::HandleInformation, KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseMutant(), KernelMode, KeWaitForSingleObject(), NULL, OBJECT_TO_OBJECT_HEADER, _OBP_FIND_HANDLE_DATA::ObjectHeader, _OBP_FIND_HANDLE_DATA::ObjectType, ObpEnumFindHandleProcedure(), ObpInitKillMutant, and TRUE.

Referenced by xxxUserFindHandleForObject().

01244 : 01245 01246 This routine searches the handle table for the specified process, 01247 looking for a handle table entry that matches the passed parameters. 01248 If an an Object pointer is specified it must match. If an 01249 ObjectType is specified it must match. If HandleInformation is 01250 specified, then both the HandleAttributes and GrantedAccess mask 01251 must match. If all three match parameters are NULL, then will 01252 match the first allocated handle for the specified process that 01253 matches the specified object pointer. 01254 01255 Arguments: 01256 01257 Process - Specifies the process whose object table is to be searched. 01258 01259 Object - Specifies the object pointer to look for. 01260 01261 ObjectType - Specifies the object type to look for. 01262 01263 HandleInformation - Specifies additional match criteria to look for. 01264 01265 Handle - Specifies the location to receive the handle value whose handle 01266 entry matches the supplied object pointer and optional match criteria. 01267 01268 Return Value: 01269 01270 TRUE if a match was found and FALSE otherwise. 01271 01272 --*/ 01273 01274 { 01275 HANDLE_TABLE_ENTRY ObjectTableEntry; 01276 OBP_FIND_HANDLE_DATA EnumParameter; 01277 BOOLEAN Result; 01278 01279 Result = FALSE; 01280 01281 // 01282 // Lock the object object name space 01283 // 01284 01285 KeEnterCriticalRegion(); 01286 01287 KeWaitForSingleObject( &ObpInitKillMutant, 01288 Executive, 01289 KernelMode, 01290 FALSE, 01291 NULL ); 01292 01293 // 01294 // We only do the work if the process has an object table meaning 01295 // it isn't going away 01296 // 01297 01298 if (Process->ObjectTable != NULL) { 01299 01300 // 01301 // Set the match parameters that our caller supplied 01302 // 01303 01304 if (ARGUMENT_PRESENT( Object )) { 01305 01306 EnumParameter.ObjectHeader = OBJECT_TO_OBJECT_HEADER( Object ); 01307 01308 } else { 01309 01310 EnumParameter.ObjectHeader = NULL; 01311 } 01312 01313 EnumParameter.ObjectType = ObjectType; 01314 EnumParameter.HandleInformation = HandleInformation; 01315 01316 // 01317 // Call the routine the enumerate the object table, this will 01318 // return true if we get match. The enumeration routine really 01319 // returns a index into the object table entries we need to 01320 // translate it to a real handle before returning. 01321 // 01322 01323 if (ExEnumHandleTable( Process->ObjectTable, 01324 ObpEnumFindHandleProcedure, 01325 &EnumParameter, 01326 Handle )) { 01327 01328 Result = TRUE; 01329 } 01330 } 01331 01332 // 01333 // Unlock the object name space and return to our caller 01334 // 01335 01336 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 01337 01338 KeLeaveCriticalRegion(); 01339 01340 return Result; 01341 }

NTSTATUS ObInitProcess PEPROCESS ParentProcess  OPTIONAL,
PEPROCESS  NewProcess
 

Definition at line 815 of file obinit.c.

References ExCreateHandleTable(), ExDupHandleTable(), Executive, ExEnumHandleTable(), FALSE, KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseMutant(), KernelMode, KeWaitForSingleObject(), MaxPoolType, NULL, ObAuditInheritedHandleProcedure(), ObDupHandleProcedure(), _EPROCESS::ObjectTable, ObpInitKillMutant, _SE_PROCESS_AUDIT_INFO::Parent, _SE_PROCESS_AUDIT_INFO::Process, SE_PROCESS_AUDIT_INFO, and SeDetailedAuditing.

Referenced by PspCreateProcess().

00822 : 00823 00824 This function initializes a process object table. If the ParentProcess 00825 is specified, then all object handles with the OBJ_INHERIT attribute are 00826 copied from the parent object table to the new process' object table. 00827 The HandleCount field of each object copied is incremented by one. Both 00828 object table mutexes remained locked for the duration of the copy 00829 operation. 00830 00831 Arguments: 00832 00833 ParentProcess - optional pointer to a process object that is the 00834 parent process to inherit object handles from. 00835 00836 NewProcess - pointer to the process object being initialized. 00837 00838 Return Value: 00839 00840 Status code. 00841 00842 The following errors can occur: 00843 00844 - insufficient memory 00845 00846 --*/ 00847 00848 { 00849 PHANDLE_TABLE OldObjectTable; 00850 PHANDLE_TABLE NewObjectTable; 00851 ULONG PoolCharges[ MaxPoolType ]; 00852 SE_PROCESS_AUDIT_INFO ProcessAuditInfo; 00853 00854 RtlZeroMemory( PoolCharges, sizeof( PoolCharges ) ); 00855 00856 // 00857 // If we have a parent process then we need to lock it down 00858 // check that it is not going away and then make a copy 00859 // of its handle table. If there isn't a parent then 00860 // we'll start with an empty handle table. 00861 // 00862 00863 if (ARGUMENT_PRESENT( ParentProcess )) { 00864 00865 KeEnterCriticalRegion(); 00866 KeWaitForSingleObject( &ObpInitKillMutant, 00867 Executive, 00868 KernelMode, 00869 FALSE, 00870 NULL ); 00871 00872 OldObjectTable = ParentProcess->ObjectTable; 00873 00874 if ( !OldObjectTable ) { 00875 00876 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 00877 KeLeaveCriticalRegion(); 00878 00879 return STATUS_PROCESS_IS_TERMINATING; 00880 } 00881 00882 NewObjectTable = ExDupHandleTable( NewProcess, 00883 OldObjectTable, 00884 ObDupHandleProcedure ); 00885 00886 } else { 00887 00888 OldObjectTable = NULL; 00889 NewObjectTable = ExCreateHandleTable( NewProcess ); 00890 } 00891 00892 // 00893 // Check that we really have a new handle table otherwise 00894 // we must be out of resources 00895 // 00896 00897 if (NewObjectTable) { 00898 00899 // 00900 // Set the new processes object table and if we are 00901 // auditing then enumerate the new table calling 00902 // the audit procedure 00903 // 00904 00905 NewProcess->ObjectTable = NewObjectTable; 00906 00907 if ( SeDetailedAuditing ) { 00908 00909 ProcessAuditInfo.Process = NewProcess; 00910 ProcessAuditInfo.Parent = ParentProcess; 00911 00912 ExEnumHandleTable( NewObjectTable, 00913 ObAuditInheritedHandleProcedure, 00914 (PVOID)&ProcessAuditInfo, 00915 (PHANDLE)NULL ); 00916 } 00917 00918 // 00919 // Free the old table if it exists and then 00920 // return our caller 00921 // 00922 00923 if ( OldObjectTable ) { 00924 00925 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 00926 KeLeaveCriticalRegion(); 00927 } 00928 00929 return( STATUS_SUCCESS ); 00930 00931 } else { 00932 00933 // 00934 // We're out of resources to null out the new object table field, 00935 // unlock the old object table, and tell our caller that this 00936 // didn't work 00937 // 00938 00939 NewProcess->ObjectTable = NULL; 00940 00941 if ( OldObjectTable ) { 00942 00943 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 00944 KeLeaveCriticalRegion(); 00945 } 00946 00947 return( STATUS_INSUFFICIENT_RESOURCES ); 00948 } 00949 }

VOID ObInitProcess2 PEPROCESS  NewProcess  ) 
 

Definition at line 953 of file obinit.c.

References ExSetHandleTableOrder, _EPROCESS::ObjectTable, and _EPROCESS::SubSystemVersion.

Referenced by PspCreateProcess().

00959 : 00960 00961 This function is called after an image file has been mapped into the address 00962 space of a newly created process. Allows the object manager to set LIFO/FIFO 00963 ordering for handle allocation based on the SubSystemVersion number in the 00964 image. 00965 00966 Arguments: 00967 00968 NewProcess - pointer to the process object being initialized. 00969 00970 Return Value: 00971 00972 None. 00973 00974 --*/ 00975 00976 { 00977 // 00978 // Set LIFO ordering of handles for images <= SubSystemVersion 3.50 00979 // 00980 00981 if (NewProcess->ObjectTable) { 00982 00983 ExSetHandleTableOrder( NewProcess->ObjectTable, (BOOLEAN)(NewProcess->SubSystemVersion <= 0x332) ); 00984 } 00985 00986 return; 00987 }

BOOLEAN ObInitSystem VOID   ) 
 

Definition at line 117 of file obinit.c.

References ASSERT, _OBJECT_HEADER::Body, _OBJECT_HEADER_NAME_INFO::Directory, ExAllocatePoolWithTag, ExCreateHandleTable(), ExInitializeNPagedLookasideList(), ExInitializeResourceLite(), FALSE, Index, InitializationPhase, KeGetCurrentPrcb, KeInitializeEvent, KeInitializeMutant(), KeInitializeSpinLock(), KeNumberProcessors, KernelMode, KiProcessorBlock, L, _NPAGED_LOOKASIDE_LIST::L, LookasideCreateInfoList, LookasideNameBufferList, MM_SYSTEMSIZE, MmIsThisAnNtAsSystem(), MmLargeSystem, MmQuerySystemSize(), _OBJECT_HEADER_NAME_INFO::Name, NonPagedPool, NPAGED_LOOKASIDE_LIST, NT_SUCCESS, NtClose(), NtCreateDirectoryObject(), NTSTATUS(), NULL, ObCreateObjectType(), OBJECT_HEADER_TO_NAME_INFO, OBJECT_NAME_BUFFER_SIZE, ObjectAttributes, ObpAuditBaseDirectories, ObpAuditBaseObjects, ObpCreateDosDevicesDirectory(), ObpCreateInfoLookasideList, ObpDefaultObject, ObpDeleteSymbolicLink(), ObpDeviceMapLock, ObpDirectoryMapping, ObpDirectoryObjectType, ObpEnterRootDirectoryMutex, ObpInitKillMutant, ObpInitSecurityDescriptorCache(), ObpInsertDirectoryEntry(), ObpKernelHandleTable, ObpLeaveRootDirectoryMutex, ObpLock, ObpLookupDirectoryEntry(), ObpNameBufferLookasideList, ObpParseSymbolicLink(), ObpRemoveObjectQueue, ObpRootDirectoryMutex, ObpRootDirectoryObject, ObpSymbolicLinkMapping, ObpSymbolicLinkObjectType, ObpTypeDirectoryObject, ObpTypeMapping, ObpTypeObjectType, ObReferenceObjectByHandle(), PAGE_SIZE, PagedPool, _EPROCESS_QUOTA_BLOCK::PagefileLimit, PsGetCurrentProcess, PsGetCurrentThread, PspDefaultQuotaBlock, _EPROCESS_QUOTA_BLOCK::QuotaLock, _EPROCESS_QUOTA_BLOCK::QuotaPoolLimit, _EPROCESS_QUOTA_BLOCK::ReferenceCount, RtlAddAuditAccessAce(), RtlCreateAcl(), RtlCreateSecurityDescriptor(), RtlGetAce(), RtlInitUnicodeString(), RtlSetDaclSecurityDescriptor(), RtlSetSaclSecurityDescriptor(), SeLengthSid, SePublicDefaultUnrestrictedDacl, SePublicDefaultUnrestrictedSd, SeWorldSid, Status, TRUE, _OBJECT_TYPE::TypeList, and USHORT.

00123 : 00124 00125 This function performs the system initialization for the object 00126 manager. The object manager data structures are self describing 00127 with the exception of the root directory, the type object type and 00128 the directory object type. The initialization code then constructs 00129 these objects by hand to get the ball rolling. 00130 00131 Arguments: 00132 00133 None. 00134 00135 Return Value: 00136 00137 TRUE if successful and FALSE if an error occurred. 00138 00139 The following errors can occur: 00140 00141 - insufficient memory 00142 00143 --*/ 00144 00145 { 00146 USHORT CreateInfoMaxDepth; 00147 USHORT NameBufferMaxDepth; 00148 ULONG RegionSegmentSize; 00149 OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; 00150 UNICODE_STRING TypeTypeName; 00151 UNICODE_STRING SymbolicLinkTypeName; 00152 UNICODE_STRING DosDevicesDirectoryName; 00153 UNICODE_STRING DirectoryTypeName; 00154 UNICODE_STRING RootDirectoryName; 00155 UNICODE_STRING TypeDirectoryName; 00156 NTSTATUS Status; 00157 OBJECT_ATTRIBUTES ObjectAttributes; 00158 HANDLE RootDirectoryHandle; 00159 HANDLE TypeDirectoryHandle; 00160 PLIST_ENTRY Next, Head; 00161 POBJECT_HEADER ObjectTypeHeader; 00162 POBJECT_HEADER_CREATOR_INFO CreatorInfo; 00163 POBJECT_HEADER_NAME_INFO NameInfo; 00164 MM_SYSTEMSIZE SystemSize; 00165 SECURITY_DESCRIPTOR AuditSd; 00166 PSECURITY_DESCRIPTOR EffectiveSd; 00167 PACL AuditAllAcl; 00168 UCHAR AuditAllBuffer[250]; // Ample room for the ACL 00169 ULONG AuditAllLength; 00170 PACE_HEADER Ace; 00171 PNPAGED_LOOKASIDE_LIST Lookaside; 00172 ULONG Index; 00173 PKPRCB Prcb; 00174 00175 // 00176 // Determine the the size of the object creation and the name buffer 00177 // lookaside lists. 00178 // 00179 00180 SystemSize = MmQuerySystemSize(); 00181 00182 if (SystemSize == MmLargeSystem) { 00183 00184 if (MmIsThisAnNtAsSystem()) { 00185 00186 CreateInfoMaxDepth = 64; 00187 NameBufferMaxDepth = 32; 00188 00189 } else { 00190 00191 CreateInfoMaxDepth = 32; 00192 NameBufferMaxDepth = 16; 00193 } 00194 00195 } else { 00196 00197 CreateInfoMaxDepth = 3; 00198 NameBufferMaxDepth = 3; 00199 } 00200 00201 // 00202 // PHASE 0 Initialization 00203 // 00204 00205 if (InitializationPhase == 0) { 00206 00207 // 00208 // Initialize the object creation lookaside list. 00209 // 00210 00211 ExInitializeNPagedLookasideList( &ObpCreateInfoLookasideList, 00212 NULL, 00213 NULL, 00214 0, 00215 sizeof(OBJECT_CREATE_INFORMATION), 00216 'iCbO', 00217 CreateInfoMaxDepth ); 00218 00219 // 00220 // Initialize the name buffer lookaside list. 00221 // 00222 00223 ExInitializeNPagedLookasideList( &ObpNameBufferLookasideList, 00224 NULL, 00225 NULL, 00226 0, 00227 OBJECT_NAME_BUFFER_SIZE, 00228 'mNbO', 00229 NameBufferMaxDepth ); 00230 00231 // 00232 // Initialize the system create info and name buffer lookaside lists 00233 // for the current processor. 00234 // 00235 // N.B. Temporarily during the initialization of the system both 00236 // lookaside list pointers in the processor block point to 00237 // the same lookaside list structure. Later in initialization 00238 // another lookaside list structure is allocated and filled 00239 // for the per processor list. 00240 // 00241 00242 Prcb = KeGetCurrentPrcb(); 00243 Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList; 00244 Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList; 00245 Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList; 00246 Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList; 00247 00248 // 00249 // Initialize the object removal queue listhead. 00250 // 00251 00252 ObpRemoveObjectQueue = NULL; 00253 00254 // 00255 // Initialize security descriptor cache 00256 // 00257 00258 ObpInitSecurityDescriptorCache(); 00259 00260 KeInitializeMutant( &ObpInitKillMutant, FALSE ); 00261 KeInitializeEvent( &ObpDefaultObject, NotificationEvent, TRUE ); 00262 KeInitializeSpinLock( &ObpLock ); 00263 PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS; 00264 PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS; 00265 00266 KeInitializeSpinLock( &ObpDeviceMapLock ); 00267 00268 // 00269 // Initialize the quota block and have the eprocess structure 00270 // point to it. 00271 // 00272 00273 KeInitializeSpinLock(&PspDefaultQuotaBlock.QuotaLock); 00274 PspDefaultQuotaBlock.ReferenceCount = 1; 00275 PspDefaultQuotaBlock.QuotaPoolLimit[PagedPool] = (ULONG)-1; 00276 PspDefaultQuotaBlock.QuotaPoolLimit[NonPagedPool] = (ULONG)-1; 00277 PspDefaultQuotaBlock.PagefileLimit = (ULONG)-1; 00278 00279 PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock; 00280 00281 // 00282 // Initialize the handle table for the system process and also the global 00283 // kernel handle table 00284 // 00285 00286 PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable( NULL ); 00287 ObpKernelHandleTable = ExCreateHandleTable( NULL ); 00288 00289 // 00290 // Create an object type for the "Type" object. This is the start of 00291 // of the object types and goes in the ObpTypeDirectoryObject. 00292 // 00293 00294 RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); 00295 ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); 00296 ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 00297 ObjectTypeInitializer.PoolType = NonPagedPool; 00298 00299 RtlInitUnicodeString( &TypeTypeName, L"Type" ); 00300 ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS; 00301 ObjectTypeInitializer.GenericMapping = ObpTypeMapping; 00302 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_TYPE ); 00303 ObjectTypeInitializer.MaintainTypeList = TRUE; 00304 ObjectTypeInitializer.UseDefaultObject = TRUE; 00305 ObCreateObjectType( &TypeTypeName, 00306 &ObjectTypeInitializer, 00307 (PSECURITY_DESCRIPTOR)NULL, 00308 &ObpTypeObjectType ); 00309 00310 // 00311 // Create the object type for the "Directory" object. 00312 // 00313 00314 RtlInitUnicodeString( &DirectoryTypeName, L"Directory" ); 00315 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_DIRECTORY ); 00316 ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS; 00317 ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping; 00318 ObjectTypeInitializer.UseDefaultObject = FALSE; 00319 ObjectTypeInitializer.MaintainTypeList = FALSE; 00320 ObCreateObjectType( &DirectoryTypeName, 00321 &ObjectTypeInitializer, 00322 (PSECURITY_DESCRIPTOR)NULL, 00323 &ObpDirectoryObjectType ); 00324 00325 // 00326 // Create the object type for the "SymbolicLink" object. 00327 // 00328 00329 RtlInitUnicodeString( &SymbolicLinkTypeName, L"SymbolicLink" ); 00330 ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_SYMBOLIC_LINK ); 00331 ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; 00332 ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; 00333 ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; 00334 ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink; 00335 ObCreateObjectType( &SymbolicLinkTypeName, 00336 &ObjectTypeInitializer, 00337 (PSECURITY_DESCRIPTOR)NULL, 00338 &ObpSymbolicLinkObjectType ); 00339 00340 // 00341 // Initialize the resource that protects the object name space directory structure 00342 // 00343 00344 ExInitializeResourceLite( &ObpRootDirectoryMutex ); 00345 00346 #if i386 && !FPO 00347 00348 // 00349 // Initialize the cached granted access structure. These variables are used 00350 // in place of the access mask in the object table entry. 00351 // 00352 00353 ObpCurCachedGrantedAccessIndex = 0; 00354 ObpMaxCachedGrantedAccessIndex = PAGE_SIZE / sizeof( ACCESS_MASK ); 00355 ObpCachedGrantedAccesses = ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, 'gAbO' ); 00356 00357 #endif // i386 && !FPO 00358 00359 } // End of Phase 0 Initialization 00360 00361 00362 // 00363 // PHASE 1 Initialization 00364 // 00365 00366 if (InitializationPhase == 1) { 00367 00368 // 00369 // Initialize the per processor nonpaged lookaside lists and descriptors. 00370 // 00371 00372 for (Index = 0; Index < (ULONG)KeNumberProcessors; Index += 1) { 00373 Prcb = KiProcessorBlock[Index]; 00374 00375 // 00376 // Initialize the create information per processor lookaside pointers. 00377 // 00378 00379 Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList; 00380 Lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00381 sizeof(NPAGED_LOOKASIDE_LIST), 00382 'ICbO'); 00383 00384 if (Lookaside != NULL) { 00385 ExInitializeNPagedLookasideList( Lookaside, 00386 NULL, 00387 NULL, 00388 0, 00389 sizeof(OBJECT_CREATE_INFORMATION), 00390 'ICbO', 00391 CreateInfoMaxDepth ); 00392 00393 } else { 00394 Lookaside = &ObpCreateInfoLookasideList; 00395 } 00396 00397 Prcb->PPLookasideList[LookasideCreateInfoList].P = Lookaside; 00398 00399 // 00400 // Initialize the name buffer per processor lookaside pointers. 00401 // 00402 00403 Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList; 00404 Lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00405 sizeof(NPAGED_LOOKASIDE_LIST), 00406 'MNbO'); 00407 00408 if (Lookaside != NULL) { 00409 ExInitializeNPagedLookasideList( Lookaside, 00410 NULL, 00411 NULL, 00412 0, 00413 OBJECT_NAME_BUFFER_SIZE, 00414 'MNbO', 00415 NameBufferMaxDepth); 00416 00417 } else { 00418 Lookaside = &ObpNameBufferLookasideList; 00419 } 00420 00421 Prcb->PPLookasideList[LookasideNameBufferList].P = Lookaside; 00422 } 00423 00424 EffectiveSd = SePublicDefaultUnrestrictedSd; 00425 00426 // 00427 // This code is only executed if base auditing is turned on. 00428 // 00429 00430 if ((ObpAuditBaseDirectories != 0) || (ObpAuditBaseObjects != 0)) { 00431 00432 // 00433 // build an SACL to audit 00434 // 00435 00436 AuditAllAcl = (PACL)AuditAllBuffer; 00437 AuditAllLength = (ULONG)sizeof(ACL) + 00438 ((ULONG)sizeof(SYSTEM_AUDIT_ACE)) + 00439 SeLengthSid(SeWorldSid); 00440 00441 ASSERT( sizeof(AuditAllBuffer) > AuditAllLength ); 00442 00443 Status = RtlCreateAcl( AuditAllAcl, AuditAllLength, ACL_REVISION2); 00444 00445 ASSERT( NT_SUCCESS(Status) ); 00446 00447 Status = RtlAddAuditAccessAce ( AuditAllAcl, 00448 ACL_REVISION2, 00449 GENERIC_ALL, 00450 SeWorldSid, 00451 TRUE, TRUE ); //Audit success and failure 00452 ASSERT( NT_SUCCESS(Status) ); 00453 00454 Status = RtlGetAce( AuditAllAcl, 0, (PVOID)&Ace ); 00455 00456 ASSERT( NT_SUCCESS(Status) ); 00457 00458 if (ObpAuditBaseDirectories != 0) { 00459 00460 Ace->AceFlags |= (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); 00461 } 00462 00463 if (ObpAuditBaseObjects != 0) { 00464 00465 Ace->AceFlags |= (OBJECT_INHERIT_ACE | 00466 CONTAINER_INHERIT_ACE | 00467 INHERIT_ONLY_ACE); 00468 } 00469 00470 // 00471 // Now create a security descriptor that looks just like 00472 // the public default, but has auditing in it as well. 00473 // 00474 00475 EffectiveSd = (PSECURITY_DESCRIPTOR)&AuditSd; 00476 Status = RtlCreateSecurityDescriptor( EffectiveSd, 00477 SECURITY_DESCRIPTOR_REVISION1 ); 00478 00479 ASSERT( NT_SUCCESS(Status) ); 00480 00481 Status = RtlSetDaclSecurityDescriptor( EffectiveSd, 00482 TRUE, // DaclPresent 00483 SePublicDefaultUnrestrictedDacl, 00484 FALSE ); // DaclDefaulted 00485 00486 ASSERT( NT_SUCCESS(Status) ); 00487 00488 Status = RtlSetSaclSecurityDescriptor( EffectiveSd, 00489 TRUE, // DaclPresent 00490 AuditAllAcl, 00491 FALSE ); // DaclDefaulted 00492 00493 ASSERT( NT_SUCCESS(Status) ); 00494 } 00495 00496 // 00497 // We only need to use the EffectiveSd on the root. The SACL 00498 // will be inherited by all other objects. 00499 // 00500 00501 // 00502 // Create an directory object for the root directory 00503 // 00504 00505 RtlInitUnicodeString( &RootDirectoryName, L"\\" ); 00506 00507 InitializeObjectAttributes( &ObjectAttributes, 00508 &RootDirectoryName, 00509 OBJ_CASE_INSENSITIVE | 00510 OBJ_PERMANENT, 00511 NULL, 00512 EffectiveSd ); 00513 00514 Status = NtCreateDirectoryObject( &RootDirectoryHandle, 00515 DIRECTORY_ALL_ACCESS, 00516 &ObjectAttributes ); 00517 00518 if (!NT_SUCCESS( Status )) { 00519 00520 return( FALSE ); 00521 } 00522 00523 Status = ObReferenceObjectByHandle( RootDirectoryHandle, 00524 0, 00525 ObpDirectoryObjectType, 00526 KernelMode, 00527 (PVOID *)&ObpRootDirectoryObject, 00528 NULL ); 00529 00530 if (!NT_SUCCESS( Status )) { 00531 00532 return( FALSE ); 00533 } 00534 00535 Status = NtClose( RootDirectoryHandle ); 00536 00537 if (!NT_SUCCESS( Status )) { 00538 00539 return( FALSE ); 00540 } 00541 00542 // 00543 // Create an directory object for the directory of object types 00544 // 00545 00546 RtlInitUnicodeString( &TypeDirectoryName, L"\\ObjectTypes" ); 00547 00548 InitializeObjectAttributes( &ObjectAttributes, 00549 &TypeDirectoryName, 00550 OBJ_CASE_INSENSITIVE | 00551 OBJ_PERMANENT, 00552 NULL, 00553 NULL ); 00554 00555 Status = NtCreateDirectoryObject( &TypeDirectoryHandle, 00556 DIRECTORY_ALL_ACCESS, 00557 &ObjectAttributes ); 00558 00559 if (!NT_SUCCESS( Status )) { 00560 00561 return( FALSE ); 00562 } 00563 00564 Status = ObReferenceObjectByHandle( TypeDirectoryHandle, 00565 0, 00566 ObpDirectoryObjectType, 00567 KernelMode, 00568 (PVOID *)&ObpTypeDirectoryObject, 00569 NULL ); 00570 00571 if (!NT_SUCCESS( Status )) { 00572 00573 return( FALSE ); 00574 } 00575 00576 Status = NtClose( TypeDirectoryHandle ); 00577 00578 if (!NT_SUCCESS( Status )) { 00579 00580 return( FALSE ); 00581 } 00582 00583 // 00584 // Lock the object directory name space 00585 // 00586 00587 ObpEnterRootDirectoryMutex(); 00588 00589 // 00590 // For every object type that has already been created we will 00591 // insert it in the type directory. We do this looking down the 00592 // linked list of type objects and for every one that has a name 00593 // and isn't already in a directory we'll look the name up and 00594 // then put it in the directory. Be sure to skip the first 00595 // entry in the type object types lists. 00596 // 00597 00598 Head = &ObpTypeObjectType->TypeList; 00599 Next = Head->Flink; 00600 00601 while (Next != Head) { 00602 00603 // 00604 // Right after the creator info is the object header. Get\ 00605 // the object header and then see if there is a name 00606 // 00607 00608 CreatorInfo = CONTAINING_RECORD( Next, 00609 OBJECT_HEADER_CREATOR_INFO, 00610 TypeList ); 00611 00612 ObjectTypeHeader = (POBJECT_HEADER)(CreatorInfo+1); 00613 00614 NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectTypeHeader ); 00615 00616 // 00617 // Check if we have a name and we're not in a directory 00618 // 00619 00620 00621 if ((NameInfo != NULL) && (NameInfo->Directory == NULL)) { 00622 00623 if (!ObpLookupDirectoryEntry( ObpTypeDirectoryObject, 00624 &NameInfo->Name, 00625 OBJ_CASE_INSENSITIVE )) { 00626 00627 ObpInsertDirectoryEntry( ObpTypeDirectoryObject, 00628 &ObjectTypeHeader->Body ); 00629 } 00630 } 00631 00632 Next = Next->Flink; 00633 } 00634 00635 // 00636 // Unlock the object directory name space 00637 // 00638 00639 ObpLeaveRootDirectoryMutex(); 00640 00641 // 00642 // Create \DosDevices object directory for drive letters and Win32 device names 00643 // 00644 00645 Status = ObpCreateDosDevicesDirectory(); 00646 00647 if (!NT_SUCCESS( Status )) { 00648 00649 return FALSE; 00650 } 00651 } 00652 00653 return TRUE; 00654 }

VOID ObKillProcess BOOLEAN  AcquireLock,
PEPROCESS  Process
 

Definition at line 1022 of file obinit.c.

References ExDestroyHandleTable(), Executive, FALSE, IoSetThreadHardErrorMode(), KeEnterCriticalRegion, KeLeaveCriticalRegion, KeReleaseMutant(), KernelMode, KeWaitForSingleObject(), NULL, ObDestroyHandleProcedure(), _EPROCESS::ObjectTable, ObpInitKillMutant, ObpValidateIrql, and PAGED_CODE.

Referenced by PspCreateProcess(), PspExitProcess(), and PspExitThread().

01028 : 01029 01030 This function is called whenever a process is destroyed. It loops over 01031 the process' object table and closes all the handles. 01032 01033 Arguments: 01034 01035 AcquireLock - TRUE if there are other pointers to this process and therefore 01036 this operation needs to be synchronized. False if this is being called 01037 from the Process delete routine and therefore this is the only pointer 01038 to the process. 01039 01040 Process - Pointer to the process that is being destroyed. 01041 01042 Return Value: 01043 01044 None. 01045 01046 --*/ 01047 01048 { 01049 PVOID ObjectTable; 01050 BOOLEAN PreviousIOHardError; 01051 01052 PAGED_CODE(); 01053 01054 ObpValidateIrql( "ObKillProcess" ); 01055 01056 // 01057 // Check if we need to get the lock 01058 // 01059 01060 if (AcquireLock) { 01061 01062 KeEnterCriticalRegion(); 01063 01064 KeWaitForSingleObject( &ObpInitKillMutant, 01065 Executive, 01066 KernelMode, 01067 FALSE, 01068 NULL ); 01069 } 01070 01071 // 01072 // If the process does NOT have an object table, return 01073 // 01074 01075 ObjectTable = Process->ObjectTable; 01076 01077 if (ObjectTable != NULL) { 01078 01079 PreviousIOHardError = IoSetThreadHardErrorMode(FALSE); 01080 01081 // 01082 // For each valid entry in the object table, close the handle 01083 // that points to that entry. 01084 // 01085 01086 ExDestroyHandleTable( ObjectTable, ObDestroyHandleProcedure ); 01087 01088 Process->ObjectTable = NULL; 01089 01090 IoSetThreadHardErrorMode( PreviousIOHardError ); 01091 } 01092 01093 // 01094 // Release the lock 01095 // 01096 01097 if (AcquireLock) { 01098 01099 KeReleaseMutant( &ObpInitKillMutant, 0, FALSE, FALSE ); 01100 01101 KeLeaveCriticalRegion(); 01102 } 01103 01104 // 01105 // And return to our caller 01106 // 01107 01108 return; 01109 }

NTSTATUS ObpCreateDosDevicesDirectory VOID   ) 
 

Definition at line 1349 of file obinit.c.

References DirectoryHandle, L, NT_SUCCESS, NtClose(), NtCreateDirectoryObject(), NtCreateSymbolicLinkObject(), NTSTATUS(), NULL, ObjectAttributes, ObpDosDevicesShortName, ObpDosDevicesShortNamePrefix, ObpDosDevicesShortNameRoot, ObpFreeDosDevicesProtection(), ObpGetDosDevicesProtection(), ObSetDeviceMap(), RtlCopyUnicodeString(), RtlCreateUnicodeString(), RtlInitUnicodeString(), and Status.

Referenced by ObInitSystem().

01355 : 01356 01357 This routine creates the directory object for the dos devices and sets 01358 the device map for the system process. 01359 01360 Arguments: 01361 01362 None. 01363 01364 Return Value: 01365 01366 STATUS_SUCCESS or an appropriate error 01367 01368 --*/ 01369 01370 { 01371 NTSTATUS Status; 01372 UNICODE_STRING NameString; 01373 UNICODE_STRING LinkNameString; 01374 UNICODE_STRING TargetString; 01375 OBJECT_ATTRIBUTES ObjectAttributes; 01376 HANDLE DirectoryHandle; 01377 HANDLE SymbolicLinkHandle; 01378 SECURITY_DESCRIPTOR DosDevicesSD; 01379 01380 // 01381 // Create the security descriptor to use for the \?? directory 01382 // 01383 01384 Status = ObpGetDosDevicesProtection( &DosDevicesSD ); 01385 01386 if (!NT_SUCCESS( Status )) { 01387 01388 return Status; 01389 } 01390 01391 // 01392 // Create the root directory object for the \?? directory. 01393 // 01394 01395 RtlInitUnicodeString( &NameString, L"\\??" ); 01396 01397 InitializeObjectAttributes( &ObjectAttributes, 01398 &NameString, 01399 OBJ_PERMANENT, 01400 (HANDLE) NULL, 01401 &DosDevicesSD ); 01402 01403 Status = NtCreateDirectoryObject( &DirectoryHandle, 01404 DIRECTORY_ALL_ACCESS, 01405 &ObjectAttributes ); 01406 01407 if (!NT_SUCCESS( Status )) { 01408 01409 return Status; 01410 } 01411 01412 // 01413 // Create a device map that will control this directory. It will be 01414 // stored in the each EPROCESS for use by ObpLookupObjectName when 01415 // translating names that begin with \??\ 01416 // 01417 01418 Status = ObSetDeviceMap( NULL, DirectoryHandle ); 01419 01420 01421 // 01422 // Now create a symbolic link, \??\GLOBALROOT, that points to \ 01423 // WorkStation service needs some mechanism to access a session specific 01424 // DosDevicesDirectory. DosPathToSessionPath API will take a DosPath 01425 // e.g (C:) and convert it into session specific path 01426 // (e.g GLOBALROOT\Sessions\6\DosDevices\C:). The GLOBALROOT symbolic 01427 // link is used to escape out of the current process's DosDevices directory 01428 // 01429 01430 RtlInitUnicodeString( &LinkNameString, L"GLOBALROOT" ); 01431 RtlInitUnicodeString( &TargetString, L"" ); 01432 01433 InitializeObjectAttributes( &ObjectAttributes, 01434 &LinkNameString, 01435 OBJ_PERMANENT, 01436 DirectoryHandle, 01437 &DosDevicesSD ); 01438 01439 Status = NtCreateSymbolicLinkObject( &SymbolicLinkHandle, 01440 SYMBOLIC_LINK_ALL_ACCESS, 01441 &ObjectAttributes, 01442 &TargetString ); 01443 01444 if (NT_SUCCESS( Status )) { 01445 01446 NtClose( SymbolicLinkHandle ); 01447 } 01448 01449 // 01450 // Create a symbolic link, \??\Global, that points to \?? 01451 // Drivers loaded dynamically create the symbolic link in the global 01452 // DosDevices directory. User mode components need some way to access this 01453 // symbolic link in the global dosdevices directory. The Global symbolic 01454 // link is used to escape out of the current sessions's DosDevices directory 01455 // and use the global dosdevices directory. e.g CreateFile("\\\\.\\Global\\NMDev"..); 01456 // 01457 01458 RtlInitUnicodeString( &LinkNameString, L"Global" ); 01459 RtlInitUnicodeString( &TargetString, L"\\??" ); 01460 01461 InitializeObjectAttributes( &ObjectAttributes, 01462 &LinkNameString, 01463 OBJ_PERMANENT, 01464 DirectoryHandle, 01465 &DosDevicesSD ); 01466 01467 Status = NtCreateSymbolicLinkObject( &SymbolicLinkHandle, 01468 SYMBOLIC_LINK_ALL_ACCESS, 01469 &ObjectAttributes, 01470 &TargetString ); 01471 01472 if (NT_SUCCESS( Status )) { 01473 01474 NtClose( SymbolicLinkHandle ); 01475 } 01476 01477 01478 NtClose( DirectoryHandle ); 01479 01480 if (!NT_SUCCESS( Status )) { 01481 01482 return Status; 01483 } 01484 01485 // 01486 // Now copy the \?? string to a ULONGLONG aligned global variable 01487 // for use by ObpLookupObjectName for quick comparisons. 01488 // 01489 01490 ObpDosDevicesShortName.Buffer = (PWSTR)&ObpDosDevicesShortNamePrefix.QuadPart; 01491 ObpDosDevicesShortName.Length = 0; 01492 ObpDosDevicesShortName.MaximumLength = sizeof( ObpDosDevicesShortNamePrefix ); 01493 01494 RtlCopyUnicodeString( &ObpDosDevicesShortName, &NameString ); 01495 01496 ObpDosDevicesShortName.Buffer[ 3 ] = UNICODE_NULL; 01497 ObpDosDevicesShortNameRoot.QuadPart = ObpDosDevicesShortNamePrefix.QuadPart; 01498 01499 // 01500 // Now create a symbolic link, \DosDevices, that points to \?? 01501 // for backwards compatibility with old drivers that use the old 01502 // name. 01503 // 01504 01505 RtlCreateUnicodeString( &NameString, L"\\DosDevices" ); 01506 01507 InitializeObjectAttributes( &ObjectAttributes, 01508 &NameString, 01509 OBJ_PERMANENT, 01510 (HANDLE) NULL, 01511 &DosDevicesSD ); 01512 01513 Status = NtCreateSymbolicLinkObject( &SymbolicLinkHandle, 01514 SYMBOLIC_LINK_ALL_ACCESS, 01515 &ObjectAttributes, 01516 &ObpDosDevicesShortName ); 01517 01518 if (NT_SUCCESS( Status )) { 01519 01520 NtClose( SymbolicLinkHandle ); 01521 } 01522 01523 // 01524 // Finish setting up the global variable for ObpLookupObjectName 01525 // 01526 01527 ObpDosDevicesShortName.Buffer[ 3 ] = OBJ_NAME_PATH_SEPARATOR; 01528 ObpDosDevicesShortName.Length += sizeof( OBJ_NAME_PATH_SEPARATOR ); 01529 01530 // 01531 // All done with the security descriptor for \?? 01532 // 01533 01534 ObpFreeDosDevicesProtection( &DosDevicesSD ); 01535 01536 return STATUS_SUCCESS; 01537 }

BOOLEAN ObpEnumFindHandleProcedure PHANDLE_TABLE_ENTRY  ObjectTableEntry,
HANDLE  HandleId,
PVOID  EnumParameter
 

Definition at line 1127 of file obinit.c.

References FALSE, _OBJECT_HANDLE_INFORMATION::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccess, _HANDLE_TABLE_ENTRY::GrantedAccessIndex, _OBJECT_HANDLE_INFORMATION::HandleAttributes, _OBP_FIND_HANDLE_DATA::HandleInformation, NtGlobalFlag, NULL, OBJ_HANDLE_ATTRIBUTES, _HANDLE_TABLE_ENTRY::Object, _OBP_FIND_HANDLE_DATA::ObjectHeader, _OBP_FIND_HANDLE_DATA::ObjectType, POBP_FIND_HANDLE_DATA, TRUE, and _OBJECT_HEADER::Type.

Referenced by ObFindHandleForObject().

01135 : 01136 01137 Call back routine when enumerating an object table to find a handle 01138 for a particular object 01139 01140 Arguments: 01141 01142 HandleTableEntry - Supplies a pointer to the handle table entry 01143 being examined. 01144 01145 HandleId - Supplies the actual handle value for the preceding entry 01146 01147 EnumParameter - Supplies context for the matching. 01148 01149 Return Value: 01150 01151 Returns TRUE if a match is found and the enumeration should stop. Returns FALSE 01152 otherwise, so the enumeration will continue. 01153 01154 --*/ 01155 01156 { 01157 POBJECT_HEADER ObjectHeader; 01158 ACCESS_MASK GrantedAccess; 01159 ULONG HandleAttributes; 01160 POBP_FIND_HANDLE_DATA MatchCriteria = EnumParameter; 01161 01162 // 01163 // Get the object header from the table entry and see if 01164 // object types and headers match if specified. 01165 // 01166 01167 ObjectHeader = (POBJECT_HEADER)((ULONG_PTR)ObjectTableEntry->Object & ~OBJ_HANDLE_ATTRIBUTES); 01168 01169 if ((MatchCriteria->ObjectHeader != NULL) && 01170 (MatchCriteria->ObjectHeader != ObjectHeader)) { 01171 01172 return FALSE; 01173 } 01174 01175 if ((MatchCriteria->ObjectType != NULL) && 01176 (MatchCriteria->ObjectType != ObjectHeader->Type)) { 01177 01178 return FALSE; 01179 } 01180 01181 // 01182 // Check if we have handle information that we need to compare 01183 // 01184 01185 if (ARGUMENT_PRESENT( MatchCriteria->HandleInformation )) { 01186 01187 // 01188 // If we are tracing the call stacks for cached security indices then we do got a 01189 // translation to do otherwise the table entry contains straight away the granted 01190 // access mask 01191 // 01192 01193 #if i386 && !FPO 01194 01195 if (NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) { 01196 01197 GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex ); 01198 01199 } else { 01200 01201 GrantedAccess = ObjectTableEntry->GrantedAccess; 01202 } 01203 #else 01204 01205 GrantedAccess = ObjectTableEntry->GrantedAccess; 01206 01207 #endif // i386 && !FPO 01208 01209 // 01210 // Get the handle attributes from table entry and see if the 01211 // fields match. If they do not match we will return false to 01212 // continue the search. 01213 // 01214 01215 HandleAttributes = (ULONG)((ULONG_PTR)ObjectTableEntry->Object & OBJ_HANDLE_ATTRIBUTES); 01216 01217 if (MatchCriteria->HandleInformation->HandleAttributes != HandleAttributes || 01218 MatchCriteria->HandleInformation->GrantedAccess != GrantedAccess ) { 01219 01220 return FALSE; 01221 } 01222 } 01223 01224 // 01225 // We found something that matches our criteria so return true to 01226 // our caller to stop the enumeration 01227 // 01228 01229 return TRUE; 01230 }

VOID ObpFreeDosDevicesProtection PSECURITY_DESCRIPTOR  SecurityDescriptor  ) 
 

Definition at line 1805 of file obinit.c.

References ASSERT, Dacl, ExFreePool(), NT_SUCCESS, NTSTATUS(), NULL, RtlGetDaclSecurityDescriptor(), and Status.

Referenced by ObpCreateDosDevicesDirectory().

01811 : 01812 01813 This routine frees memory allocated via ObpGetDosDevicesProtection(). 01814 01815 Arguments: 01816 01817 SecurityDescriptor - The address of a security descriptor initialized by 01818 ObpGetDosDevicesProtection(). 01819 01820 Return Value: 01821 01822 None. 01823 01824 --*/ 01825 01826 { 01827 NTSTATUS Status; 01828 PACL Dacl; 01829 BOOLEAN DaclPresent, Defaulted; 01830 01831 Status = RtlGetDaclSecurityDescriptor ( SecurityDescriptor, 01832 &DaclPresent, 01833 &Dacl, 01834 &Defaulted ); 01835 01836 ASSERT( NT_SUCCESS( Status ) ); 01837 ASSERT( DaclPresent ); 01838 ASSERT( Dacl != NULL ); 01839 01840 ExFreePool( (PVOID)Dacl ); 01841 01842 return; 01843 } }

NTSTATUS ObpGetDosDevicesProtection PSECURITY_DESCRIPTOR  SecurityDescriptor  ) 
 

DaclDefaulted

DaclDefaulted

Definition at line 1545 of file obinit.c.

References ASSERT, ExAllocatePool, FALSE, NT_SUCCESS, NTSTATUS(), NULL, ObpProtectionMode, PagedPool, RtlAddAccessAllowedAce(), RtlCreateAcl(), RtlCreateSecurityDescriptor(), RtlGetAce(), RtlLengthSid(), RtlSetDaclSecurityDescriptor(), SeAliasAdminsSid, SeCreatorOwnerSid, SeLocalSystemSid, SeWorldSid, Status, and TRUE.

Referenced by ObpCreateDosDevicesDirectory().

01551 : 01552 01553 This routine builds a security descriptor for use in creating 01554 the \DosDevices object directory. The protection of \DosDevices 01555 must establish inheritable protection which will dictate how 01556 dos devices created via the DefineDosDevice() and 01557 IoCreateUnprotectedSymbolicLink() apis can be managed. 01558 01559 The protection assigned is dependent upon an administrable registry 01560 key: 01561 01562 Key: \hkey_local_machine\System\CurrentControlSet\Control\Session Manager 01563 Value: [REG_DWORD] ProtectionMode 01564 01565 If this value is 0x1, then 01566 01567 Administrators may control all Dos devices, 01568 Anyone may create new Dos devices (such as net drives 01569 or additional printers), 01570 Anyone may use any Dos device, 01571 The creator of a Dos device may delete it. 01572 Note that this protects system-defined LPTs and COMs so that only 01573 administrators may redirect them. However, anyone may add 01574 additional printers and direct them to wherever they would 01575 like. 01576 01577 This is achieved with the following protection for the DosDevices 01578 Directory object: 01579 01580 Grant: World: Execute | Read (No Inherit) 01581 Grant: System: All Access (No Inherit) 01582 Grant: World: Execute (Inherit Only) 01583 Grant: Admins: All Access (Inherit Only) 01584 Grant: System: All Access (Inherit Only) 01585 Grant: Owner: All Access (Inherit Only) 01586 01587 If this value is 0x0, or not present, then 01588 01589 Administrators may control all Dos devices, 01590 Anyone may create new Dos devices (such as net drives 01591 or additional printers), 01592 Anyone may use any Dos device, 01593 Anyone may delete Dos devices created with either DefineDosDevice() 01594 or IoCreateUnprotectedSymbolicLink(). This is how network drives 01595 and LPTs are created (but not COMs). 01596 01597 This is achieved with the following protection for the DosDevices 01598 Directory object: 01599 01600 Grant: World: Execute | Read | Write (No Inherit) 01601 Grant: System: All Access (No Inherit) 01602 Grant: World: All Access (Inherit Only) 01603 01604 01605 Arguments: 01606 01607 SecurityDescriptor - The address of a security descriptor to be 01608 initialized and filled in. When this security descriptor is no 01609 longer needed, you should call ObpFreeDosDevicesProtection() to 01610 free the protection information. 01611 01612 01613 Return Value: 01614 01615 Returns one of the following status codes: 01616 01617 STATUS_SUCCESS - normal, successful completion. 01618 01619 STATUS_NO_MEMORY - not enough memory 01620 01621 01622 --*/ 01623 01624 { 01625 NTSTATUS Status; 01626 ULONG aceIndex, aclLength; 01627 PACL dacl; 01628 PACE_HEADER ace; 01629 ACCESS_MASK accessMask; 01630 01631 UCHAR inheritOnlyFlags = (OBJECT_INHERIT_ACE | 01632 CONTAINER_INHERIT_ACE | 01633 INHERIT_ONLY_ACE 01634 ); 01635 01636 // 01637 // NOTE: This routine expects the value of ObpProtectionMode to have been set 01638 // 01639 01640 Status = RtlCreateSecurityDescriptor( SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION ); 01641 01642 ASSERT( NT_SUCCESS( Status ) ); 01643 01644 if (ObpProtectionMode & 0x00000001) { 01645 01646 // 01647 // Dacl: 01648 // Grant: World: Execute | Read (No Inherit) 01649 // Grant: System: All Access (No Inherit) 01650 // Grant: World: Execute (Inherit Only) 01651 // Grant: Admins: All Access (Inherit Only) 01652 // Grant: System: All Access (Inherit Only) 01653 // Grant: Owner: All Access (Inherit Only) 01654 // 01655 01656 aclLength = sizeof( ACL ) + 01657 6 * sizeof( ACCESS_ALLOWED_ACE ) + 01658 (2*RtlLengthSid( SeWorldSid )) + 01659 (2*RtlLengthSid( SeLocalSystemSid )) + 01660 RtlLengthSid( SeAliasAdminsSid ) + 01661 RtlLengthSid( SeCreatorOwnerSid ); 01662 01663 dacl = (PACL)ExAllocatePool(PagedPool, aclLength ); 01664 01665 if (dacl == NULL) { 01666 01667 return STATUS_NO_MEMORY; 01668 } 01669 01670 Status = RtlCreateAcl( dacl, aclLength, ACL_REVISION2); 01671 ASSERT( NT_SUCCESS( Status ) ); 01672 01673 // 01674 // Non-inheritable ACEs first 01675 // World 01676 // System 01677 // 01678 01679 aceIndex = 0; 01680 accessMask = (GENERIC_READ | GENERIC_EXECUTE); 01681 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid ); 01682 ASSERT( NT_SUCCESS( Status ) ); 01683 aceIndex++; 01684 accessMask = (GENERIC_ALL); 01685 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid ); 01686 ASSERT( NT_SUCCESS( Status ) ); 01687 01688 // 01689 // Inheritable ACEs at the end of the ACL 01690 // World 01691 // Admins 01692 // System 01693 // Owner 01694 // 01695 01696 aceIndex++; 01697 accessMask = (GENERIC_EXECUTE); 01698 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid ); 01699 ASSERT( NT_SUCCESS( Status ) ); 01700 Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace ); 01701 ASSERT( NT_SUCCESS( Status ) ); 01702 ace->AceFlags |= inheritOnlyFlags; 01703 01704 aceIndex++; 01705 accessMask = (GENERIC_ALL); 01706 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeAliasAdminsSid ); 01707 ASSERT( NT_SUCCESS( Status ) ); 01708 Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace ); 01709 ASSERT( NT_SUCCESS( Status ) ); 01710 ace->AceFlags |= inheritOnlyFlags; 01711 01712 aceIndex++; 01713 accessMask = (GENERIC_ALL); 01714 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid ); 01715 ASSERT( NT_SUCCESS( Status ) ); 01716 Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace ); 01717 ASSERT( NT_SUCCESS( Status ) ); 01718 ace->AceFlags |= inheritOnlyFlags; 01719 01720 aceIndex++; 01721 accessMask = (GENERIC_ALL); 01722 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeCreatorOwnerSid ); 01723 ASSERT( NT_SUCCESS( Status ) ); 01724 Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace ); 01725 ASSERT( NT_SUCCESS( Status ) ); 01726 ace->AceFlags |= inheritOnlyFlags; 01727 01728 Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor, 01729 TRUE, //DaclPresent, 01730 dacl, //Dacl 01731 FALSE ); 01732 01733 ASSERT( NT_SUCCESS( Status ) ); 01734 01735 } else { 01736 01737 // 01738 // DACL: 01739 // Grant: World: Execute | Read | Write (No Inherit) 01740 // Grant: System: All Access (No Inherit) 01741 // Grant: World: All Access (Inherit Only) 01742 // 01743 01744 aclLength = sizeof( ACL ) + 01745 3 * sizeof( ACCESS_ALLOWED_ACE ) + 01746 (2*RtlLengthSid( SeWorldSid )) + 01747 RtlLengthSid( SeLocalSystemSid ); 01748 01749 dacl = (PACL)ExAllocatePool(PagedPool, aclLength ); 01750 01751 if (dacl == NULL) { 01752 01753 return STATUS_NO_MEMORY; 01754 } 01755 01756 Status = RtlCreateAcl( dacl, aclLength, ACL_REVISION2); 01757 ASSERT( NT_SUCCESS( Status ) ); 01758 01759 // 01760 // Non-inheritable ACEs first 01761 // World 01762 // System 01763 // 01764 01765 aceIndex = 0; 01766 accessMask = (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE); 01767 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid ); 01768 ASSERT( NT_SUCCESS( Status ) ); 01769 01770 aceIndex++; 01771 accessMask = (GENERIC_ALL); 01772 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeLocalSystemSid ); 01773 ASSERT( NT_SUCCESS( Status ) ); 01774 01775 // 01776 // Inheritable ACEs at the end of the ACL 01777 // World 01778 // 01779 01780 aceIndex++; 01781 accessMask = (GENERIC_ALL); 01782 Status = RtlAddAccessAllowedAce ( dacl, ACL_REVISION2, accessMask, SeWorldSid ); 01783 ASSERT( NT_SUCCESS( Status ) ); 01784 Status = RtlGetAce( dacl, aceIndex, (PVOID)&ace ); 01785 ASSERT( NT_SUCCESS( Status ) ); 01786 ace->AceFlags |= inheritOnlyFlags; 01787 01788 Status = RtlSetDaclSecurityDescriptor( SecurityDescriptor, 01789 TRUE, //DaclPresent, 01790 dacl, //Dacl 01791 FALSE ); 01792 01793 ASSERT( NT_SUCCESS( Status ) ); 01794 } 01795 01796 return STATUS_SUCCESS; 01797 }


Variable Documentation

ULONG ObpAuditBaseDirectories
 

Definition at line 103 of file obinit.c.

Referenced by ObInitSystem().

ULONG ObpAuditBaseObjects
 

Definition at line 104 of file obinit.c.

Referenced by ObInitSystem().

GENERIC_MAPPING ObpDirectoryMapping
 

Initial value:

{ STANDARD_RIGHTS_READ | DIRECTORY_QUERY | DIRECTORY_TRAVERSE, STANDARD_RIGHTS_WRITE | DIRECTORY_CREATE_OBJECT | DIRECTORY_CREATE_SUBDIRECTORY, STANDARD_RIGHTS_EXECUTE | DIRECTORY_QUERY | DIRECTORY_TRAVERSE, DIRECTORY_ALL_ACCESS }

Definition at line 34 of file obinit.c.

Referenced by ObInitSystem().

UNICODE_STRING ObpDosDevicesShortName
 

Definition at line 110 of file obinit.c.

Referenced by ObpCreateDosDevicesDirectory(), ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

ULARGE_INTEGER ObpDosDevicesShortNamePrefix
 

Definition at line 111 of file obinit.c.

Referenced by ObpCreateDosDevicesDirectory(), ObpLookupObjectName(), and ObpProcessDosDeviceSymbolicLink().

ULARGE_INTEGER ObpDosDevicesShortNameRoot
 

Definition at line 112 of file obinit.c.

Referenced by ObpCreateDosDevicesDirectory(), and ObpLookupObjectName().

KMUTANT ObpInitKillMutant
 

Definition at line 95 of file obinit.c.

ULONG ObpProtectionMode
 

Definition at line 102 of file obinit.c.

Referenced by ObpGetDosDevicesProtection().

GENERIC_MAPPING ObpSymbolicLinkMapping
 

Initial value:

{ STANDARD_RIGHTS_READ | SYMBOLIC_LINK_QUERY, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE | SYMBOLIC_LINK_QUERY, SYMBOLIC_LINK_ALL_ACCESS }

Definition at line 47 of file obinit.c.

Referenced by ObInitSystem().

GENERIC_MAPPING ObpTypeMapping
 

Initial value:

{ STANDARD_RIGHTS_READ, STANDARD_RIGHTS_WRITE, STANDARD_RIGHTS_EXECUTE, OBJECT_TYPE_ALL_ACCESS }

Definition at line 27 of file obinit.c.

Referenced by ObInitSystem().

PDEVICE_MAP ObSystemDeviceMap
 

Definition at line 113 of file obinit.c.

Referenced by ObInheritDeviceMap(), ObQueryDeviceMapInformation(), and ObSetDeviceMap().

EPROCESS_QUOTA_BLOCK PspDefaultQuotaBlock
 

Definition at line 88 of file obinit.c.


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