BOOLEAN INIT_FUNCTION NTAPI ExpInitializeTimerImplementation(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING Name; NTSTATUS Status; /* Create the Timer Object Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Timer"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETIMER); ObjectTypeInitializer.GenericMapping = ExpTimerMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = TIMER_ALL_ACCESS; ObjectTypeInitializer.DeleteProcedure = ExpDeleteTimer; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExTimerType); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize the Wait List and Lock */ KeInitializeSpinLock(&ExpWakeListLock); InitializeListHead(&ExpWakeList); return TRUE; }
BOOLEAN ExpMutantInitialization ( ) /*++ Routine Description: This function creates the mutant object type descriptor at system initialization and stores the address of the object type descriptor in local static storage. Arguments: None. Return Value: A value of TRUE is returned if the mutant object type descriptor is successfully created. Otherwise a value of FALSE is returned. --*/ { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; NTSTATUS Status; UNICODE_STRING TypeName; // // Initialize string descriptor. // RtlInitUnicodeString(&TypeName, L"Mutant"); // // Create mutant object type descriptor. // RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlZeroMemory(&PsGetCurrentProcess()->Pcb.DirectoryTableBase[0],KdDumpEnableOffset); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpMutantMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KMUTANT); ObjectTypeInitializer.ValidAccessMask = MUTANT_ALL_ACCESS; ObjectTypeInitializer.DeleteProcedure = ExpDeleteMutant; Status = ObCreateObjectType(&TypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExMutantObjectType); // // If the mutant object type descriptor was successfully created, then // return a value of TRUE. Otherwise return a value of FALSE. // return (BOOLEAN)(NT_SUCCESS(Status)); }
BOOLEAN ExpEventInitialization ( VOID ) /*++ Routine Description: This function creates the event object type descriptor at system initialization and stores the address of the object type descriptor in global storage. Arguments: None. Return Value: A value of TRUE is returned if the event object type descriptor is successfully initialized. Otherwise a value of FALSE is returned. --*/ { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; NTSTATUS Status; UNICODE_STRING TypeName; // // Initialize string descriptor. // RtlInitUnicodeString(&TypeName, L"Event"); // // Create event object type descriptor. // RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpEventMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT); ObjectTypeInitializer.ValidAccessMask = EVENT_ALL_ACCESS; Status = ObCreateObjectType(&TypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExEventObjectType); // // If the event object type descriptor was successfully created, then // return a value of TRUE. Otherwise return a value of FALSE. // return (BOOLEAN)(NT_SUCCESS(Status)); }
BOOLEAN INIT_FUNCTION NTAPI ExpWin32kInit(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING Name; NTSTATUS Status; DPRINT("Creating Win32 Object Types\n"); /* Create the window station Object Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"WindowStation"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.GenericMapping = ExpWindowStationMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DeleteProcedure = ExpWinStaObjectDelete; ObjectTypeInitializer.ParseProcedure = ExpWinStaObjectParse; ObjectTypeInitializer.OkayToCloseProcedure = ExpWindowStationOkToClose; ObjectTypeInitializer.SecurityRequired = TRUE; ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK | OBJ_PERMANENT | OBJ_EXCLUSIVE; ObjectTypeInitializer.ValidAccessMask = STANDARD_RIGHTS_REQUIRED; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExWindowStationObjectType); if (!NT_SUCCESS(Status)) return FALSE; /* Create desktop object type */ RtlInitUnicodeString(&Name, L"Desktop"); ObjectTypeInitializer.GenericMapping = ExpDesktopMapping; ObjectTypeInitializer.DeleteProcedure = ExpDesktopDelete; ObjectTypeInitializer.ParseProcedure = NULL; ObjectTypeInitializer.OkayToCloseProcedure = ExpDesktopOkToClose; ObjectTypeInitializer.OpenProcedure = ExpDesktopOpen; ObjectTypeInitializer.CloseProcedure = ExpDesktopClose; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExDesktopObjectType); if (!NT_SUCCESS(Status)) return FALSE; return TRUE; }
STATUS InitializeFoo( ) { OBJECT_TYPE_INITIALIZER typeInitializer; STATUS status; // // create a new object type: foo // typeInitializer.DumpMethod = DumpFoo; typeInitializer.DeleteMethod = DeleteFoo; status = ObCreateObjectType('foo', &typeInitializer, &fooType); return status; }
BOOLEAN NTAPI INIT_FUNCTION LpcInitSystem(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING Name; /* Setup the LPC Lock */ KeInitializeGuardedMutex(&LpcpLock); /* Create the Port Object Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Port"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(LPCP_PORT_OBJECT); ObjectTypeInitializer.DefaultPagedPoolCharge = sizeof(LPCP_NONPAGED_PORT_QUEUE); ObjectTypeInitializer.GenericMapping = LpcpPortMapping; ObjectTypeInitializer.PoolType = PagedPool; ObjectTypeInitializer.UseDefaultObject = TRUE; ObjectTypeInitializer.CloseProcedure = LpcpClosePort; ObjectTypeInitializer.DeleteProcedure = LpcpDeletePort; ObjectTypeInitializer.ValidAccessMask = PORT_ALL_ACCESS; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &LpcPortObjectType); /* Allocate the LPC lookaside list */ LpcpMaxMessageSize = LPCP_MAX_MESSAGE_SIZE; ExInitializePagedLookasideList(&LpcpMessagesLookaside, NULL, NULL, 0, LpcpMaxMessageSize, 'McpL', 32); /* We're done */ return TRUE; }
BOOLEAN INIT_FUNCTION NTAPI ExpInitializeEventImplementation(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING Name; NTSTATUS Status; DPRINT("Creating Event Object Type\n"); /* Create the Event Object Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Event"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KEVENT); ObjectTypeInitializer.GenericMapping = ExpEventMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = EVENT_ALL_ACCESS; ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExEventObjectType); if (!NT_SUCCESS(Status)) return FALSE; return TRUE; }
BOOLEAN obtest( void ) { ULONG i; HANDLE Handles[ 2 ]; NTSTATUS Status; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectTypeAName, "ObjectTypeA" ); RtlInitString( &ObjectTypeBName, "ObjectTypeB" ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.ValidAccessMask = -1; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.DumpProcedure = DumpAProc; ObjectTypeInitializer.OpenProcedure = OpenAProc; ObjectTypeInitializer.CloseProcedure = CloseAProc; ObjectTypeInitializer.DeleteProcedure = DeleteAProc; ObjectTypeInitializer.ParseProcedure = ParseAProc; ObCreateObjectType( &ObjectTypeAName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeA ); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.MaintainHandleCount = FALSE; ObjectTypeInitializer.GenericMapping = MyGenericMapping; ObjectTypeInitializer.DumpProcedure = DumpBProc; ObjectTypeInitializer.OpenProcedure = NULL; ObjectTypeInitializer.CloseProcedure = NULL; ObjectTypeInitializer.DeleteProcedure = DeleteBProc; ObjectTypeInitializer.ParseProcedure = NULL; ObCreateObjectType( &ObjectTypeBName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObjectTypeB ); ObpDumpTypes( NULL ); RtlInitString( &DirectoryName, "\\MyObjects" ); InitializeObjectAttributes( &DirectoryObjA, &DirectoryName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); NtCreateDirectoryObject( &DirectoryHandle, 0, &DirectoryObjA ); NtClose( DirectoryHandle ); RtlInitString( &ObjectAName, "\\myobjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_CASE_INSENSITIVE, NULL, NULL ); RtlInitString( &ObjectBName, "\\myobjects\\ObjectB" ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBName, OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA ); ObjectA = (POBJECTTYPEA)ObjectBodyA; ObjectA->TypeALength = sizeof( *ObjectA ); for (i=0; i<4; i++) { ObjectA->Stuff[i] = i+1; } KeInitializeEvent( &ObjectA->Event, NotificationEvent, TRUE ); Status = ObCreateObject( KernelMode, ObjectTypeB, &ObjectBObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEB ), 0L, 0L, (PVOID *)&ObjectBodyB ); ObjectB = (POBJECTTYPEB)ObjectBodyB; ObjectB->TypeBLength = sizeof( *ObjectB ); for (i=0; i<16; i++) { ObjectB->Stuff[i] = i+1; } KeInitializeSemaphore ( &ObjectB->Semaphore, 2L, 2L ); Status = ObInsertObject( ObjectBodyA, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA, &ObjectHandleA1 ); DbgPrint( "Status: %lx ObjectBodyA: %lx ObjectHandleA1: %lx\n", Status, ObjectBodyA, ObjectHandleA1 ); Status = ObInsertObject( ObjectBodyB, SYNCHRONIZE | 0x1, NULL, 1, &ObjectBodyB, &ObjectHandleB1 ); DbgPrint( "Status: %lx ObjectBodyB: %lx ObjectHandleB1: %lx\n", Status, ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAName, "\\MyObjects\\ObjectA" ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAName, OBJ_OPENIF, NULL, NULL ); Status = ObCreateObject( KernelMode, ObjectTypeA, &ObjectAObjA, KernelMode, NULL, (ULONG)sizeof( OBJECTTYPEA ), 0L, 0L, (PVOID *)&ObjectBodyA1 ); Status = ObInsertObject( ObjectBodyA1, SYNCHRONIZE | 0x3, NULL, 1, &ObjectBodyA2, &ObjectHandleA2 ); DbgPrint( "Status: %lx ObjectBodyA1: %lx ObjectBodyA2: %lx ObjectHandleA2: %lx\n", Status, ObjectBodyA1, ObjectBodyA2, ObjectHandleA2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA2 ); ObDereferenceObject( ObjectBodyA2 ); // ObInsertObject,ObjectPointerBias NtWaitForSingleObject( ObjectHandleB1, TRUE, NULL ); Handles[ 0 ] = ObjectHandleA1; Handles[ 1 ] = ObjectHandleB1; NtWaitForMultipleObjects( 2, Handles, WaitAny, TRUE, NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByPointer( ObjectBodyA, 0L, ObjectTypeA, KernelMode ); ObReferenceObjectByPointer( ObjectBodyB, 0L, ObjectTypeB, KernelMode ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); RtlInitString( &ObjectAPathName, "\\MyObjects\\ObjectA" ); RtlInitString( &ObjectBPathName, "\\MyObjects\\ObjectB" ); ObReferenceObjectByName( &ObjectAPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeA, KernelMode, NULL, &ObjectBodyA ); ObReferenceObjectByName( &ObjectBPathName, OBJ_CASE_INSENSITIVE, 0L, ObjectTypeB, KernelMode, NULL, &ObjectBodyB ); DbgPrint( "Reference Name %s = %lx\n", ObjectAPathName.Buffer, ObjectBodyA ); DbgPrint( "Reference Name %s = %lx\n", ObjectBPathName.Buffer, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObInsertObject,ObjectPointerBias ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByPointer ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByName ObDereferenceObject( ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); InitializeObjectAttributes( &ObjectAObjA, &ObjectAPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectAObjA, 0L, NULL, ObjectTypeA, KernelMode, NULL, &ObjectHandleA2 ); InitializeObjectAttributes( &ObjectBObjA, &ObjectBPathName, OBJ_CASE_INSENSITIVE, NULL, NULL ); ObOpenObjectByName( &ObjectBObjA, 0L, NULL, ObjectTypeB, KernelMode, NULL, &ObjectHandleB2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectAPathName.Buffer, ObjectHandleA2 ); DbgPrint( "Open Object Name %s = %lx\n", ObjectBPathName.Buffer, ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA2, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB2, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA2, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB2, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObOpenObjectByPointer( ObjectBodyA, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeA, KernelMode, &ObjectHandleA1 ); ObOpenObjectByPointer( ObjectBodyB, OBJ_CASE_INSENSITIVE, 0L, NULL, ObjectTypeB, KernelMode, &ObjectHandleB1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyA, ObjectHandleA1 ); DbgPrint( "Open Object Pointer %lx = %lx\n", ObjectBodyB, ObjectHandleB1 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObReferenceObjectByHandle( ObjectHandleA1, 0L, ObjectTypeA, KernelMode, &ObjectBodyA, NULL ); ObReferenceObjectByHandle( ObjectHandleB1, 0L, ObjectTypeB, KernelMode, &ObjectBodyB, NULL ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleA1, ObjectBodyA ); DbgPrint( "Reference Handle %lx = %lx\n", ObjectHandleB1, ObjectBodyB ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); ObDereferenceObject( ObjectBodyA ); // ObReferenceObjectByHandle ObDereferenceObject( ObjectBodyB ); NtClose( ObjectHandleA1 ); NtClose( ObjectHandleB1 ); NtClose( ObjectHandleA2 ); NtClose( ObjectHandleB2 ); ObpDumpObjectTable( ObpGetObjectTable(), NULL ); TestFunction = NULL; return( TRUE ); }
BOOLEAN ObInitSystem( VOID ) /*++ Routine Description: This function performs the system initialization for the object manager. The object manager data structures are self describing with the exception of the root directory, the type object type and the directory object type. The initialization code then constructs these objects by hand to get the ball rolling. Arguments: None. Return Value: TRUE if successful and FALSE if an error occurred. The following errors can occur: - insufficient memory --*/ { USHORT CreateInfoMaxDepth; USHORT NameBufferMaxDepth; ULONG RegionSegmentSize; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING TypeTypeName; UNICODE_STRING SymbolicLinkTypeName; UNICODE_STRING DosDevicesDirectoryName; UNICODE_STRING DirectoryTypeName; UNICODE_STRING RootDirectoryName; UNICODE_STRING TypeDirectoryName; NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; HANDLE RootDirectoryHandle; HANDLE TypeDirectoryHandle; PLIST_ENTRY Next, Head; POBJECT_HEADER ObjectTypeHeader; POBJECT_HEADER_CREATOR_INFO CreatorInfo; POBJECT_HEADER_NAME_INFO NameInfo; MM_SYSTEMSIZE SystemSize; SECURITY_DESCRIPTOR AuditSd; PSECURITY_DESCRIPTOR EffectiveSd; PACL AuditAllAcl; UCHAR AuditAllBuffer[250]; // Ample room for the ACL ULONG AuditAllLength; PACE_HEADER Ace; // // PHASE 0 Initialization // if (InitializationPhase == 0) { // // Determine the the size of the object creation and the name buffer // lookaside lists. // SystemSize = MmQuerySystemSize(); if (SystemSize == MmLargeSystem) { if (MmIsThisAnNtAsSystem()) { CreateInfoMaxDepth = 64; NameBufferMaxDepth = 32; } else { CreateInfoMaxDepth = 32; NameBufferMaxDepth = 16; } } else { CreateInfoMaxDepth = 3; NameBufferMaxDepth = 3; } // // Initialize the object creation lookaside list. // ExInitializeNPagedLookasideList(&ObpCreateInfoLookasideList, NULL, NULL, 0, sizeof(OBJECT_CREATE_INFORMATION), 'iCbO', CreateInfoMaxDepth); // // Initialize the name buffer lookaside list. // ExInitializeNPagedLookasideList(&ObpNameBufferLookasideList, NULL, NULL, 0, OBJECT_NAME_BUFFER_SIZE, 'mNbO', NameBufferMaxDepth); InitializeListHead( &ObpRemoveObjectQueue ); // // Initialize security descriptor cache // ObpInitSecurityDescriptorCache(); KeInitializeMutant( &ObpInitKillMutant, FALSE ); KeInitializeEvent( &ObpDefaultObject, NotificationEvent, TRUE ); KeInitializeSpinLock( &ObpLock ); PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS; PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS; // // Initialize the quota block // KeInitializeSpinLock(&PspDefaultQuotaBlock.QuotaLock); PspDefaultQuotaBlock.ReferenceCount = 1; PspDefaultQuotaBlock.QuotaPoolLimit[PagedPool] = (ULONG)-1; PspDefaultQuotaBlock.QuotaPoolLimit[NonPagedPool] = (ULONG)-1; PspDefaultQuotaBlock.PagefileLimit = (ULONG)-1; PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock; PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable( NULL, 0, 0 ); RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.PoolType = NonPagedPool; RtlInitUnicodeString( &TypeTypeName, L"Type" ); ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = ObpTypeMapping; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_TYPE ); ObjectTypeInitializer.MaintainTypeList = TRUE; ObjectTypeInitializer.UseDefaultObject = TRUE; ObCreateObjectType( &TypeTypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObpTypeObjectType ); RtlInitUnicodeString( &DirectoryTypeName, L"Directory" ); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_DIRECTORY ); ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping; ObjectTypeInitializer.MaintainTypeList = FALSE; ObCreateObjectType( &DirectoryTypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObpDirectoryObjectType ); RtlInitUnicodeString( &SymbolicLinkTypeName, L"SymbolicLink" ); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_SYMBOLIC_LINK ); ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink; ObCreateObjectType( &SymbolicLinkTypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ObpSymbolicLinkObjectType ); ExInitializeResourceLite( &ObpRootDirectoryMutex ); #if i386 && !FPO ObpCurCachedGrantedAccessIndex = 0; ObpMaxCachedGrantedAccessIndex = PAGE_SIZE / sizeof( ACCESS_MASK ); ObpCachedGrantedAccesses = ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, 'gAbO' ); #endif // i386 && !FPO #if DBG ObpCreateObjectEventId = RtlCreateEventId( NULL, 0, "CreateObject", 6, RTL_EVENT_ULONG_PARAM, "Object", 0, RTL_EVENT_PUNICODE_STRING_PARAM, "Type", 0, RTL_EVENT_ULONG_PARAM, "PagedPool", 0, RTL_EVENT_ULONG_PARAM, "NonPagedPool", 0, RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0, RTL_EVENT_FLAGS_PARAM, "", 5, OBJ_INHERIT, "Inherit", OBJ_PERMANENT, "Permanent", OBJ_OPENIF, "OpenIf", OBJ_CASE_INSENSITIVE, "CaseInsenitive", OBJ_EXCLUSIVE, "Exclusive" ); ObpFreeObjectEventId = RtlCreateEventId( NULL, 0, "FreeObject", 3, RTL_EVENT_ULONG_PARAM, "Object", 0, RTL_EVENT_ULONG_PARAM, "Type", 0, RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0 ); #endif // DBG } // End of Phase 0 Initializtion // // PHASE 1 Initialization // if (InitializationPhase == 1) { EffectiveSd = SePublicDefaultSd; // // This code is only executed if base auditing is turned on. // if ((ObpAuditBaseDirectories != 0) || (ObpAuditBaseObjects != 0)) { // // build an SACL to audit // AuditAllAcl = (PACL)AuditAllBuffer; AuditAllLength = (ULONG)sizeof(ACL) + ((ULONG)sizeof(SYSTEM_AUDIT_ACE)) + SeLengthSid(SeWorldSid); ASSERT( sizeof(AuditAllBuffer) > AuditAllLength ); Status = RtlCreateAcl( AuditAllAcl, AuditAllLength, ACL_REVISION2); ASSERT( NT_SUCCESS(Status) ); Status = RtlAddAuditAccessAce ( AuditAllAcl, ACL_REVISION2, GENERIC_ALL, SeWorldSid, TRUE, TRUE //Audit success and failure ); ASSERT( NT_SUCCESS(Status) ); Status = RtlGetAce( AuditAllAcl, 0, (PVOID)&Ace ); ASSERT( NT_SUCCESS(Status) ); if (ObpAuditBaseDirectories != 0) { Ace->AceFlags |= (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); } if (ObpAuditBaseObjects != 0) { Ace->AceFlags |= (OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE); } // // Now create a security descriptor that looks just like // the public default, but has auditing in it as well. EffectiveSd = (PSECURITY_DESCRIPTOR)&AuditSd; Status = RtlCreateSecurityDescriptor( EffectiveSd, SECURITY_DESCRIPTOR_REVISION1 ); ASSERT( NT_SUCCESS(Status) ); Status = RtlSetDaclSecurityDescriptor( EffectiveSd, TRUE, // DaclPresent SePublicDefaultDacl, FALSE // DaclDefaulted ); ASSERT( NT_SUCCESS(Status) ); Status = RtlSetSaclSecurityDescriptor( EffectiveSd, TRUE, // DaclPresent AuditAllAcl, FALSE // DaclDefaulted ); ASSERT( NT_SUCCESS(Status) ); } // // We only need to use the EffectiveSd on the root. The SACL // will be inherited by all other objects. // RtlInitUnicodeString( &RootDirectoryName, L"\\" ); InitializeObjectAttributes( &ObjectAttributes, &RootDirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, EffectiveSd ); Status = NtCreateDirectoryObject( &RootDirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { return( FALSE ); } Status = ObReferenceObjectByHandle( RootDirectoryHandle, 0, ObpDirectoryObjectType, KernelMode, (PVOID *)&ObpRootDirectoryObject, NULL ); if (!NT_SUCCESS( Status )) { return( FALSE ); } Status = NtClose( RootDirectoryHandle ); if (!NT_SUCCESS( Status )) { return( FALSE ); } RtlInitUnicodeString( &TypeDirectoryName, L"\\ObjectTypes" ); InitializeObjectAttributes( &ObjectAttributes, &TypeDirectoryName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL ); Status = NtCreateDirectoryObject( &TypeDirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS( Status )) { return( FALSE ); } Status = ObReferenceObjectByHandle( TypeDirectoryHandle, 0, ObpDirectoryObjectType, KernelMode, (PVOID *)&ObpTypeDirectoryObject, NULL ); if (!NT_SUCCESS( Status )) { return( FALSE ); } Status = NtClose( TypeDirectoryHandle ); if (!NT_SUCCESS( Status )) { return( FALSE ); } ObpEnterRootDirectoryMutex(); Head = &ObpTypeObjectType->TypeList; Next = Head->Flink; while (Next != Head) { CreatorInfo = CONTAINING_RECORD( Next, OBJECT_HEADER_CREATOR_INFO, TypeList ); ObjectTypeHeader = (POBJECT_HEADER)(CreatorInfo+1); NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectTypeHeader ); if (NameInfo != NULL && NameInfo->Directory == NULL) { if (!ObpLookupDirectoryEntry( ObpTypeDirectoryObject, &NameInfo->Name, OBJ_CASE_INSENSITIVE ) ) { ObpInsertDirectoryEntry( ObpTypeDirectoryObject, &ObjectTypeHeader->Body ); } } Next = Next->Flink; } ObpLeaveRootDirectoryMutex(); // // Create \DosDevices object directory for drive letters and Win32 device names // Status = ObpCreateDosDevicesDirectory(); if (!NT_SUCCESS( Status )) { return FALSE; } } return TRUE; }
BOOLEAN ExpTimerInitialization ( ) /*++ Routine Description: This function creates the timer object type descriptor at system initialization and stores the address of the object type descriptor in local static storage. Arguments: None. Return Value: A value of TRUE is returned if the timer object type descriptor is successfully initialized. Otherwise a value of FALSE is returned. --*/ { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; NTSTATUS Status; UNICODE_STRING TypeName; KeInitializeSpinLock (&ExpWakeTimerListLock); InitializeListHead (&ExpWakeTimerList); // // Initialize string descriptor. // RtlInitUnicodeString(&TypeName, L"Timer"); // // Create timer object type descriptor. // RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpTimerMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(ETIMER); ObjectTypeInitializer.ValidAccessMask = TIMER_ALL_ACCESS; ObjectTypeInitializer.DeleteProcedure = ExpDeleteTimer; Status = ObCreateObjectType(&TypeName, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExTimerObjectType); // // If the time object type descriptor was successfully created, then // return a value of TRUE. Otherwise return a value of FALSE. // return (BOOLEAN)(NT_SUCCESS(Status)); }
BOOLEAN PspInitPhase0 ( IN PLOADER_PARAMETER_BLOCK LoaderBlock ) /*++ Routine Description: This routine performs phase 0 process structure initialization. During this phase, the initial system process, phase 1 initialization thread, and reaper threads are created. All object types and other process structures are created and initialized. Arguments: None. Return Value: TRUE - Initialization was successful. FALSE - Initialization Failed. --*/ { PLDR_DATA_TABLE_ENTRY DataTableEntry1; PLDR_DATA_TABLE_ENTRY DataTableEntry2; UNICODE_STRING NameString; PLIST_ENTRY NextEntry; OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; HANDLE ThreadHandle; PETHREAD Thread; MM_SYSTEMSIZE SystemSize; PsPrioritySeperation = 2; SystemSize = MmQuerySystemSize(); PspDefaultPagefileLimit = (ULONG)-1; if ( sizeof(TEB) > 4096 || sizeof(PEB) > 4096 ) { KeBugCheckEx(PROCESS_INITIALIZATION_FAILED,99,sizeof(TEB),sizeof(PEB),99); } switch ( SystemSize ) { case MmMediumSystem : PsMinimumWorkingSet += 10; PsMaximumWorkingSet += 100; break; case MmLargeSystem : PsMinimumWorkingSet += 30; PsMaximumWorkingSet += 300; break; case MmSmallSystem : default: break; } if ( MmIsThisAnNtAsSystem() ) { PspForegroundQuantum[0] = 6*THREAD_QUANTUM; PspForegroundQuantum[1] = 6*THREAD_QUANTUM; PspForegroundQuantum[2] = 6*THREAD_QUANTUM; } else { // // For Workstation: // // BG is THREAD_QUANTUM // FG is THREAD_QUANTUM 50/50 fg/bg // FG is 2 * THREAD_QUANTUM 65/35 fg/bg // FG is 3 * THREAD_QUANTUM 75/25 fg/bg // PspForegroundQuantum[0] = THREAD_QUANTUM; PspForegroundQuantum[1] = 2*THREAD_QUANTUM; PspForegroundQuantum[2] = 3*THREAD_QUANTUM; } // // Quotas grow as needed automatically // if ( !PspDefaultPagedLimit ) { PspDefaultPagedLimit = 0; } if ( !PspDefaultNonPagedLimit ) { PspDefaultNonPagedLimit = 0; } if ( PspDefaultNonPagedLimit == 0 && PspDefaultPagedLimit == 0) { PspDoingGiveBacks = TRUE; } else { PspDoingGiveBacks = FALSE; } PspDefaultPagedLimit *= PSP_1MB; PspDefaultNonPagedLimit *= PSP_1MB; if (PspDefaultPagefileLimit != -1) { PspDefaultPagefileLimit *= PSP_1MB; } // // Initialize the process security fields lock and the process lock. // ExInitializeFastMutex( &PspProcessLockMutex ); ExInitializeFastMutex( &PspProcessSecurityLock ); // // Initialize the loaded module list executive resource and spin lock. // ExInitializeResource( &PsLoadedModuleResource ); KeInitializeSpinLock( &PsLoadedModuleSpinLock ); KeInitializeSpinLock( &PspEventPairLock ); // // Initialize the loaded module listheads. // PsIdleProcess = PsGetCurrentProcess(); PsIdleProcess->Pcb.KernelTime = 0; PsIdleProcess->Pcb.KernelTime = 0; InitializeListHead(&PsLoadedModuleList); // // Scan the loaded module list and allocate and initialize a data table // entry for each module. The data table entry is inserted in the loaded // module list and the initialization order list in the order specified // in the loader parameter block. The data table entry is inserted in the // memory order list in memory order. // NextEntry = LoaderBlock->LoadOrderListHead.Flink; DataTableEntry2 = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); PsNtosImageBase = DataTableEntry2->DllBase; DataTableEntry2 = (PLDR_DATA_TABLE_ENTRY) NextEntry->Flink; DataTableEntry2 = CONTAINING_RECORD(DataTableEntry2, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); PsHalImageBase = DataTableEntry2->DllBase; while (NextEntry != &LoaderBlock->LoadOrderListHead) { DataTableEntry2 = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); // // Allocate a data table entry. // DataTableEntry1 = ExAllocatePool(NonPagedPool, sizeof(LDR_DATA_TABLE_ENTRY) + DataTableEntry2->FullDllName.MaximumLength + DataTableEntry2->BaseDllName.MaximumLength + sizeof(ULONG) + sizeof(ULONG)); if (DataTableEntry1 == NULL) { return FALSE; } // // Copy the data table entry. // *DataTableEntry1 = *DataTableEntry2; // // Copy the strings. // DataTableEntry1->FullDllName.Buffer = (PWSTR)((PCHAR)DataTableEntry1 + ROUND_UP(sizeof(LDR_DATA_TABLE_ENTRY), sizeof(ULONG))); RtlMoveMemory (DataTableEntry1->FullDllName.Buffer, DataTableEntry2->FullDllName.Buffer, DataTableEntry1->FullDllName.MaximumLength); DataTableEntry1->BaseDllName.Buffer = (PWSTR)((PCHAR)DataTableEntry1->FullDllName.Buffer + ROUND_UP(DataTableEntry1->FullDllName.MaximumLength, sizeof(ULONG))); RtlMoveMemory (DataTableEntry1->BaseDllName.Buffer, DataTableEntry2->BaseDllName.Buffer, DataTableEntry1->BaseDllName.MaximumLength); // // Insert the data table entry in the load order list in the order // they are specified. // InsertTailList(&PsLoadedModuleList, &DataTableEntry1->InLoadOrderLinks); NextEntry = NextEntry->Flink; } // // Initialize the common fields of the Object Type Prototype record // RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) ); ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer ); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.SecurityRequired = TRUE; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.InvalidAttributes = OBJ_PERMANENT | OBJ_EXCLUSIVE | OBJ_OPENIF; // // Create Object types for Thread and Process Objects. // RtlInitUnicodeString(&NameString, L"Process"); ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_PROCESS_PAGED_CHARGE; ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_PROCESS_NONPAGED_CHARGE; ObjectTypeInitializer.DeleteProcedure = PspProcessDelete; ObjectTypeInitializer.ValidAccessMask = PROCESS_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = PspProcessMapping; if ( !NT_SUCCESS(ObCreateObjectType(&NameString, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR) NULL, &PsProcessType )) ){ return FALSE; } RtlInitUnicodeString(&NameString, L"Thread"); ObjectTypeInitializer.DefaultPagedPoolCharge = PSP_THREAD_PAGED_CHARGE; ObjectTypeInitializer.DefaultNonPagedPoolCharge = PSP_THREAD_NONPAGED_CHARGE; ObjectTypeInitializer.DeleteProcedure = PspThreadDelete; ObjectTypeInitializer.ValidAccessMask = THREAD_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = PspThreadMapping; if ( !NT_SUCCESS(ObCreateObjectType(&NameString, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR) NULL, &PsThreadType )) ){ return FALSE; } // // Initialize active process list head and mutex // InitializeListHead(&PsActiveProcessHead); ExInitializeFastMutex(&PspActiveProcessMutex); // // Initialize CID handle table. // // N.B. The CID handle table is removed from the handle table list so // it will not be enumerated for object handle queries. // PspCidTable = ExCreateHandleTable(NULL, 0, 0); if ( ! PspCidTable ) { return FALSE; } ExRemoveHandleTable(PspCidTable); #ifdef i386 // // Ldt Initialization // if ( !NT_SUCCESS(PspLdtInitialize()) ) { return FALSE; } // // Vdm support Initialization // if ( !NT_SUCCESS(PspVdmInitialize()) ) { return FALSE; } #endif // // Initialize Reaper Data Structures // InitializeListHead(&PsReaperListHead); ExInitializeWorkItem(&PsReaperWorkItem, PspReaper, NULL); // // Get a pointer to the system access token. // This token is used by the boot process, so we can take the pointer // from there. // PspBootAccessToken = PsGetCurrentProcess()->Token; InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL ); // FIXFIX if ( !NT_SUCCESS(PspCreateProcess( &PspInitialSystemProcessHandle, PROCESS_ALL_ACCESS, &ObjectAttributes, 0L, FALSE, 0L, 0L, 0L )) ) { return FALSE; } if ( !NT_SUCCESS(ObReferenceObjectByHandle( PspInitialSystemProcessHandle, 0L, PsProcessType, KernelMode, (PVOID *)&PsInitialSystemProcess, NULL )) ) { return FALSE; } strcpy(&PsGetCurrentProcess()->ImageFileName[0],"Idle"); strcpy(&PsInitialSystemProcess->ImageFileName[0],"System"); // // Phase 1 System initialization // if ( !NT_SUCCESS(PsCreateSystemThread( &ThreadHandle, THREAD_ALL_ACCESS, &ObjectAttributes, 0L, NULL, Phase1Initialization, (PVOID)LoaderBlock )) ) { return FALSE; } if ( !NT_SUCCESS(ObReferenceObjectByHandle( ThreadHandle, 0L, PsThreadType, KernelMode, (PVOID *)&Thread, NULL )) ) { return FALSE; } ZwClose( ThreadHandle ); #if DBG PspExitProcessEventId = RtlCreateEventId( NULL, 0, "ExitProcess", 1, RTL_EVENT_STATUS_PARAM, "ExitStatus", 0 ); PspPageFaultEventId = RtlCreateEventId( NULL, 0, "PageFault", 3, RTL_EVENT_STATUS_PARAM, "", 0, RTL_EVENT_ADDRESS_PARAM, "PC", 0, RTL_EVENT_ADDRESS_PARAM, "Va", 0 ); #endif // DBG return TRUE; }
BOOLEAN ExpInitializeCallbacks ( ) /*++ Routine Description: This function creates the callback object type descriptor at system initialization and stores the address of the object type descriptor in local static storage. Arguments: None. Return Value: A value of TRUE is returned if the timer object type descriptor is successfully initialized. Otherwise a value of FALSE is returned. --*/ { #ifdef _PNP_POWER_ OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING unicodeString; ULONG i; HANDLE handle; // // Initialize string descriptor. // RtlInitUnicodeString(&unicodeString, L"Callback"); // // Create timer object type descriptor. // RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpCallbackMapping; ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS; Status = ObCreateObjectType(&unicodeString, &ObjectTypeInitializer, (PSECURITY_DESCRIPTOR)NULL, &ExCallbackObjectType); if (!NT_SUCCESS(Status)) { return FALSE; } RtlInitUnicodeString( &unicodeString, ExpWstrCallback ); InitializeObjectAttributes( &ObjectAttributes, &unicodeString, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultSd ); Status = NtCreateDirectoryObject( &handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes ); if (!NT_SUCCESS(Status)) { return FALSE; } NtClose (handle); // // Initialize event to wait on for Unregisters which occur while // notifications are in progress // KeInitializeEvent (&ExpCallbackEvent, NotificationEvent, 0); // // Initialize NT global callbacks // for (i=0; ExpInitializeCallback[i].CallBackObject; i++) { // // Create named calledback // RtlInitUnicodeString(&unicodeString, ExpInitializeCallback[i].CallbackName); InitializeObjectAttributes( &ObjectAttributes, &unicodeString, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL ); Status = ExCreateCallback ( ExpInitializeCallback[i].CallBackObject, &ObjectAttributes, TRUE, TRUE ); if (!NT_SUCCESS(Status)) { return FALSE; } } #endif return TRUE; }
BOOLEAN INIT_FUNCTION NTAPI IopCreateObjectTypes(VOID) { OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; UNICODE_STRING Name; /* Initialize default settings */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; ObjectTypeInitializer.UseDefaultObject = TRUE; ObjectTypeInitializer.GenericMapping = IopFileMapping; /* Do the Adapter Type */ RtlInitUnicodeString(&Name, L"Adapter"); if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoAdapterObjectType))) return FALSE; /* Do the Controller Type */ RtlInitUnicodeString(&Name, L"Controller"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(CONTROLLER_OBJECT); if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoControllerObjectType))) return FALSE; /* Do the Device Type */ RtlInitUnicodeString(&Name, L"Device"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DEVICE_OBJECT); ObjectTypeInitializer.DeleteProcedure = IopDeleteDevice; ObjectTypeInitializer.ParseProcedure = IopParseDevice; ObjectTypeInitializer.SecurityProcedure = IopSecurityFile; ObjectTypeInitializer.CaseInsensitive = TRUE; if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoDeviceObjectType))) return FALSE; /* Initialize the Driver object type */ RtlInitUnicodeString(&Name, L"Driver"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(DRIVER_OBJECT); ObjectTypeInitializer.DeleteProcedure = IopDeleteDriver; ObjectTypeInitializer.ParseProcedure = NULL; ObjectTypeInitializer.SecurityProcedure = NULL; if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoDriverObjectType))) return FALSE; /* Initialize the I/O Completion object type */ RtlInitUnicodeString(&Name, L"IoCompletion"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(KQUEUE); ObjectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS; ObjectTypeInitializer.InvalidAttributes |= OBJ_PERMANENT; ObjectTypeInitializer.GenericMapping = IopCompletionMapping; ObjectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion; if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoCompletionType))) return FALSE; /* Initialize the File object type */ RtlInitUnicodeString(&Name, L"File"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(FILE_OBJECT); ObjectTypeInitializer.InvalidAttributes |= OBJ_EXCLUSIVE; ObjectTypeInitializer.MaintainHandleCount = TRUE; ObjectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; ObjectTypeInitializer.GenericMapping = IopFileMapping; ObjectTypeInitializer.CloseProcedure = IopCloseFile; ObjectTypeInitializer.DeleteProcedure = IopDeleteFile; ObjectTypeInitializer.SecurityProcedure = IopSecurityFile; ObjectTypeInitializer.QueryNameProcedure = IopQueryNameFile; ObjectTypeInitializer.ParseProcedure = IopParseFile; ObjectTypeInitializer.UseDefaultObject = FALSE; if (!NT_SUCCESS(ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &IoFileObjectType))) return FALSE; /* Success */ return TRUE; }
BOOLEAN INIT_FUNCTION NTAPI ObInitSystem(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; OBP_LOOKUP_CONTEXT Context; HANDLE Handle; PKPRCB Prcb = KeGetCurrentPrcb(); PLIST_ENTRY ListHead, NextEntry; POBJECT_HEADER Header; POBJECT_HEADER_CREATOR_INFO CreatorInfo; POBJECT_HEADER_NAME_INFO NameInfo; NTSTATUS Status; /* Check if this is actually Phase 1 initialization */ if (ObpInitializationPhase != 0) goto ObPostPhase0; /* Initialize the OBJECT_CREATE_INFORMATION List */ ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList, NonPagedPool, sizeof(OBJECT_CREATE_INFORMATION), 'ICbO', 32, &ExSystemLookasideListHead); /* Set the captured UNICODE_STRING Object Name List */ ExInitializeSystemLookasideList(&ObpNameBufferLookasideList, PagedPool, 248, 'MNbO', 16, &ExSystemLookasideListHead); /* Temporarily setup both pointers to the shared list */ Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList; Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList; Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList; Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList; /* Initialize the security descriptor cache */ ObpInitSdCache(); /* Initialize the Default Event */ KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE); /* Initialize the Dos Device Map mutex */ KeInitializeGuardedMutex(&ObpDeviceMapLock); /* Setup default access for the system process */ PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS; PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS; /* Setup the Object Reaper */ ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL); /* Initialize default Quota block */ PsInitializeQuotaSystem(); /* Create kernel handle table */ PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL); ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable; /* Create the Type Type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Type"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS; ObjectTypeInitializer.UseDefaultObject = TRUE; ObjectTypeInitializer.MaintainTypeList = TRUE; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.GenericMapping = ObpTypeMapping; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType); /* Create the Directory Type */ RtlInitUnicodeString(&Name, L"Directory"); ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS; ObjectTypeInitializer.CaseInsensitive = TRUE; ObjectTypeInitializer.MaintainTypeList = FALSE; ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping; ObjectTypeInitializer.DeleteProcedure = NULL; ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY); ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType); /* Create 'symbolic link' object type */ RtlInitUnicodeString(&Name, L"SymbolicLink"); ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK); ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping; ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS; ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink; ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink; ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType); /* Phase 0 initialization complete */ ObpInitializationPhase++; return TRUE; ObPostPhase0: /* Re-initialize lookaside lists */ ObInit2(); /* Initialize Object Types directory attributes */ RtlInitUnicodeString(&Name, L"\\"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultUnrestrictedSd); /* Create the directory */ Status = NtCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Get a handle to it */ Status = ObReferenceObjectByHandle(Handle, 0, ObDirectoryType, KernelMode, (PVOID*)&ObpRootDirectoryObject, NULL); if (!NT_SUCCESS(Status)) return FALSE; /* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize Object Types directory attributes */ RtlInitUnicodeString(&Name, L"\\KernelObjects"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); /* Create the directory */ Status = NtCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize Object Types directory attributes */ RtlInitUnicodeString(&Name, L"\\ObjectTypes"); InitializeObjectAttributes(&ObjectAttributes, &Name, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, NULL); /* Create the directory */ Status = NtCreateDirectoryObject(&Handle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Get a handle to it */ Status = ObReferenceObjectByHandle(Handle, 0, ObDirectoryType, KernelMode, (PVOID*)&ObpTypeDirectoryObject, NULL); if (!NT_SUCCESS(Status)) return FALSE; /* Close the extra handle */ Status = NtClose(Handle); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize lookup context */ ObpInitializeLookupContext(&Context); /* Lock it */ ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context); /* Loop the object types */ ListHead = &ObpTypeObjectType->TypeList; NextEntry = ListHead->Flink; while (ListHead != NextEntry) { /* Get the creator info from the list */ CreatorInfo = CONTAINING_RECORD(NextEntry, OBJECT_HEADER_CREATOR_INFO, TypeList); /* Recover the header and the name header from the creator info */ Header = (POBJECT_HEADER)(CreatorInfo + 1); NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header); /* Make sure we have a name, and aren't inserted yet */ if ((NameInfo) && !(NameInfo->Directory)) { /* Do the initial lookup to setup the context */ if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject, &NameInfo->Name, OBJ_CASE_INSENSITIVE, FALSE, &Context)) { /* Insert this object type */ ObpInsertEntryDirectory(ObpTypeDirectoryObject, &Context, Header); } } /* Move to the next entry */ NextEntry = NextEntry->Flink; } /* Cleanup after lookup */ ObpReleaseLookupContext(&Context); /* Initialize DOS Devices Directory and related Symbolic Links */ Status = ObpCreateDosDevicesDirectory(); if (!NT_SUCCESS(Status)) return FALSE; return TRUE; }
/*++ * @name ExpInitializeCallbacks * * Creates the Callback Object as a valid Object Type in the Kernel. * Internal function, subject to further review * * @return TRUE if the Callback Object Type was successfully created. * * @remarks None * *--*/ BOOLEAN INIT_FUNCTION NTAPI ExpInitializeCallbacks(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; NTSTATUS Status; UNICODE_STRING DirName = RTL_CONSTANT_STRING(L"\\Callback"); UNICODE_STRING CallbackName; UNICODE_STRING Name; OBJECT_TYPE_INITIALIZER ObjectTypeInitializer; HANDLE DirectoryHandle; ULONG i; /* Setup lightweight callback lock */ ExpCallBackFlush.Value = 0; /* Initialize the Callback Object type */ RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer)); RtlInitUnicodeString(&Name, L"Callback"); ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer); ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; ObjectTypeInitializer.GenericMapping = ExpCallbackMapping; ObjectTypeInitializer.PoolType = NonPagedPool; ObjectTypeInitializer.DeleteProcedure = ExpDeleteCallback; ObjectTypeInitializer.ValidAccessMask = CALLBACK_ALL_ACCESS; Status = ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ExCallbackObjectType); if (!NT_SUCCESS(Status)) return FALSE; /* Initialize the Object */ InitializeObjectAttributes(&ObjectAttributes, &DirName, OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, NULL, SePublicDefaultSd); /* Create the Object Directory */ Status = NtCreateDirectoryObject(&DirectoryHandle, DIRECTORY_ALL_ACCESS, &ObjectAttributes); if (!NT_SUCCESS(Status)) return FALSE; /* Close Handle... */ NtClose(DirectoryHandle); /* Initialize Event used when unregistering */ KeInitializeEvent(&ExpCallbackEvent, NotificationEvent, 0); /* Default NT Kernel Callbacks. */ for (i = 0; ExpInitializeCallback[i].CallbackObject; i++) { /* Create the name from the structure */ RtlInitUnicodeString(&CallbackName, ExpInitializeCallback[i].Name); /* Initialize the Object Attributes Structure */ InitializeObjectAttributes(&ObjectAttributes, &CallbackName, OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, NULL, NULL); /* Create the Callback Object */ Status = ExCreateCallback(ExpInitializeCallback[i].CallbackObject, &ObjectAttributes, TRUE, TRUE); if (!NT_SUCCESS(Status)) return FALSE; } /* Everything successful */ return TRUE; }