VOID CmpInitCmPrivateAlloc( ) /*++ Routine Description: Initialize the CmPrivate pool allocation module Arguments: Return Value: --*/ { if( CmpAllocInited ) { // // already initialized // return; } InitializeListHead(&(CmpFreeKCBListHead)); // // init the bucket lock // KeInitializeGuardedMutex(&CmpAllocBucketLock); CmpAllocInited = TRUE; }
VOID CmpInitializeDelayedCloseTable() /*++ Routine Description: Initialize delayed close table; allocation + LRU list initialization. Arguments: Return Value: NONE. --*/ { ExInitializeWorkItem(&CmpDelayCloseWorkItem, CmpDelayCloseWorker, NULL); KeInitializeGuardedMutex(&CmpDelayedCloseTableLock); InitializeListHead(&(CmpDelayedLRUListHead)); KeInitializeDpc(&CmpDelayCloseDpc, CmpDelayCloseDpcRoutine, NULL); KeInitializeTimer(&CmpDelayCloseTimer); }
VOID CmpInitCmPrivateDelayAlloc( ) /*++ Routine Description: Initialize the CmPrivate pool allocation module for delay related allocs Arguments: Return Value: --*/ { InitializeListHead(&(CmpFreeDelayItemsListHead)); // // init the bucket lock // KeInitializeGuardedMutex(&CmpDelayAllocBucketLock); }
VOID NTAPI INIT_FUNCTION CmpInitCmPrivateDelayAlloc(VOID) { /* Initialize the delay allocation list and lock */ KeInitializeGuardedMutex(&CmpDelayAllocBucketLock); InitializeListHead(&CmpFreeDelayItemsListHead); }
VOID CmpInitDelayDerefKCBEngine() { InitializeListHead(&CmpDelayDerefKCBListHead); KeInitializeGuardedMutex(&CmpDelayDerefKCBLock); ExInitializeWorkItem(&CmpDelayDerefKCBWorkItem, CmpDelayDerefKCBWorker, NULL); KeInitializeDpc(&CmpDelayDerefKCBDpc, CmpDelayDerefKCBDpcRoutine, NULL); KeInitializeTimer(&CmpDelayDerefKCBTimer); }
VOID NTAPI INIT_FUNCTION CmpInitCmPrivateAlloc(VOID) { /* Make sure we didn't already do this */ if (!CmpAllocInited) { /* Setup the lock and list */ KeInitializeGuardedMutex(&CmpAllocBucketLock); InitializeListHead(&CmpFreeKCBListHead); CmpAllocInited = TRUE; } }
VOID NTAPI PopInitShutdownList(VOID) { PAGED_CODE(); /* Initialize the global shutdown event */ KeInitializeEvent(&PopShutdownEvent, NotificationEvent, FALSE); /* Initialize the shutdown lists */ PopShutdownThreadList = NULL; InitializeListHead(&PopShutdownQueue); /* Initialize the shutdown list lock */ KeInitializeGuardedMutex(&PopShutdownListMutex); /* The list is available now */ PopShutdownListAvailable = TRUE; }
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; }
/* * @implemented */ VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType) { Mcb->GuardedMutex = ExAllocateFromNPagedLookasideList(&FsRtlFastMutexLookasideList); KeInitializeGuardedMutex(Mcb->GuardedMutex); _SEH2_TRY { FsRtlInitializeBaseMcb(&(Mcb->BaseMcb), PoolType); } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { ExFreeToNPagedLookasideList(&FsRtlFastMutexLookasideList, Mcb->GuardedMutex); Mcb->GuardedMutex = NULL; } _SEH2_END; }
NTSTATUS NTAPI CmpInitializeHive(OUT PCMHIVE *RegistryHive, IN ULONG OperationType, IN ULONG HiveFlags, IN ULONG FileType, IN PVOID HiveData OPTIONAL, IN HANDLE Primary, IN HANDLE Log, IN HANDLE External, IN PCUNICODE_STRING FileName OPTIONAL, IN ULONG CheckFlags) { PCMHIVE Hive; FILE_STANDARD_INFORMATION FileInformation; IO_STATUS_BLOCK IoStatusBlock; FILE_FS_SIZE_INFORMATION FileSizeInformation; NTSTATUS Status; ULONG Cluster; /* Assume failure */ *RegistryHive = NULL; /* * The following are invalid: * An external hive that is also internal. * A log hive that's not a primary hive too. * A volatile hive that's linked to permanent storage. * An in-memory initialization without hive data. * A log hive that's not linked to a correct file type. */ if (((External) && ((Primary) || (Log))) || ((Log) && !(Primary)) || ((HiveFlags & HIVE_VOLATILE) && ((Primary) || (External) || (Log))) || ((OperationType == HINIT_MEMORY) && (!HiveData)) || ((Log) && (FileType != HFILE_TYPE_LOG))) { /* Fail the request */ return STATUS_INVALID_PARAMETER; } /* Check if this is a primary hive */ if (Primary) { /* Get the cluster size */ Status = ZwQueryVolumeInformationFile(Primary, &IoStatusBlock, &FileSizeInformation, sizeof(FILE_FS_SIZE_INFORMATION), FileFsSizeInformation); if (!NT_SUCCESS(Status)) return Status; /* Make sure it's not larger then the block size */ if (FileSizeInformation.BytesPerSector > HBLOCK_SIZE) { /* Fail */ return STATUS_REGISTRY_IO_FAILED; } /* Otherwise, calculate the cluster */ Cluster = FileSizeInformation.BytesPerSector / HSECTOR_SIZE; Cluster = max(1, Cluster); } else { /* Otherwise use cluster 1 */ Cluster = 1; } /* Allocate the hive */ Hive = ExAllocatePoolWithTag(NonPagedPool, sizeof(CMHIVE), TAG_CMHIVE); if (!Hive) return STATUS_INSUFFICIENT_RESOURCES; /* Setup null fields */ Hive->UnloadEvent = NULL; Hive->RootKcb = NULL; Hive->Frozen = FALSE; Hive->UnloadWorkItem = NULL; Hive->GrowOnlyMode = FALSE; Hive->GrowOffset = 0; Hive->CellRemapArray = NULL; Hive->UseCountLog.Next = 0; Hive->LockHiveLog.Next = 0; Hive->FileObject = NULL; Hive->NotifyList.Flink = NULL; Hive->NotifyList.Blink = NULL; /* Set loading flag */ Hive->HiveIsLoading = TRUE; /* Set the current thread as creator */ Hive->CreatorOwner = KeGetCurrentThread(); /* Initialize lists */ InitializeListHead(&Hive->KcbConvertListHead); InitializeListHead(&Hive->KnodeConvertListHead); InitializeListHead(&Hive->TrustClassEntry); /* Allocate the view log */ Hive->ViewLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(KGUARDED_MUTEX), TAG_CMHIVE); if (!Hive->ViewLock) { /* Cleanup allocation and fail */ ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate the flush lock */ Hive->FlusherLock = ExAllocatePoolWithTag(NonPagedPool, sizeof(ERESOURCE), TAG_CMHIVE); if (!Hive->FlusherLock) { /* Cleanup allocations and fail */ ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_INSUFFICIENT_RESOURCES; } /* Setup the handles */ Hive->FileHandles[HFILE_TYPE_PRIMARY] = Primary; Hive->FileHandles[HFILE_TYPE_LOG] = Log; Hive->FileHandles[HFILE_TYPE_EXTERNAL] = External; /* Initailize the guarded mutex */ KeInitializeGuardedMutex(Hive->ViewLock); Hive->ViewLockOwner = NULL; /* Initialize the flush lock */ ExInitializeResourceLite(Hive->FlusherLock); /* Setup hive locks */ ExInitializePushLock(&Hive->HiveLock); Hive->HiveLockOwner = NULL; ExInitializePushLock(&Hive->WriterLock); Hive->WriterLockOwner = NULL; ExInitializePushLock(&Hive->SecurityLock); Hive->HiveSecurityLockOwner = NULL; /* Clear file names */ RtlInitEmptyUnicodeString(&Hive->FileUserName, NULL, 0); RtlInitEmptyUnicodeString(&Hive->FileFullPath, NULL, 0); /* Initialize the view list */ CmpInitHiveViewList(Hive); /* Initailize the security cache */ CmpInitSecurityCache(Hive); /* Setup flags */ Hive->Flags = 0; Hive->FlushCount = 0; /* Set flags */ Hive->Flags = HiveFlags; /* Check if this is a primary */ if (Primary) { /* Check how large the file is */ ZwQueryInformationFile(Primary, &IoStatusBlock, &FileInformation, sizeof(FileInformation), FileStandardInformation); Cluster = FileInformation.EndOfFile.LowPart; } /* Initialize it */ Status = HvInitialize(&Hive->Hive, OperationType, FileType, HiveFlags, HiveData, CmpAllocate, CmpFree, CmpFileSetSize, CmpFileWrite, CmpFileRead, CmpFileFlush, Cluster, FileName); if (!NT_SUCCESS(Status)) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE); ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return Status; } /* Check if we should verify the registry */ if ((OperationType == HINIT_FILE) || (OperationType == HINIT_MEMORY) || (OperationType == HINIT_MEMORY_INPLACE) || (OperationType == HINIT_MAPFILE)) { /* Verify integrity */ ULONG CheckStatus = CmCheckRegistry(Hive, CheckFlags); if (CheckStatus != 0) { /* Cleanup allocations and fail */ ExDeleteResourceLite(Hive->FlusherLock); ExFreePoolWithTag(Hive->FlusherLock, TAG_CMHIVE); ExFreePoolWithTag(Hive->ViewLock, TAG_CMHIVE); ExFreePoolWithTag(Hive, TAG_CMHIVE); return STATUS_REGISTRY_CORRUPT; } } /* Lock the hive list */ ExAcquirePushLockExclusive(&CmpHiveListHeadLock); /* Insert this hive */ InsertHeadList(&CmpHiveListHead, &Hive->HiveList); /* Release the lock */ ExReleasePushLock(&CmpHiveListHeadLock); /* Return the hive and success */ *RegistryHive = (PCMHIVE)Hive; return STATUS_SUCCESS; }
BOOLEAN NTAPI INIT_FUNCTION PoInitSystem(IN ULONG BootPhase) { PVOID NotificationEntry; PCHAR CommandLine; BOOLEAN ForceAcpiDisable = FALSE; /* Check if this is phase 1 init */ if (BootPhase == 1) { /* Register power button notification */ IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVICE_SYS_BUTTON, IopRootDeviceNode-> PhysicalDeviceObject->DriverObject, PopAddRemoveSysCapsCallback, NULL, &NotificationEntry); /* Register lid notification */ IoRegisterPlugPlayNotification(EventCategoryDeviceInterfaceChange, PNPNOTIFY_DEVICE_INTERFACE_INCLUDE_EXISTING_INTERFACES, (PVOID)&GUID_DEVICE_LID, IopRootDeviceNode-> PhysicalDeviceObject->DriverObject, PopAddRemoveSysCapsCallback, NULL, &NotificationEntry); return TRUE; } /* Get the Command Line */ CommandLine = KeLoaderBlock->LoadOptions; /* Upcase it */ _strupr(CommandLine); /* Check for ACPI disable */ if (strstr(CommandLine, "NOACPI")) ForceAcpiDisable = TRUE; if (ForceAcpiDisable) { /* Set the ACPI State to False if it's been forced that way */ PopAcpiPresent = FALSE; } else { /* Otherwise check if the LoaderBlock has a ACPI Table */ PopAcpiPresent = KeLoaderBlock->Extension->AcpiTable != NULL ? TRUE : FALSE; } /* Initialize volume support */ InitializeListHead(&PopVolumeDevices); KeInitializeGuardedMutex(&PopVolumeLock); /* Initialize support for dope */ KeInitializeSpinLock(&PopDopeGlobalLock); /* Initialize support for shutdown waits and work-items */ PopInitShutdownList(); return TRUE; }
BOOLEAN NTAPI INIT_FUNCTION MmInitSystem(IN ULONG Phase, IN PLOADER_PARAMETER_BLOCK LoaderBlock) { extern MMPTE ValidKernelPte; PMMPTE PointerPte; MMPTE TempPte = ValidKernelPte; PFN_NUMBER PageFrameNumber; /* Initialize the kernel address space */ ASSERT(Phase == 1); KeInitializeGuardedMutex(&PsIdleProcess->AddressCreationLock); MmKernelAddressSpace = &PsIdleProcess->Vm; /* Intialize system memory areas */ MiInitSystemMemoryAreas(); /* Dump the address space */ MiDbgDumpAddressSpace(); MmInitGlobalKernelPageDirectory(); MiInitializeUserPfnBitmap(); MmInitializeMemoryConsumer(MC_USER, MmTrimUserMemory); MmInitializeRmapList(); MmInitializePageOp(); MmInitSectionImplementation(); MmInitPagingFile(); // // Create a PTE to double-map the shared data section. We allocate it // from paged pool so that we can't fault when trying to touch the PTE // itself (to map it), since paged pool addresses will already be mapped // by the fault handler. // MmSharedUserDataPte = ExAllocatePoolWithTag(PagedPool, sizeof(MMPTE), ' mM'); if (!MmSharedUserDataPte) return FALSE; // // Now get the PTE for shared data, and read the PFN that holds it // PointerPte = MiAddressToPte((PVOID)KI_USER_SHARED_DATA); ASSERT(PointerPte->u.Hard.Valid == 1); PageFrameNumber = PFN_FROM_PTE(PointerPte); /* Build the PTE and write it */ MI_MAKE_HARDWARE_PTE_KERNEL(&TempPte, PointerPte, MM_READONLY, PageFrameNumber); *MmSharedUserDataPte = TempPte; /* Setup the memory threshold events */ if (!MiInitializeMemoryEvents()) return FALSE; /* * Unmap low memory */ MiInitBalancerThread(); /* * Initialise the modified page writer. */ MmInitMpwThread(); /* Initialize the balance set manager */ MmInitBsmThread(); return TRUE; }
NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status = STATUS_SUCCESS; PDEVICE_OBJECT deviceObject = NULL; UNICODE_STRING deviceName; UNICODE_STRING deviceLink; UNREFERENCED_PARAMETER( RegistryPath ); // Get OS Dependant offsets status = BBInitDynamicData( &dynData ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: Unsupported OS version. Aborting\n", __FUNCTION__ ); return status; } // Initialize some loader structures status = BBInitLdrData( (PKLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection ); if (!NT_SUCCESS( status )) return status; // // Globals init // InitializeListHead( &g_PhysProcesses ); RtlInitializeGenericTableAvl( &g_ProcessPageTables, &AvlCompare, &AvlAllocate, &AvlFree, NULL ); KeInitializeGuardedMutex( &g_globalLock ); // Setup process termination notifier status = PsSetCreateProcessNotifyRoutine( BBProcessNotify, FALSE ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: Failed to setup notify routine with staus 0x%X\n", __FUNCTION__, status ); return status; } RtlUnicodeStringInit( &deviceName, DEVICE_NAME ); status = IoCreateDevice( DriverObject, 0, &deviceName, FILE_DEVICE_BLACKBONE, 0, FALSE, &deviceObject ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: IoCreateDevice failed with status 0x%X\n", __FUNCTION__, status ); return status; } DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BBDispatch; DriverObject->DriverUnload = BBUnload; RtlUnicodeStringInit( &deviceLink, DOS_DEVICE_NAME ); status = IoCreateSymbolicLink( &deviceLink, &deviceName ); if (!NT_SUCCESS( status )) { DPRINT( "BlackBone: %s: IoCreateSymbolicLink failed with status 0x%X\n", __FUNCTION__, status ); IoDeleteDevice (deviceObject); } return status; }
BOOLEAN INIT_FUNCTION NTAPI IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { LARGE_INTEGER ExpireTime; NTSTATUS Status; CHAR Buffer[256]; ANSI_STRING NtBootPath, RootString; /* Initialize empty NT Boot Path */ RtlInitEmptyAnsiString(&NtBootPath, Buffer, sizeof(Buffer)); /* Initialize the lookaside lists */ IopInitLookasideLists(); /* Initialize all locks and lists */ ExInitializeResource(&IopDatabaseResource); ExInitializeResource(&IopSecurityResource); KeInitializeGuardedMutex(&PnpNotifyListLock); InitializeListHead(&IopDiskFileSystemQueueHead); InitializeListHead(&IopCdRomFileSystemQueueHead); InitializeListHead(&IopTapeFileSystemQueueHead); InitializeListHead(&IopNetworkFileSystemQueueHead); InitializeListHead(&DriverBootReinitListHead); InitializeListHead(&DriverReinitListHead); InitializeListHead(&PnpNotifyListHead); InitializeListHead(&ShutdownListHead); InitializeListHead(&LastChanceShutdownListHead); InitializeListHead(&IopFsNotifyChangeQueueHead); InitializeListHead(&IopErrorLogListHead); KeInitializeSpinLock(&IoStatisticsLock); KeInitializeSpinLock(&DriverReinitListLock); KeInitializeSpinLock(&DriverBootReinitListLock); KeInitializeSpinLock(&ShutdownListLock); KeInitializeSpinLock(&IopLogListLock); /* Initialize Timer List Lock */ KeInitializeSpinLock(&IopTimerLock); /* Initialize Timer List */ InitializeListHead(&IopTimerQueueHead); /* Initialize the DPC/Timer which will call the other Timer Routines */ ExpireTime.QuadPart = -10000000; KeInitializeDpc(&IopTimerDpc, IopTimerDispatch, NULL); KeInitializeTimerEx(&IopTimer, SynchronizationTimer); KeSetTimerEx(&IopTimer, ExpireTime, 1000, &IopTimerDpc); /* Create Object Types */ if (!IopCreateObjectTypes()) { DPRINT1("IopCreateObjectTypes failed!\n"); return FALSE; } /* Create Object Directories */ if (!IopCreateRootDirectories()) { DPRINT1("IopCreateRootDirectories failed!\n"); return FALSE; } /* Initialize PnP manager */ IopInitializePlugPlayServices(); /* Initialize HAL Root Bus Driver */ HalInitPnpDriver(); /* Make loader block available for the whole kernel */ IopLoaderBlock = LoaderBlock; /* Load boot start drivers */ IopInitializeBootDrivers(); /* Call back drivers that asked for */ IopReinitializeBootDrivers(); /* Check if this was a ramdisk boot */ if (!_strnicmp(LoaderBlock->ArcBootDeviceName, "ramdisk(0)", 10)) { /* Initialize the ramdisk driver */ IopStartRamdisk(LoaderBlock); } /* No one should need loader block any longer */ IopLoaderBlock = NULL; /* Create ARC names for boot devices */ Status = IopCreateArcNames(LoaderBlock); if (!NT_SUCCESS(Status)) { DPRINT1("IopCreateArcNames failed: %lx\n", Status); return FALSE; } /* Mark the system boot partition */ if (!IopMarkBootPartition(LoaderBlock)) { DPRINT1("IopMarkBootPartition failed!\n"); return FALSE; } /* Initialize PnP root relations */ IopEnumerateDevice(IopRootDeviceNode->PhysicalDeviceObject); #ifndef _WINKD_ /* Read KDB Data */ KdbInit(); /* I/O is now setup for disk access, so phase 3 */ KdInitSystem(3, LoaderBlock); #endif /* Load services for devices found by PnP manager */ IopInitializePnpServices(IopRootDeviceNode); /* Load system start drivers */ IopInitializeSystemDrivers(); PnpSystemInit = TRUE; /* Reinitialize drivers that requested it */ IopReinitializeDrivers(); /* Convert SystemRoot from ARC to NT path */ Status = IopReassignSystemRoot(LoaderBlock, &NtBootPath); if (!NT_SUCCESS(Status)) { DPRINT1("IopReassignSystemRoot failed: %lx\n", Status); return FALSE; } /* Set the ANSI_STRING for the root path */ RootString.MaximumLength = NtSystemRoot.MaximumLength / sizeof(WCHAR); RootString.Length = 0; RootString.Buffer = ExAllocatePoolWithTag(PagedPool, RootString.MaximumLength, TAG_IO); /* Convert the path into the ANSI_STRING */ Status = RtlUnicodeStringToAnsiString(&RootString, &NtSystemRoot, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlUnicodeStringToAnsiString failed: %lx\n", Status); return FALSE; } /* Assign drive letters */ IoAssignDriveLetters(LoaderBlock, &NtBootPath, (PUCHAR)RootString.Buffer, &RootString); /* Update system root */ Status = RtlAnsiStringToUnicodeString(&NtSystemRoot, &RootString, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("RtlAnsiStringToUnicodeString failed: %lx\n", Status); return FALSE; } /* Load the System DLL and its Entrypoints */ Status = PsLocateSystemDll(); if (!NT_SUCCESS(Status)) { DPRINT1("PsLocateSystemDll failed: %lx\n", Status); return FALSE; } /* Return 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; }
NTSTATUS DriverEntry ( _In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath ) { NTSTATUS Status; UNICODE_STRING NtDeviceName = RTL_CONSTANT_STRING (TD_NT_DEVICE_NAME); UNICODE_STRING DosDevicesLinkName = RTL_CONSTANT_STRING (TD_DOS_DEVICES_LINK_NAME); PDEVICE_OBJECT Device = NULL; BOOLEAN SymLinkCreated = FALSE; USHORT CallbackVersion; UNREFERENCED_PARAMETER (RegistryPath); DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ObCallbackTest: DriverEntry: Driver loaded. Use ed nt!Kd_IHVDRIVER_Mask f (or 7) to enable more traces\n"); CallbackVersion = ObGetFilterVersion(); DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_INFO_LEVEL, "ObCallbackTest: DriverEntry: Callback version 0x%hx\n", CallbackVersion); // // Initialize globals. // KeInitializeGuardedMutex (&TdCallbacksMutex); // // Create our device object. // Status = IoCreateDevice ( DriverObject, // pointer to driver object 0, // device extension size &NtDeviceName, // device name FILE_DEVICE_UNKNOWN, // device type 0, // device characteristics FALSE, // not exclusive &Device); // returned device object pointer if (! NT_SUCCESS(Status)) { goto Exit; } TD_ASSERT (Device == DriverObject->DeviceObject); // // Set dispatch routines. // DriverObject->MajorFunction[IRP_MJ_CREATE] = TdDeviceCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = TdDeviceClose; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = TdDeviceCleanup; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = TdDeviceControl; DriverObject->DriverUnload = TdDeviceUnload; // // Create a link in the Win32 namespace. // Status = IoCreateSymbolicLink (&DosDevicesLinkName, &NtDeviceName); if (! NT_SUCCESS(Status)) { goto Exit; } SymLinkCreated = TRUE; // // Set process create routines. // Status = PsSetCreateProcessNotifyRoutineEx ( TdCreateProcessNotifyRoutine2, FALSE ); if (! NT_SUCCESS(Status)) { DbgPrintEx (DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "ObCallbackTest: DriverEntry: PsSetCreateProcessNotifyRoutineEx(2) returned 0x%x\n", Status); goto Exit; } TdProcessNotifyRoutineSet2 = TRUE; Exit: if (!NT_SUCCESS (Status)) { if (TdProcessNotifyRoutineSet2 == TRUE) { Status = PsSetCreateProcessNotifyRoutineEx ( TdCreateProcessNotifyRoutine2, TRUE ); TD_ASSERT (Status == STATUS_SUCCESS); TdProcessNotifyRoutineSet2 = FALSE; } if (SymLinkCreated == TRUE) { IoDeleteSymbolicLink (&DosDevicesLinkName); } if (Device != NULL) { IoDeleteDevice (Device); } } return Status; }