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

ioinit.c File Reference

#include "iop.h"
#include <setupblk.h>
#include <inbv.h>
#include <ntddstor.h>

Go to the source code of this file.

Classes

struct  _TREE_ENTRY
struct  _DRIVER_INFORMATION

Defines

#define DEFAULT_LARGE_IRP_LOCATIONS   8
#define DEFAULT_LOOKASIDE_IRP_LIMIT   512
#define InitializeDriverObject(Object)

Typedefs

typedef _TREE_ENTRY TREE_ENTRY
typedef _TREE_ENTRYPTREE_ENTRY
typedef _DRIVER_INFORMATION DRIVER_INFORMATION
typedef _DRIVER_INFORMATIONPDRIVER_INFORMATION

Functions

VOID IopInitializeData (VOID)
NTSTATUS RawInitialize (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
BOOLEAN IopCheckDependencies (IN HANDLE KeyHandle)
VOID IopCreateArcNames (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN IopCreateObjectTypes (VOID)
PTREE_ENTRY IopCreateEntry (IN PUNICODE_STRING GroupName)
BOOLEAN IopCreateRootDirectories (VOID)
VOID IopFreeGroupTree (IN PTREE_ENTRY TreeEntry)
NTSTATUS IopInitializeAttributesAndCreateObject (IN PUNICODE_STRING ObjectName, IN OUT POBJECT_ATTRIBUTES ObjectAttributes, OUT PDRIVER_OBJECT *DriverObject)
BOOLEAN IopInitializeBootDrivers (IN PLOADER_PARAMETER_BLOCK LoaderBlock, OUT PDRIVER_OBJECT *PreviousDriver)
PDRIVER_OBJECT IopInitializeBuiltinDriver (IN PUNICODE_STRING DriverName, IN PUNICODE_STRING RegistryPath, IN PDRIVER_INITIALIZE DriverInitializeRoutine, IN PLDR_DATA_TABLE_ENTRY TableEntry, IN BOOLEAN TextModeSetup)
BOOLEAN IopInitializeSingleBootDriver (IN HANDLE KeyHandle, IN PBOOT_DRIVER_LIST_ENTRY BootDriver, OUT PUNICODE_STRING DriverName OPTIONAL)
BOOLEAN IopInitializeSystemDrivers (VOID)
PTREE_ENTRY IopLookupGroupName (IN PUNICODE_STRING GroupName, IN BOOLEAN Insert)
BOOLEAN IopMarkBootPartition (IN PLOADER_PARAMETER_BLOCK LoaderBlock)
BOOLEAN IopReassignSystemRoot (IN PLOADER_PARAMETER_BLOCK LoaderBlock, OUT PSTRING NtDeviceName)
VOID IopStoreSystemPartitionInformation (IN PUNICODE_STRING NtSystemPartitionDeviceName, IN OUT PUNICODE_STRING OsLoaderPathName)
USHORT IopGetDriverTagPriority (IN HANDLE Servicehandle)
VOID IopInsertDriverList (IN PLIST_ENTRY ListHead, IN PDRIVER_INFORMATION DriverInfo)
VOID IopNotifySetupDevices (PDEVICE_NODE DeviceNode)
BOOLEAN IopWaitForBootDevicesStarted (IN VOID)
BOOLEAN IopWaitForBootDevicesDeleted (IN VOID)
VOID IopSetIoRoutines (IN VOID)
BOOLEAN IoInitSystem (PLOADER_PARAMETER_BLOCK LoaderBlock)
VOID IopSetIoRoutines ()
VOID IopFreeGroupTree (PTREE_ENTRY TreeEntry)
NTSTATUS IopLogErrorEvent (IN ULONG SequenceNumber, IN ULONG UniqueErrorValue, IN NTSTATUS FinalStatus, IN NTSTATUS SpecificIOStatus, IN ULONG LengthOfInsert1, IN PWCHAR Insert1, IN ULONG LengthOfInsert2, IN PWCHAR Insert2)
PDRIVER_OBJECT IopLoadBootFilterDriver (IN PUNICODE_STRING DriverName, IN ULONG GroupIndex)

Variables

PTREE_ENTRY IopGroupListHead
PVOID IopErrorLogObject = NULL
ULONG IopGroupIndex
PLIST_ENTRY IopGroupTable
GENERIC_MAPPING IopFileMapping
GENERIC_MAPPING IopCompletionMapping


Define Documentation

#define DEFAULT_LARGE_IRP_LOCATIONS   8
 

Definition at line 37 of file ioinit.c.

Referenced by IoInitSystem().

#define DEFAULT_LOOKASIDE_IRP_LIMIT   512
 

Definition at line 44 of file ioinit.c.

Referenced by IoInitSystem().

#define InitializeDriverObject Object   ) 
 

Value:

{ \ ULONG i; \ RtlZeroMemory( Object, \ sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )); \ Object->DriverExtension = (PDRIVER_EXTENSION) (Object + 1); \ Object->DriverExtension->DriverObject = Object; \ for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) \ Object->MajorFunction[i] = IopInvalidDeviceRequest; \ Object->Type = IO_TYPE_DRIVER; \ Object->Size = sizeof( DRIVER_OBJECT ); \ }

Definition at line 88 of file ioinit.c.

Referenced by IopInitializeBuiltinDriver().


Typedef Documentation

typedef struct _DRIVER_INFORMATION DRIVER_INFORMATION
 

Referenced by IopInitializeBootDrivers().

typedef struct _DRIVER_INFORMATION * PDRIVER_INFORMATION
 

Referenced by IopInitializeBootDrivers(), IopInsertDriverList(), and IopLoadBootFilterDriver().

typedef struct _TREE_ENTRY * PTREE_ENTRY
 

Referenced by IopCheckDependencies(), IopCreateEntry(), IopInitializeBootDrivers(), IopInitializeSystemDrivers(), and IopLookupGroupName().

typedef struct _TREE_ENTRY TREE_ENTRY
 

Referenced by IopCreateEntry().


Function Documentation

BOOLEAN IoInitSystem PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 270 of file ioinit.c.

References ASSERT, _DEVICE_NODE::Child, CmRegistryMachineSystemCurrentControlSetServicesEventLog, _REINIT_PACKET::Context, _DRIVER_EXTENSION::Count, DbgPrint, DEFAULT_LARGE_IRP_LOCATIONS, DEFAULT_LOOKASIDE_IRP_LIMIT, DNF_HAL_NODE, DNF_LEGACY_DRIVER, DNF_STARTED, _DRIVER_OBJECT::DriverExtension, _REINIT_PACKET::DriverObject, _REINIT_PACKET::DriverReinitializationRoutine, DRVO_REINIT_REGISTERED, _LINK_TRACKING_PACKET::Event, ExAllocatePoolWithTag, ExEventObjectType, ExFreePool(), ExInitializeNPagedLookasideList(), ExInitializeResource, ExInitializeWorkItem, ExInterlockedRemoveHeadList(), _IOP_HARD_ERROR_QUEUE::ExWorkItem, FALSE, _DRIVER_OBJECT::Flags, _DEVICE_NODE::Flags, HalInitPnpDriver, Index, IoAssignDriveLetters(), IOP_FIXED_SIZE_MDL_PFNS, IOP_MINI_COMPLETION_PACKET, IopAddRemoteBootValuesToRegistry(), IopBootDriverReinitializeQueueHead, IopCancelSpinLock, IopCdRomFileSystemQueueHead, IopCompletionLock, IopCompletionLookasideList, IopCreateObjectTypes(), IopCreateRootDirectories(), IopCurrentHardError, IopDatabaseLock, IopDatabaseResource, IopDiskFileSystemQueueHead, IopDriverReinitializeQueueHead, IopErrorLogAllocationLock, IopErrorLogDisabledThisBoot, IopErrorLogListHead, IopErrorLogLock, IopFreeGroupTree(), IopFsNotifyChangeQueueHead, IopGroupListHead, IopHardError, IopHardErrorThread(), IopInitHalDeviceNode, IopInitializeBootDrivers(), IopInitializePlugPlayServices(), IopInitializeResourceMap(), IopInitializeSystemDrivers(), IopLargeIrpLookasideList, IopLargeIrpStackLocations, IopLinkTrackingPacket, IopLinkTrackingPortObject, IopLinkTrackingServiceEvent, IopLoaderBlock, IopLookasideIrpLimit, IopMdlLookasideList, IopNetworkFileSystemQueueHead, IopNotifyLastChanceShutdownQueueHead, IopNotifyShutdownQueueHead, IopProfileChangeSemaphore, IopProtectSystemPartition(), IopQueryFsOperationAccess, IopQueryFsOperationLength, IopQueryOperationAccess, IopQueryOperationLength, IopReassignSystemRoot(), IopRegistrySemaphore, IopRootDeviceNode, IopSecurityResource, IopSetFsOperationAccess, IopSetFsOperationLength, IopSetIoRoutines(), IopSetOperationAccess, IopSetOperationLength, IopSmallIrpLookasideList, IopStartNetworkForRemoteBoot(), IopTapeFileSystemQueueHead, IopTimer, IopTimerDispatch(), IopTimerDpc, IopTimerLock, IopTimerQueueHead, IopUniqueDeviceObjectNumber, IopVpbSpinLock, IoRemoteBootClient, IoStatisticsLock, KeBugCheckEx(), KeInitializeDpc(), KeInitializeEvent, KeInitializeSemaphore(), KeInitializeSpinLock(), KeInitializeTimerEx(), KeNumberProcessors, KernelMode, KeSetTimerEx(), KiProcessorBlock, L, _NPAGED_LOOKASIDE_LIST::L, LookasideCompletionList, LookasideLargeIrpList, LookasideMdlList, LookasideSmallIrpList, MM_SYSTEMSIZE, MmIsThisAnNtAsSystem(), MmLargeSystem, MmMediumSystem, MmQuerySystemSize(), MmSmallSystem, NonPagedPool, NPAGED_LOOKASIDE_LIST, NT_SUCCESS, NtCreateEvent(), NtGlobalFlag, NtQueryValueKey(), NTSTATUS(), NtSystemRoot, NULL, ObReferenceObjectByHandle(), PoInitDriverServices(), PsLocateSystemDll(), RtlAllocateStringRoutine, RtlAnsiStringToUnicodeString(), RtlInitUnicodeString(), RtlUnicodeStringToAnsiString(), _DEVICE_NODE::Sibling, _IOP_HARD_ERROR_QUEUE::ThreadStarted, TRUE, USHORT, VOID(), WMIInitialize(), _IOP_HARD_ERROR_QUEUE::WorkQueue, _IOP_HARD_ERROR_QUEUE::WorkQueueSemaphore, and _IOP_HARD_ERROR_QUEUE::WorkQueueSpinLock.

00276 : 00277 00278 This routine initializes the I/O system. 00279 00280 Arguments: 00281 00282 LoaderBlock - Supplies a pointer to the loader parameter block that was 00283 created by the OS Loader. 00284 00285 Return Value: 00286 00287 The function value is a BOOLEAN indicating whether or not the I/O system 00288 was successfully initialized. 00289 00290 --*/ 00291 00292 { 00293 PDRIVER_OBJECT driverObject; 00294 PDRIVER_OBJECT *nextDriverObject; 00295 STRING ntDeviceName; 00296 UCHAR deviceNameBuffer[256]; 00297 ULONG largePacketSize; 00298 ULONG smallPacketSize; 00299 ULONG mdlPacketSize; 00300 ULONG numberOfPackets; 00301 ULONG poolSize; 00302 PLIST_ENTRY entry; 00303 PREINIT_PACKET reinitEntry; 00304 LARGE_INTEGER deltaTime; 00305 MM_SYSTEMSIZE systemSize; 00306 USHORT completionZoneSize; 00307 USHORT largeIrpZoneSize; 00308 USHORT smallIrpZoneSize; 00309 USHORT mdlZoneSize; 00310 ULONG oldNtGlobalFlag; 00311 NTSTATUS status; 00312 ANSI_STRING ansiString; 00313 UNICODE_STRING eventName; 00314 UNICODE_STRING startTypeName; 00315 OBJECT_ATTRIBUTES objectAttributes; 00316 HANDLE handle; 00317 PDEVICE_NODE deviceNode; 00318 PNPAGED_LOOKASIDE_LIST lookaside; 00319 ULONG Index; 00320 PKPRCB prcb; 00321 ULONG len; 00322 PKEY_VALUE_PARTIAL_INFORMATION value; 00323 UCHAR valueBuffer[32]; 00324 00325 ASSERT( IopQueryOperationLength[FileMaximumInformation] == 0xff ); 00326 ASSERT( IopSetOperationLength[FileMaximumInformation] == 0xff ); 00327 ASSERT( IopQueryOperationAccess[FileMaximumInformation] == 0xffffffff ); 00328 ASSERT( IopSetOperationAccess[FileMaximumInformation] == 0xffffffff ); 00329 00330 ASSERT( IopQueryFsOperationLength[FileFsMaximumInformation] == 0xff ); 00331 ASSERT( IopSetFsOperationLength[FileFsMaximumInformation] == 0xff ); 00332 ASSERT( IopQueryFsOperationAccess[FileFsMaximumInformation] == 0xffffffff ); 00333 ASSERT( IopSetFsOperationAccess[FileFsMaximumInformation] == 0xffffffff ); 00334 00335 // 00336 // Initialize the I/O database resource, lock, and the file system and 00337 // network file system queue headers. Also allocate the cancel spin 00338 // lock. 00339 // 00340 00341 ntDeviceName.Buffer = deviceNameBuffer; 00342 ntDeviceName.MaximumLength = sizeof(deviceNameBuffer); 00343 ntDeviceName.Length = 0; 00344 00345 ExInitializeResource( &IopDatabaseResource ); 00346 ExInitializeResource( &IopSecurityResource ); 00347 KeInitializeSpinLock( &IopDatabaseLock ); 00348 InitializeListHead( &IopDiskFileSystemQueueHead ); 00349 InitializeListHead( &IopCdRomFileSystemQueueHead ); 00350 InitializeListHead( &IopTapeFileSystemQueueHead ); 00351 InitializeListHead( &IopNetworkFileSystemQueueHead ); 00352 InitializeListHead( &IopBootDriverReinitializeQueueHead ); 00353 InitializeListHead( &IopDriverReinitializeQueueHead ); 00354 InitializeListHead( &IopNotifyShutdownQueueHead ); 00355 InitializeListHead( &IopNotifyLastChanceShutdownQueueHead ); 00356 InitializeListHead( &IopFsNotifyChangeQueueHead ); 00357 KeInitializeSpinLock( &IopCancelSpinLock ); 00358 KeInitializeSpinLock( &IopVpbSpinLock ); 00359 KeInitializeSpinLock( &IoStatisticsLock ); 00360 00361 IopSetIoRoutines(); 00362 // 00363 // Initialize the unique device object number counter used by IoCreateDevice 00364 // when automatically generating a device object name. 00365 // 00366 IopUniqueDeviceObjectNumber = 0; 00367 00368 // 00369 // Initialize the large I/O Request Packet (IRP) lookaside list head and the 00370 // mutex which guards the list. 00371 // 00372 00373 if (!IopLargeIrpStackLocations) { 00374 IopLargeIrpStackLocations = DEFAULT_LARGE_IRP_LOCATIONS; 00375 } 00376 00377 systemSize = MmQuerySystemSize(); 00378 00379 switch ( systemSize ) { 00380 00381 case MmSmallSystem : 00382 completionZoneSize = 6; 00383 smallIrpZoneSize = 6; 00384 largeIrpZoneSize = 8; 00385 mdlZoneSize = 16; 00386 IopLookasideIrpLimit = DEFAULT_LOOKASIDE_IRP_LIMIT; 00387 break; 00388 00389 case MmMediumSystem : 00390 completionZoneSize = 24; 00391 smallIrpZoneSize = 24; 00392 largeIrpZoneSize = 32; 00393 mdlZoneSize = 90; 00394 IopLookasideIrpLimit = DEFAULT_LOOKASIDE_IRP_LIMIT * 2; 00395 break; 00396 00397 case MmLargeSystem : 00398 if (MmIsThisAnNtAsSystem()) { 00399 completionZoneSize = 96; 00400 smallIrpZoneSize = 96; 00401 largeIrpZoneSize = 128; 00402 mdlZoneSize = 256; 00403 IopLookasideIrpLimit = DEFAULT_LOOKASIDE_IRP_LIMIT * 4; 00404 00405 } else { 00406 completionZoneSize = 32; 00407 smallIrpZoneSize = 32; 00408 largeIrpZoneSize = 64; 00409 mdlZoneSize = 128; 00410 IopLookasideIrpLimit = DEFAULT_LOOKASIDE_IRP_LIMIT * 3; 00411 } 00412 00413 break; 00414 } 00415 00416 // 00417 // Initialize the system I/O completion lookaside list. 00418 // 00419 00420 ExInitializeNPagedLookasideList( &IopCompletionLookasideList, 00421 NULL, 00422 NULL, 00423 0, 00424 sizeof(IOP_MINI_COMPLETION_PACKET), 00425 ' pcI', 00426 completionZoneSize ); 00427 00428 // 00429 // Initialize the system large IRP lookaside list. 00430 // 00431 00432 largePacketSize = (ULONG) (sizeof( IRP ) + (IopLargeIrpStackLocations * sizeof( IO_STACK_LOCATION ))); 00433 ExInitializeNPagedLookasideList( &IopLargeIrpLookasideList, 00434 NULL, 00435 NULL, 00436 0, 00437 largePacketSize, 00438 'lprI', 00439 largeIrpZoneSize ); 00440 00441 // 00442 // Initialize the system small IRP lookaside list. 00443 // 00444 00445 smallPacketSize = (ULONG) (sizeof( IRP ) + sizeof( IO_STACK_LOCATION )); 00446 ExInitializeNPagedLookasideList( &IopSmallIrpLookasideList, 00447 NULL, 00448 NULL, 00449 0, 00450 smallPacketSize, 00451 'sprI', 00452 smallIrpZoneSize ); 00453 00454 // 00455 // Initialize the system MDL lookaside list. 00456 // 00457 00458 mdlPacketSize = (ULONG) (sizeof( MDL ) + (IOP_FIXED_SIZE_MDL_PFNS * sizeof( PFN_NUMBER ))); 00459 ExInitializeNPagedLookasideList( &IopMdlLookasideList, 00460 NULL, 00461 NULL, 00462 0, 00463 mdlPacketSize, 00464 ' ldM', 00465 mdlZoneSize ); 00466 00467 // 00468 // Initialize the per processor nonpaged lookaside lists and descriptors. 00469 // 00470 00471 for (Index = 0; Index < (ULONG)KeNumberProcessors; Index += 1) { 00472 prcb = KiProcessorBlock[Index]; 00473 00474 // 00475 // Initialize the I/O completion per processor lookaside pointers 00476 // 00477 00478 prcb->PPLookasideList[LookasideCompletionList].L = &IopCompletionLookasideList; 00479 lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00480 sizeof(NPAGED_LOOKASIDE_LIST), 00481 'PpcI'); 00482 00483 if (lookaside != NULL) { 00484 ExInitializeNPagedLookasideList( lookaside, 00485 NULL, 00486 NULL, 00487 0, 00488 sizeof(IOP_MINI_COMPLETION_PACKET), 00489 'PpcI', 00490 completionZoneSize ); 00491 00492 } else { 00493 lookaside = &IopCompletionLookasideList; 00494 } 00495 00496 prcb->PPLookasideList[LookasideCompletionList].P = lookaside; 00497 00498 // 00499 // Initialize the large IRP per processor lookaside pointers. 00500 // 00501 00502 prcb->PPLookasideList[LookasideLargeIrpList].L = &IopLargeIrpLookasideList; 00503 lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00504 sizeof(NPAGED_LOOKASIDE_LIST), 00505 'LprI'); 00506 00507 if (lookaside != NULL) { 00508 ExInitializeNPagedLookasideList( lookaside, 00509 NULL, 00510 NULL, 00511 0, 00512 largePacketSize, 00513 'LprI', 00514 largeIrpZoneSize ); 00515 00516 } else { 00517 lookaside = &IopLargeIrpLookasideList; 00518 } 00519 00520 prcb->PPLookasideList[LookasideLargeIrpList].P = lookaside; 00521 00522 // 00523 // Initialize the small IRP per processor lookaside pointers. 00524 // 00525 00526 prcb->PPLookasideList[LookasideSmallIrpList].L = &IopSmallIrpLookasideList; 00527 lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00528 sizeof(NPAGED_LOOKASIDE_LIST), 00529 'SprI'); 00530 00531 if (lookaside != NULL) { 00532 ExInitializeNPagedLookasideList( lookaside, 00533 NULL, 00534 NULL, 00535 0, 00536 smallPacketSize, 00537 'SprI', 00538 smallIrpZoneSize); 00539 00540 } else { 00541 lookaside = &IopSmallIrpLookasideList; 00542 } 00543 00544 prcb->PPLookasideList[LookasideSmallIrpList].P = lookaside; 00545 00546 // 00547 // Initialize the MDL per processor lookaside list pointers. 00548 // 00549 00550 prcb->PPLookasideList[LookasideMdlList].L = &IopMdlLookasideList; 00551 lookaside = (PNPAGED_LOOKASIDE_LIST)ExAllocatePoolWithTag( NonPagedPool, 00552 sizeof(NPAGED_LOOKASIDE_LIST), 00553 'PldM'); 00554 00555 if (lookaside != NULL) { 00556 ExInitializeNPagedLookasideList( lookaside, 00557 NULL, 00558 NULL, 00559 0, 00560 mdlPacketSize, 00561 'PldM', 00562 mdlZoneSize ); 00563 00564 } else { 00565 lookaside = &IopMdlLookasideList; 00566 } 00567 00568 prcb->PPLookasideList[LookasideMdlList].P = lookaside; 00569 } 00570 00571 // 00572 // Initialize the I/O completion spin lock. 00573 // 00574 00575 KeInitializeSpinLock( &IopCompletionLock ); 00576 00577 // 00578 // Initalize the error log spin locks and log list. 00579 // 00580 00581 KeInitializeSpinLock( &IopErrorLogLock ); 00582 KeInitializeSpinLock( &IopErrorLogAllocationLock ); 00583 InitializeListHead( &IopErrorLogListHead ); 00584 00585 // 00586 // Determine if the Error Log service will ever run this boot. 00587 // 00588 InitializeObjectAttributes (&objectAttributes, 00589 &CmRegistryMachineSystemCurrentControlSetServicesEventLog, 00590 OBJ_CASE_INSENSITIVE, 00591 (HANDLE) NULL, 00592 (PSECURITY_DESCRIPTOR) NULL ); 00593 00594 status = ZwOpenKey(&handle, 00595 KEY_READ, 00596 &objectAttributes 00597 ); 00598 00599 if (NT_SUCCESS (status)) { 00600 RtlInitUnicodeString (&startTypeName, L"Start"); 00601 value = (PKEY_VALUE_PARTIAL_INFORMATION) valueBuffer; 00602 status = NtQueryValueKey (handle, 00603 &startTypeName, 00604 KeyValuePartialInformation, 00605 valueBuffer, 00606 sizeof (valueBuffer), 00607 &len); 00608 00609 if (NT_SUCCESS (status) && (value->Type == REG_DWORD)) { 00610 if (SERVICE_DISABLED == (*(PULONG) (value->Data))) { 00611 // 00612 // We are disabled for this boot. 00613 // 00614 IopErrorLogDisabledThisBoot = TRUE; 00615 } else { 00616 IopErrorLogDisabledThisBoot = FALSE; 00617 } 00618 } else { 00619 // 00620 // Didn't find the value so we are not enabled. 00621 // 00622 IopErrorLogDisabledThisBoot = TRUE; 00623 } 00624 } else { 00625 // 00626 // Didn't find the key so we are not enabled 00627 // 00628 IopErrorLogDisabledThisBoot = TRUE; 00629 } 00630 00631 // 00632 // Initialize the registry access semaphore. 00633 // 00634 00635 KeInitializeSemaphore( &IopRegistrySemaphore, 1, 1 ); 00636 00637 // 00638 // Initialize the timer database and start the timer DPC routine firing 00639 // so that drivers can use it during initialization. 00640 // 00641 00642 deltaTime.QuadPart = - 10 * 1000 * 1000; 00643 00644 KeInitializeSpinLock( &IopTimerLock ); 00645 InitializeListHead( &IopTimerQueueHead ); 00646 KeInitializeDpc( &IopTimerDpc, IopTimerDispatch, NULL ); 00647 KeInitializeTimerEx( &IopTimer, SynchronizationTimer ); 00648 (VOID) KeSetTimerEx( &IopTimer, deltaTime, 1000, &IopTimerDpc ); 00649 00650 // 00651 // Initialize the IopHardError structure used for informational pop-ups. 00652 // 00653 00654 ExInitializeWorkItem( &IopHardError.ExWorkItem, 00655 IopHardErrorThread, 00656 NULL ); 00657 00658 InitializeListHead( &IopHardError.WorkQueue ); 00659 00660 KeInitializeSpinLock( &IopHardError.WorkQueueSpinLock ); 00661 00662 KeInitializeSemaphore( &IopHardError.WorkQueueSemaphore, 00663 0, 00664 MAXLONG ); 00665 00666 IopHardError.ThreadStarted = FALSE; 00667 00668 IopCurrentHardError = NULL; 00669 00670 // 00671 // Create the link tracking named event. 00672 // 00673 00674 RtlInitUnicodeString( &eventName, L"\\Security\\TRKWKS_EVENT" ); 00675 InitializeObjectAttributes( &objectAttributes, 00676 &eventName, 00677 OBJ_PERMANENT, 00678 (HANDLE) NULL, 00679 (PSECURITY_DESCRIPTOR) NULL ); 00680 status = NtCreateEvent( &handle, 00681 EVENT_ALL_ACCESS, 00682 &objectAttributes, 00683 NotificationEvent, 00684 FALSE ); 00685 if (!NT_SUCCESS( status )) { 00686 #if DBG 00687 DbgPrint( "IOINIT: NtCreateEvent failed\n" ); 00688 #endif 00689 return FALSE; 00690 } 00691 00692 (VOID) ObReferenceObjectByHandle( handle, 00693 0, 00694 ExEventObjectType, 00695 KernelMode, 00696 (PVOID *) &IopLinkTrackingServiceEvent, 00697 NULL ); 00698 00699 KeInitializeEvent( &IopLinkTrackingPacket.Event, NotificationEvent, FALSE ); 00700 KeInitializeEvent(&IopLinkTrackingPortObject, SynchronizationEvent, TRUE ); 00701 00702 KeInitializeSemaphore(&IopProfileChangeSemaphore, 1, 1) ; 00703 00704 // 00705 // Create all of the objects for the I/O system. 00706 // 00707 00708 if (!IopCreateObjectTypes()) { 00709 #if DBG 00710 DbgPrint( "IOINIT: IopCreateObjectTypes failed\n" ); 00711 #endif 00712 return FALSE; 00713 } 00714 00715 // 00716 // Create the root directories for the I/O system. 00717 // 00718 00719 if (!IopCreateRootDirectories()) { 00720 #if DBG 00721 DbgPrint( "IOINIT: IopCreateRootDirectories failed\n" ); 00722 #endif 00723 return FALSE; 00724 } 00725 00726 // 00727 // Initialize the resource map 00728 // 00729 00730 IopInitializeResourceMap (LoaderBlock); 00731 00732 // 00733 // Initialize PlugPlay services phase 0 00734 // 00735 00736 status = IopInitializePlugPlayServices(LoaderBlock, 0); 00737 if (!NT_SUCCESS(status)) { 00738 return FALSE; 00739 } 00740 00741 // 00742 // Call Power manager to initialize for drivers 00743 // 00744 00745 PoInitDriverServices(0); 00746 00747 // 00748 // Call HAL to initialize PnP bus driver 00749 // 00750 00751 HalInitPnpDriver(); 00752 deviceNode = IopRootDeviceNode->Child; 00753 while (deviceNode) { 00754 if ((deviceNode->Flags & DNF_STARTED) && 00755 !(deviceNode->Flags & DNF_LEGACY_DRIVER)) { 00756 IopInitHalDeviceNode = deviceNode; 00757 deviceNode->Flags |= DNF_HAL_NODE; 00758 break; 00759 } 00760 deviceNode = deviceNode->Sibling; 00761 } 00762 00763 // 00764 // Call WMI to initialize it and allow it to create its driver object 00765 // Note that no calls to WMI can occur until it is initialized here. 00766 // 00767 00768 WMIInitialize(); 00769 00770 // 00771 // Save this for use during PnP enumeration -- we NULL it out later 00772 // before LoaderBlock is reused. 00773 // 00774 00775 IopLoaderBlock = (PVOID)LoaderBlock; 00776 00777 // 00778 // If this is a remote boot, we need to add a few values to the registry. 00779 // 00780 00781 if (IoRemoteBootClient) { 00782 status = IopAddRemoteBootValuesToRegistry(LoaderBlock); 00783 if (!NT_SUCCESS(status)) { 00784 KeBugCheckEx( NETWORK_BOOT_INITIALIZATION_FAILED, 00785 1, 00786 status, 00787 0, 00788 0 ); 00789 } 00790 } 00791 00792 // 00793 // Initialize PlugPlay services phase 1 to execute firmware mapper 00794 // 00795 00796 status = IopInitializePlugPlayServices(LoaderBlock, 1); 00797 if (!NT_SUCCESS(status)) { 00798 return FALSE; 00799 } 00800 00801 // 00802 // Initialize the drivers loaded by the boot loader (OSLOADER) 00803 // 00804 00805 nextDriverObject = &driverObject; 00806 if (!IopInitializeBootDrivers( LoaderBlock, 00807 nextDriverObject )) { 00808 #if DBG 00809 DbgPrint( "IOINIT: Initializing boot drivers failed\n" ); 00810 #endif // DBG 00811 return FALSE; 00812 } 00813 00814 // 00815 // Once we have initialized the boot drivers, we don't need the 00816 // copy of the pointer to the loader block any more. 00817 // 00818 00819 IopLoaderBlock = NULL; 00820 00821 // 00822 // If this is a remote boot, start the network and assign 00823 // C: to \Device\LanmanRedirector. 00824 // 00825 00826 if (IoRemoteBootClient) { 00827 status = IopStartNetworkForRemoteBoot(LoaderBlock); 00828 if (!NT_SUCCESS( status )) { 00829 KeBugCheckEx( NETWORK_BOOT_INITIALIZATION_FAILED, 00830 2, 00831 status, 00832 0, 00833 0 ); 00834 } 00835 } 00836 00837 // 00838 // Save the current value of the NT Global Flags and enable kernel debugger 00839 // symbol loading while drivers are being loaded so that systems can be 00840 // debugged regardless of whether they are free or checked builds. 00841 // 00842 00843 oldNtGlobalFlag = NtGlobalFlag; 00844 00845 if (!(NtGlobalFlag & FLG_ENABLE_KDEBUG_SYMBOL_LOAD)) { 00846 NtGlobalFlag |= FLG_ENABLE_KDEBUG_SYMBOL_LOAD; 00847 } 00848 00849 status = PsLocateSystemDll(); 00850 if (!NT_SUCCESS( status )) { 00851 return FALSE; 00852 } 00853 00854 // 00855 // Initialize the device drivers for the system. 00856 // 00857 00858 if (!IopInitializeSystemDrivers()) { 00859 #if DBG 00860 DbgPrint( "IOINIT: Initializing system drivers failed\n" ); 00861 #endif // DBG 00862 return FALSE; 00863 } 00864 00865 // 00866 // Free the memory allocated to contain the group dependency list. 00867 // 00868 00869 if (IopGroupListHead) { 00870 IopFreeGroupTree( IopGroupListHead ); 00871 } 00872 00873 // 00874 // Walk the list of drivers that have requested that they be called again 00875 // for reinitialization purposes. 00876 // 00877 00878 while (entry = ExInterlockedRemoveHeadList( &IopDriverReinitializeQueueHead, &IopDatabaseLock )) { 00879 reinitEntry = CONTAINING_RECORD( entry, REINIT_PACKET, ListEntry ); 00880 reinitEntry->DriverObject->DriverExtension->Count++; 00881 reinitEntry->DriverObject->Flags &= ~DRVO_REINIT_REGISTERED; 00882 reinitEntry->DriverReinitializationRoutine( reinitEntry->DriverObject, 00883 reinitEntry->Context, 00884 reinitEntry->DriverObject->DriverExtension->Count ); 00885 ExFreePool( reinitEntry ); 00886 } 00887 00888 // 00889 // Reassign \SystemRoot to NT device name path. 00890 // 00891 00892 if (!IopReassignSystemRoot( LoaderBlock, &ntDeviceName )) { 00893 return FALSE; 00894 } 00895 00896 // 00897 // Protect the system partition of an ARC system if necessary 00898 // 00899 00900 if (!IopProtectSystemPartition( LoaderBlock )) { 00901 return(FALSE); 00902 } 00903 00904 // 00905 // Assign DOS drive letters to disks and cdroms and define \SystemRoot. 00906 // 00907 00908 ansiString.MaximumLength = NtSystemRoot.MaximumLength / sizeof( WCHAR ); 00909 ansiString.Length = 0; 00910 ansiString.Buffer = (RtlAllocateStringRoutine)( ansiString.MaximumLength ); 00911 status = RtlUnicodeStringToAnsiString( &ansiString, 00912 &NtSystemRoot, 00913 FALSE 00914 ); 00915 if (!NT_SUCCESS( status )) { 00916 DbgPrint( "IOINIT: UnicodeToAnsi( %wZ ) failed - %x\n", &NtSystemRoot, status ); 00917 return(FALSE); 00918 } 00919 00920 IoAssignDriveLetters( LoaderBlock, 00921 &ntDeviceName, 00922 ansiString.Buffer, 00923 &ansiString ); 00924 00925 status = RtlAnsiStringToUnicodeString( &NtSystemRoot, 00926 &ansiString, 00927 FALSE 00928 ); 00929 if (!NT_SUCCESS( status )) { 00930 DbgPrint( "IOINIT: AnsiToUnicode( %Z ) failed - %x\n", &ansiString, status ); 00931 return(FALSE); 00932 } 00933 00934 // 00935 // Also restore the NT Global Flags to their original state. 00936 // 00937 00938 NtGlobalFlag = oldNtGlobalFlag; 00939 00940 // 00941 // Call Power manager to initialize for post-boot drivers 00942 // 00943 PoInitDriverServices(1); 00944 00945 // 00946 // Indicate that the I/O system successfully initialized itself. 00947 // 00948 00949 return TRUE; 00950 }

BOOLEAN IopCheckDependencies IN HANDLE  KeyHandle  ) 
 

Definition at line 978 of file ioinit.c.

References _TREE_ENTRY::DriversLoaded, ExFreePool(), FALSE, IopGetRegistryValue(), IopLookupGroupName(), L, NT_SUCCESS, PTREE_ENTRY, RtlInitUnicodeString(), and TRUE.

Referenced by IopInitializeBootDrivers(), and IopInitializeSystemDrivers().

00984 : 00985 00986 This routine gets the "DependOnGroup" field for the specified key node 00987 and determines whether any driver in the group(s) that this entry is 00988 dependent on has successfully loaded. 00989 00990 Arguments: 00991 00992 KeyHandle - Supplies a handle to the key representing the driver in 00993 question. 00994 00995 Return Value: 00996 00997 The function value is TRUE if the driver should be loaded, otherwise 00998 FALSE 00999 01000 --*/ 01001 01002 { 01003 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 01004 UNICODE_STRING groupName; 01005 BOOLEAN load; 01006 ULONG length; 01007 PWSTR source; 01008 PTREE_ENTRY treeEntry; 01009 01010 // 01011 // Attempt to obtain the "DependOnGroup" key for the specified driver 01012 // entry. If one does not exist, then simply mark this driver as being 01013 // one to attempt to load. If it does exist, then check to see whether 01014 // or not any driver in the groups that it is dependent on has loaded 01015 // and allow it to load. 01016 // 01017 01018 if (!NT_SUCCESS( IopGetRegistryValue( KeyHandle, L"DependOnGroup", &keyValueInformation ))) { 01019 return TRUE; 01020 } 01021 01022 length = keyValueInformation->DataLength; 01023 01024 source = (PWSTR) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset); 01025 load = TRUE; 01026 01027 while (length) { 01028 RtlInitUnicodeString( &groupName, source ); 01029 groupName.Length = groupName.MaximumLength; 01030 treeEntry = IopLookupGroupName( &groupName, FALSE ); 01031 if (treeEntry) { 01032 if (!treeEntry->DriversLoaded) { 01033 load = FALSE; 01034 break; 01035 } 01036 } 01037 length -= groupName.MaximumLength; 01038 source = (PWSTR) ((PUCHAR) source + groupName.MaximumLength); 01039 } 01040 01041 ExFreePool( keyValueInformation ); 01042 return load; 01043 }

VOID IopCreateArcNames IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 1047 of file ioinit.c.

References _ARC_DISK_SIGNATURE::ArcName, _ARC_DISK_SIGNATURE::CheckSum, DbgPrint, _CONFIGURATION_INFORMATION::DiskCount, _ARC_DISK_INFORMATION::DiskSignatures, ExAllocatePool, ExFreePool(), FALSE, HalExamineMBR, IoArcBootDeviceName, IoArcHalDeviceName, IoBuildDeviceIoControlRequest(), IoBuildSynchronousFsdRequest(), IoCallDriver, IoCreateSymbolicLink(), IoGetConfigurationInformation(), IoGetDeviceInterfaces(), IoGetDeviceObjectPointer(), IoLoaderArcBootDeviceName, IopStoreSystemPartitionInformation(), IoReadPartitionTable(), IoRemoteBootClient, IRP_MJ_READ, KeI386MachineType, KeInitializeEvent, KernelMode, KeWaitForSingleObject(), L, max, NonPagedPoolCacheAlignedMustS, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PagedPool, RtlAnsiStringToUnicodeString(), RtlEqualString(), RtlFreeUnicodeString(), RtlInitAnsiString(), RtlInitUnicodeString(), _ARC_DISK_SIGNATURE::Signature, sprintf(), strlen(), Suspended, TRUE, and _ARC_DISK_SIGNATURE::ValidPartitionTable.

Referenced by IopInitializeBootDrivers().

01053 : 01054 01055 The loader block contains a table of disk signatures and corresponding 01056 ARC names. Each device that the loader can access will appear in the 01057 table. This routine opens each disk device in the system, reads the 01058 signature and compares it to the table. For each match, it creates a 01059 symbolic link between the nt device name and the ARC name. 01060 01061 The checksum value provided by the loader is the ULONG sum of all 01062 elements in the checksum, inverted, plus 1: 01063 checksum = ~sum + 1; 01064 This way the sum of all of the elements can be calculated here and 01065 added to the checksum in the loader block. If the result is zero, then 01066 there is a match. 01067 01068 Arguments: 01069 01070 LoaderBlock - Supplies a pointer to the loader parameter block that was 01071 created by the OS Loader. 01072 01073 Return Value: 01074 01075 None. 01076 01077 --*/ 01078 01079 { 01080 STRING arcBootDeviceString; 01081 UCHAR deviceNameBuffer[128]; 01082 STRING deviceNameString; 01083 UNICODE_STRING deviceNameUnicodeString; 01084 PDEVICE_OBJECT deviceObject; 01085 UCHAR arcNameBuffer[128]; 01086 STRING arcNameString; 01087 UNICODE_STRING arcNameUnicodeString; 01088 PFILE_OBJECT fileObject; 01089 NTSTATUS status; 01090 IO_STATUS_BLOCK ioStatusBlock; 01091 DISK_GEOMETRY diskGeometry; 01092 PDRIVE_LAYOUT_INFORMATION driveLayout; 01093 PLIST_ENTRY listEntry; 01094 PARC_DISK_SIGNATURE diskBlock; 01095 ULONG diskNumber; 01096 ULONG partitionNumber; 01097 PCHAR arcName; 01098 PULONG buffer; 01099 PIRP irp; 01100 KEVENT event; 01101 LARGE_INTEGER offset; 01102 ULONG checkSum; 01103 ULONG i; 01104 PVOID tmpPtr; 01105 BOOLEAN useLegacyEnumeration = FALSE; 01106 BOOLEAN singleBiosDiskFound; 01107 BOOLEAN bootDiskFound = FALSE; 01108 PARC_DISK_INFORMATION arcInformation = LoaderBlock->ArcDiskInformation; 01109 ULONG totalDriverDisksFound = IoGetConfigurationInformation()->DiskCount; 01110 ULONG totalPnpDisksFound = 0; 01111 STRING arcSystemDeviceString; 01112 STRING osLoaderPathString; 01113 UNICODE_STRING osLoaderPathUnicodeString; 01114 PWSTR diskList = NULL; 01115 wchar_t *pDiskNameList; 01116 STORAGE_DEVICE_NUMBER pnpDiskDeviceNumber; 01117 01118 01119 // 01120 // ask PNP to give us a list with all the currently active disks 01121 // 01122 01123 pDiskNameList = diskList; 01124 pnpDiskDeviceNumber.DeviceNumber = 0xFFFFFFFF; 01125 status = IoGetDeviceInterfaces(&DiskClassGuid, NULL, 0, &diskList); 01126 01127 if (!NT_SUCCESS(status)) { 01128 01129 useLegacyEnumeration = TRUE; 01130 if (pDiskNameList) { 01131 *pDiskNameList = L'\0'; 01132 } 01133 01134 } else { 01135 01136 // 01137 // count the number of disks returned 01138 // 01139 01140 pDiskNameList = diskList; 01141 while (*pDiskNameList != L'\0') { 01142 01143 totalPnpDisksFound++; 01144 pDiskNameList = pDiskNameList + (wcslen(pDiskNameList) + 1); 01145 01146 } 01147 01148 pDiskNameList = diskList; 01149 01150 // 01151 // if the disk returned by PNP are not all the disks in the system 01152 // it means that some legacy driver has generated a disk device object/link. 01153 // In that case we need to enumerate all pnp disks and then using the legacy 01154 // for-loop also enumerate the non-pnp disks 01155 // 01156 01157 if (totalPnpDisksFound < totalDriverDisksFound) { 01158 useLegacyEnumeration = TRUE; 01159 } 01160 01161 } 01162 01163 // 01164 // If a single bios disk was found if there is only a 01165 // single entry on the disk signature list. 01166 // 01167 01168 singleBiosDiskFound = (arcInformation->DiskSignatures.Flink->Flink == 01169 &arcInformation->DiskSignatures) ? (TRUE) : (FALSE); 01170 01171 01172 // 01173 // Create hal/loader partition name 01174 // 01175 01176 sprintf( arcNameBuffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName ); 01177 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01178 RtlAnsiStringToUnicodeString (&IoArcHalDeviceName, &arcNameString, TRUE); 01179 01180 // 01181 // Create boot partition name 01182 // 01183 01184 sprintf( arcNameBuffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName ); 01185 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01186 RtlAnsiStringToUnicodeString (&IoArcBootDeviceName, &arcNameString, TRUE); 01187 i = strlen (LoaderBlock->ArcBootDeviceName) + 1; 01188 IoLoaderArcBootDeviceName = ExAllocatePool (PagedPool, i); 01189 if (IoLoaderArcBootDeviceName) { 01190 memcpy (IoLoaderArcBootDeviceName, LoaderBlock->ArcBootDeviceName, i); 01191 } 01192 01193 if (singleBiosDiskFound && strstr(LoaderBlock->ArcBootDeviceName, "cdrom")) { 01194 singleBiosDiskFound = FALSE; 01195 } 01196 01197 // 01198 // Get ARC boot device name from loader block. 01199 // 01200 01201 RtlInitAnsiString( &arcBootDeviceString, 01202 LoaderBlock->ArcBootDeviceName ); 01203 01204 // 01205 // Get ARC system device name from loader block. 01206 // 01207 01208 RtlInitAnsiString( &arcSystemDeviceString, 01209 LoaderBlock->ArcHalDeviceName ); 01210 01211 // 01212 // If this is a remote boot, create an ArcName for the redirector path. 01213 // 01214 01215 if (IoRemoteBootClient) { 01216 01217 bootDiskFound = TRUE; 01218 01219 RtlInitAnsiString( &deviceNameString, "\\Device\\LanmanRedirector" ); 01220 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 01221 &deviceNameString, 01222 TRUE ); 01223 01224 if (NT_SUCCESS( status )) { 01225 01226 sprintf( arcNameBuffer, 01227 "\\ArcName\\%s", 01228 LoaderBlock->ArcBootDeviceName ); 01229 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01230 status = RtlAnsiStringToUnicodeString( &arcNameUnicodeString, 01231 &arcNameString, 01232 TRUE ); 01233 if (NT_SUCCESS( status )) { 01234 01235 // 01236 // Create symbolic link between NT device name and ARC name. 01237 // 01238 01239 IoCreateSymbolicLink( &arcNameUnicodeString, 01240 &deviceNameUnicodeString ); 01241 RtlFreeUnicodeString( &arcNameUnicodeString ); 01242 01243 // 01244 // We've found the system partition--store it away in the registry 01245 // to later be transferred to a application-friendly location. 01246 // 01247 RtlInitAnsiString( &osLoaderPathString, LoaderBlock->NtHalPathName ); 01248 status = RtlAnsiStringToUnicodeString( &osLoaderPathUnicodeString, 01249 &osLoaderPathString, 01250 TRUE ); 01251 01252 #if DBG 01253 if (!NT_SUCCESS( status )) { 01254 DbgPrint("IopCreateArcNames: couldn't allocate unicode string for OsLoader path - %x\n", status); 01255 } 01256 #endif // DBG 01257 if (NT_SUCCESS( status )) { 01258 01259 IopStoreSystemPartitionInformation( &deviceNameUnicodeString, 01260 &osLoaderPathUnicodeString ); 01261 01262 RtlFreeUnicodeString( &osLoaderPathUnicodeString ); 01263 } 01264 } 01265 01266 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01267 } 01268 } 01269 01270 // 01271 // For each disk in the system do the following: 01272 // 1. open the device 01273 // 2. get its geometry 01274 // 3. read the MBR 01275 // 4. determine ARC name via disk signature and checksum 01276 // 5. construct ARC name. 01277 // In order to deal with the case of disk dissappearing before we get to this point 01278 // (due to a failed start on one of many disks present in the system) we ask PNP for a list 01279 // of all the currenttly active disks in the system. If the number of disks returned is 01280 // less than the IoGetConfigurationInformation()->DiskCount, then we have legacy disks 01281 // that we need to enumerate in the for loop. 01282 // In the legacy case, the ending condition for the loop is NOT the total disk on the 01283 // system but an arbitrary number of the max total legacy disks expected in the system.. 01284 // Additional note: Legacy disks get assigned symbolic links AFTER all pnp enumeration is complete 01285 // 01286 01287 totalDriverDisksFound = max(totalPnpDisksFound,totalDriverDisksFound); 01288 01289 if (useLegacyEnumeration && (totalPnpDisksFound == 0)) { 01290 01291 // 01292 // search up to a maximum arbitrary number of legacy disks 01293 // 01294 01295 totalDriverDisksFound +=20; 01296 } 01297 01298 for (diskNumber = 0; 01299 diskNumber < totalDriverDisksFound; 01300 diskNumber++) { 01301 01302 // 01303 // Construct the NT name for a disk and obtain a reference. 01304 // 01305 01306 if (pDiskNameList && (*pDiskNameList != L'\0')) { 01307 01308 // 01309 // retrieve the first symbolic linkname from the PNP disk list 01310 // 01311 01312 RtlInitUnicodeString(&deviceNameUnicodeString, pDiskNameList); 01313 pDiskNameList = pDiskNameList + (wcslen(pDiskNameList) + 1); 01314 01315 status = IoGetDeviceObjectPointer( &deviceNameUnicodeString, 01316 FILE_READ_ATTRIBUTES, 01317 &fileObject, 01318 &deviceObject ); 01319 01320 if (NT_SUCCESS(status)) { 01321 01322 // 01323 // since PNP gave s just asym link we have to retrieve the actual 01324 // disk number through an IOCTL call to the disk stack. 01325 // Create IRP for get device number device control. 01326 // 01327 01328 irp = IoBuildDeviceIoControlRequest( IOCTL_STORAGE_GET_DEVICE_NUMBER, 01329 deviceObject, 01330 NULL, 01331 0, 01332 &pnpDiskDeviceNumber, 01333 sizeof(STORAGE_DEVICE_NUMBER), 01334 FALSE, 01335 &event, 01336 &ioStatusBlock ); 01337 if (!irp) { 01338 ObDereferenceObject( fileObject ); 01339 continue; 01340 } 01341 01342 KeInitializeEvent( &event, 01343 NotificationEvent, 01344 FALSE ); 01345 status = IoCallDriver( deviceObject, 01346 irp ); 01347 01348 if (status == STATUS_PENDING) { 01349 KeWaitForSingleObject( &event, 01350 Suspended, 01351 KernelMode, 01352 FALSE, 01353 NULL ); 01354 status = ioStatusBlock.Status; 01355 } 01356 01357 if (!NT_SUCCESS( status )) { 01358 ObDereferenceObject( fileObject ); 01359 continue; 01360 } 01361 01362 } 01363 01364 if (useLegacyEnumeration && (*pDiskNameList == L'\0') ) { 01365 01366 // 01367 // end of pnp disks 01368 // if there are any legacy disks following we need to update 01369 // the total disk found number to cover the maximum disk number 01370 // a legacy disk could be at. (in a sparse name space) 01371 // 01372 01373 if (pnpDiskDeviceNumber.DeviceNumber == 0xFFFFFFFF) { 01374 pnpDiskDeviceNumber.DeviceNumber = 0; 01375 } 01376 01377 diskNumber = max(diskNumber,pnpDiskDeviceNumber.DeviceNumber); 01378 totalDriverDisksFound = diskNumber + 20; 01379 01380 } 01381 01382 } else { 01383 01384 sprintf( deviceNameBuffer, 01385 "\\Device\\Harddisk%d\\Partition0", 01386 diskNumber ); 01387 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 01388 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 01389 &deviceNameString, 01390 TRUE ); 01391 if (!NT_SUCCESS( status )) { 01392 continue; 01393 } 01394 01395 status = IoGetDeviceObjectPointer( &deviceNameUnicodeString, 01396 FILE_READ_ATTRIBUTES, 01397 &fileObject, 01398 &deviceObject ); 01399 01400 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01401 01402 // 01403 // set the pnpDiskNumber value so its not used. 01404 // 01405 01406 pnpDiskDeviceNumber.DeviceNumber = 0xFFFFFFFF; 01407 01408 } 01409 01410 01411 if (!NT_SUCCESS( status )) { 01412 01413 continue; 01414 } 01415 01416 // 01417 // Create IRP for get drive geometry device control. 01418 // 01419 01420 irp = IoBuildDeviceIoControlRequest( IOCTL_DISK_GET_DRIVE_GEOMETRY, 01421 deviceObject, 01422 NULL, 01423 0, 01424 &diskGeometry, 01425 sizeof(DISK_GEOMETRY), 01426 FALSE, 01427 &event, 01428 &ioStatusBlock ); 01429 if (!irp) { 01430 ObDereferenceObject( fileObject ); 01431 continue; 01432 } 01433 01434 KeInitializeEvent( &event, 01435 NotificationEvent, 01436 FALSE ); 01437 status = IoCallDriver( deviceObject, 01438 irp ); 01439 01440 if (status == STATUS_PENDING) { 01441 KeWaitForSingleObject( &event, 01442 Suspended, 01443 KernelMode, 01444 FALSE, 01445 NULL ); 01446 status = ioStatusBlock.Status; 01447 } 01448 01449 if (!NT_SUCCESS( status )) { 01450 ObDereferenceObject( fileObject ); 01451 continue; 01452 } 01453 01454 // 01455 // Get partition information for this disk. 01456 // 01457 01458 status = IoReadPartitionTable( deviceObject, 01459 diskGeometry.BytesPerSector, 01460 TRUE, 01461 &driveLayout ); 01462 01463 ObDereferenceObject( fileObject ); 01464 01465 if (!NT_SUCCESS( status )) { 01466 continue; 01467 } 01468 01469 // 01470 // Make sure sector size is at least 512 bytes. 01471 // 01472 01473 if (diskGeometry.BytesPerSector < 512) { 01474 diskGeometry.BytesPerSector = 512; 01475 } 01476 01477 // 01478 // Check to see if EZ Drive is out there on this disk. If 01479 // it is then zero out the signature in the drive layout since 01480 // this will never be written by anyone AND change to offset to 01481 // actually read sector 1 rather than 0 cause that's what the 01482 // loader actually did. 01483 // 01484 01485 offset.QuadPart = 0; 01486 HalExamineMBR( deviceObject, 01487 diskGeometry.BytesPerSector, 01488 (ULONG)0x55, 01489 &tmpPtr ); 01490 01491 if (tmpPtr) { 01492 01493 offset.QuadPart = diskGeometry.BytesPerSector; 01494 ExFreePool(tmpPtr); 01495 #ifdef _X86_ 01496 } else if (KeI386MachineType & MACHINE_TYPE_PC_9800_COMPATIBLE) { 01497 01498 // 01499 // PC 9800 compatible machines do not have a standard 01500 // MBR format and use a different sector for checksuming. 01501 // 01502 01503 offset.QuadPart = 512; 01504 #endif //_X86_ 01505 } 01506 01507 // 01508 // Allocate buffer for sector read and construct the read request. 01509 // 01510 01511 buffer = ExAllocatePool( NonPagedPoolCacheAlignedMustS, 01512 diskGeometry.BytesPerSector ); 01513 01514 if (buffer) { 01515 irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, 01516 deviceObject, 01517 buffer, 01518 diskGeometry.BytesPerSector, 01519 &offset, 01520 &event, 01521 &ioStatusBlock ); 01522 01523 if (!irp) { 01524 ExFreePool(driveLayout); 01525 ExFreePool(buffer); 01526 continue; 01527 } 01528 } else { 01529 ExFreePool(driveLayout); 01530 continue; 01531 } 01532 KeInitializeEvent( &event, 01533 NotificationEvent, 01534 FALSE ); 01535 status = IoCallDriver( deviceObject, 01536 irp ); 01537 if (status == STATUS_PENDING) { 01538 KeWaitForSingleObject( &event, 01539 Suspended, 01540 KernelMode, 01541 FALSE, 01542 NULL ); 01543 status = ioStatusBlock.Status; 01544 } 01545 01546 if (!NT_SUCCESS( status )) { 01547 ExFreePool(driveLayout); 01548 ExFreePool(buffer); 01549 continue; 01550 } 01551 01552 // 01553 // Calculate MBR sector checksum. Only 512 bytes are used. 01554 // 01555 01556 checkSum = 0; 01557 for (i = 0; i < 128; i++) { 01558 checkSum += buffer[i]; 01559 } 01560 01561 // 01562 // For each ARC disk information record in the loader block 01563 // match the disk signature and checksum to determine its ARC 01564 // name and construct the NT ARC names symbolic links. 01565 // 01566 01567 for (listEntry = arcInformation->DiskSignatures.Flink; 01568 listEntry != &arcInformation->DiskSignatures; 01569 listEntry = listEntry->Flink) { 01570 01571 // 01572 // Get next record and compare disk signatures. 01573 // 01574 01575 diskBlock = CONTAINING_RECORD( listEntry, 01576 ARC_DISK_SIGNATURE, 01577 ListEntry ); 01578 01579 // 01580 // Compare disk signatures. 01581 // 01582 // Or if there is only a single disk drive from 01583 // both the bios and driver viewpoints then 01584 // assign an arc name to that drive. 01585 // 01586 01587 if ((singleBiosDiskFound && (totalDriverDisksFound == 1)) || 01588 (diskBlock->Signature == driveLayout->Signature && 01589 !(diskBlock->CheckSum + checkSum) && 01590 diskBlock->ValidPartitionTable)) { 01591 01592 // 01593 // Create unicode device name for physical disk. 01594 // 01595 01596 if (pnpDiskDeviceNumber.DeviceNumber == 0xFFFFFFFF) { 01597 01598 sprintf( deviceNameBuffer, 01599 "\\Device\\Harddisk%d\\Partition0", 01600 diskNumber ); 01601 01602 } else { 01603 01604 sprintf( deviceNameBuffer, 01605 "\\Device\\Harddisk%d\\Partition0", 01606 pnpDiskDeviceNumber.DeviceNumber ); 01607 01608 } 01609 01610 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 01611 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 01612 &deviceNameString, 01613 TRUE ); 01614 if (!NT_SUCCESS( status )) { 01615 continue; 01616 } 01617 01618 // 01619 // Create unicode ARC name for this partition. 01620 // 01621 01622 arcName = diskBlock->ArcName; 01623 sprintf( arcNameBuffer, 01624 "\\ArcName\\%s", 01625 arcName ); 01626 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01627 status = RtlAnsiStringToUnicodeString( &arcNameUnicodeString, 01628 &arcNameString, 01629 TRUE ); 01630 if (!NT_SUCCESS( status )) { 01631 continue; 01632 } 01633 01634 // 01635 // Create symbolic link between NT device name and ARC name. 01636 // 01637 01638 IoCreateSymbolicLink( &arcNameUnicodeString, 01639 &deviceNameUnicodeString ); 01640 RtlFreeUnicodeString( &arcNameUnicodeString ); 01641 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01642 01643 // 01644 // Create an ARC name for every partition on this disk. 01645 // 01646 01647 for (partitionNumber = 0; 01648 partitionNumber < driveLayout->PartitionCount; 01649 partitionNumber++) { 01650 01651 // 01652 // Create unicode NT device name. 01653 // 01654 01655 if (pnpDiskDeviceNumber.DeviceNumber == 0xFFFFFFFF) { 01656 01657 sprintf( deviceNameBuffer, 01658 "\\Device\\Harddisk%d\\Partition%d", 01659 diskNumber, 01660 partitionNumber+1 ); 01661 01662 01663 } else { 01664 01665 sprintf( deviceNameBuffer, 01666 "\\Device\\Harddisk%d\\Partition%d", 01667 pnpDiskDeviceNumber.DeviceNumber, 01668 partitionNumber+1 ); 01669 01670 } 01671 01672 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 01673 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 01674 &deviceNameString, 01675 TRUE ); 01676 if (!NT_SUCCESS( status )) { 01677 continue; 01678 } 01679 01680 // 01681 // Create unicode ARC name for this partition and 01682 // check to see if this is the boot disk. 01683 // 01684 01685 sprintf( arcNameBuffer, 01686 "%spartition(%d)", 01687 arcName, 01688 partitionNumber+1 ); 01689 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01690 if (RtlEqualString( &arcNameString, 01691 &arcBootDeviceString, 01692 TRUE )) { 01693 bootDiskFound = TRUE; 01694 } 01695 01696 // 01697 // See if this is the system partition. 01698 // 01699 if (RtlEqualString( &arcNameString, 01700 &arcSystemDeviceString, 01701 TRUE )) { 01702 // 01703 // We've found the system partition--store it away in the registry 01704 // to later be transferred to a application-friendly location. 01705 // 01706 RtlInitAnsiString( &osLoaderPathString, LoaderBlock->NtHalPathName ); 01707 status = RtlAnsiStringToUnicodeString( &osLoaderPathUnicodeString, 01708 &osLoaderPathString, 01709 TRUE ); 01710 01711 #if DBG 01712 if (!NT_SUCCESS( status )) { 01713 DbgPrint("IopCreateArcNames: couldn't allocate unicode string for OsLoader path - %x\n", status); 01714 } 01715 #endif // DBG 01716 if (NT_SUCCESS( status )) { 01717 01718 IopStoreSystemPartitionInformation( &deviceNameUnicodeString, 01719 &osLoaderPathUnicodeString ); 01720 01721 RtlFreeUnicodeString( &osLoaderPathUnicodeString ); 01722 } 01723 } 01724 01725 // 01726 // Add the NT ARC namespace prefix to the ARC name constructed. 01727 // 01728 01729 sprintf( arcNameBuffer, 01730 "\\ArcName\\%spartition(%d)", 01731 arcName, 01732 partitionNumber+1 ); 01733 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01734 status = RtlAnsiStringToUnicodeString( &arcNameUnicodeString, 01735 &arcNameString, 01736 TRUE ); 01737 if (!NT_SUCCESS( status )) { 01738 continue; 01739 } 01740 01741 // 01742 // Create symbolic link between NT device name and ARC name. 01743 // 01744 01745 IoCreateSymbolicLink( &arcNameUnicodeString, 01746 &deviceNameUnicodeString ); 01747 RtlFreeUnicodeString( &arcNameUnicodeString ); 01748 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01749 } 01750 01751 } else { 01752 01753 #if DBG 01754 // 01755 // Check key indicators to see if this condition may be 01756 // caused by a viral infection. 01757 // 01758 01759 if (diskBlock->Signature == driveLayout->Signature && 01760 (diskBlock->CheckSum + checkSum) != 0 && 01761 diskBlock->ValidPartitionTable) { 01762 DbgPrint("IopCreateArcNames: Virus or duplicate disk signatures\n"); 01763 } 01764 #endif 01765 } 01766 } 01767 01768 ExFreePool( driveLayout ); 01769 ExFreePool( buffer ); 01770 } 01771 01772 if (!bootDiskFound) { 01773 01774 // 01775 // Locate the disk block that represents the boot device. 01776 // 01777 01778 diskBlock = NULL; 01779 for (listEntry = arcInformation->DiskSignatures.Flink; 01780 listEntry != &arcInformation->DiskSignatures; 01781 listEntry = listEntry->Flink) { 01782 01783 diskBlock = CONTAINING_RECORD( listEntry, 01784 ARC_DISK_SIGNATURE, 01785 ListEntry ); 01786 if (strcmp( diskBlock->ArcName, LoaderBlock->ArcBootDeviceName ) == 0) { 01787 break; 01788 } 01789 diskBlock = NULL; 01790 } 01791 01792 if (diskBlock) { 01793 01794 // 01795 // This could be a CdRom boot. Search all of the NT CdRoms 01796 // to locate a checksum match on the diskBlock found. If 01797 // there is a match, assign the ARC name to the CdRom. 01798 // 01799 01800 irp = NULL; 01801 buffer = ExAllocatePool( NonPagedPoolCacheAlignedMustS, 01802 2048 ); 01803 if (buffer) { 01804 01805 // 01806 // Construct the NT names for CdRoms and search each one 01807 // for a checksum match. If found, create the ARC Name 01808 // symbolic link. 01809 // 01810 01811 for (diskNumber = 0; TRUE; diskNumber++) { 01812 01813 sprintf( deviceNameBuffer, 01814 "\\Device\\CdRom%d", 01815 diskNumber ); 01816 01817 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 01818 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 01819 &deviceNameString, 01820 TRUE ); 01821 if (NT_SUCCESS( status )) { 01822 01823 status = IoGetDeviceObjectPointer( &deviceNameUnicodeString, 01824 FILE_READ_ATTRIBUTES, 01825 &fileObject, 01826 &deviceObject ); 01827 if (!NT_SUCCESS( status )) { 01828 01829 // 01830 // All CdRoms have been processed. 01831 // 01832 01833 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01834 break; 01835 } 01836 01837 // 01838 // Read the block for the checksum calculation. 01839 // 01840 01841 offset.QuadPart = 0x8000; 01842 irp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, 01843 deviceObject, 01844 buffer, 01845 2048, 01846 &offset, 01847 &event, 01848 &ioStatusBlock ); 01849 checkSum = 0; 01850 if (irp) { 01851 KeInitializeEvent( &event, 01852 NotificationEvent, 01853 FALSE ); 01854 status = IoCallDriver( deviceObject, 01855 irp ); 01856 if (status == STATUS_PENDING) { 01857 KeWaitForSingleObject( &event, 01858 Suspended, 01859 KernelMode, 01860 FALSE, 01861 NULL ); 01862 status = ioStatusBlock.Status; 01863 } 01864 01865 if (NT_SUCCESS( status )) { 01866 01867 // 01868 // Calculate MBR sector checksum. 01869 // 2048 bytes are used. 01870 // 01871 01872 for (i = 0; i < 2048 / sizeof(ULONG) ; i++) { 01873 checkSum += buffer[i]; 01874 } 01875 } 01876 } 01877 ObDereferenceObject( fileObject ); 01878 01879 if (!(diskBlock->CheckSum + checkSum)) { 01880 01881 // 01882 // This is the boot CdRom. Create the symlink for 01883 // the ARC name from the loader block. 01884 // 01885 01886 sprintf( arcNameBuffer, 01887 "\\ArcName\\%s", 01888 LoaderBlock->ArcBootDeviceName ); 01889 RtlInitAnsiString( &arcNameString, arcNameBuffer ); 01890 status = RtlAnsiStringToUnicodeString( &arcNameUnicodeString, 01891 &arcNameString, 01892 TRUE ); 01893 if (NT_SUCCESS( status )) { 01894 01895 IoCreateSymbolicLink( &arcNameUnicodeString, 01896 &deviceNameUnicodeString ); 01897 RtlFreeUnicodeString( &arcNameUnicodeString ); 01898 } 01899 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01900 break; 01901 } 01902 RtlFreeUnicodeString( &deviceNameUnicodeString ); 01903 } 01904 } 01905 ExFreePool(buffer); 01906 } 01907 } 01908 } 01909 01910 if (diskList) { 01911 ExFreePool(diskList); 01912 } 01913 }

PTREE_ENTRY IopCreateEntry IN PUNICODE_STRING  GroupName  ) 
 

Definition at line 2107 of file ioinit.c.

References ExAllocatePool, ExRaiseStatus(), _TREE_ENTRY::GroupName, PagedPool, PTREE_ENTRY, and TREE_ENTRY.

Referenced by IopLookupGroupName().

02113 : 02114 02115 This routine creates an entry for the specified group name suitable for 02116 being inserted into the group name tree. 02117 02118 Arguments: 02119 02120 GroupName - Specifies the name of the group for the entry. 02121 02122 Return Value: 02123 02124 The function value is a pointer to the created entry. 02125 02126 02127 --*/ 02128 02129 { 02130 PTREE_ENTRY treeEntry; 02131 02132 // 02133 // Allocate and initialize an entry suitable for placing into the group 02134 // name tree. 02135 // 02136 02137 treeEntry = ExAllocatePool( PagedPool, 02138 sizeof( TREE_ENTRY ) + GroupName->Length ); 02139 if (!treeEntry) { 02140 ExRaiseStatus( STATUS_INSUFFICIENT_RESOURCES ); 02141 } 02142 02143 RtlZeroMemory( treeEntry, sizeof( TREE_ENTRY ) ); 02144 treeEntry->GroupName.Length = GroupName->Length; 02145 treeEntry->GroupName.MaximumLength = GroupName->Length; 02146 treeEntry->GroupName.Buffer = (PWCHAR) (treeEntry + 1); 02147 RtlCopyMemory( treeEntry->GroupName.Buffer, 02148 GroupName->Buffer, 02149 GroupName->Length ); 02150 02151 return treeEntry; 02152 }

BOOLEAN IopCreateObjectTypes VOID   ) 
 

Definition at line 1936 of file ioinit.c.

References FALSE, IO_FILE_OBJECT_NON_PAGED_POOL_CHARGE, IO_FILE_OBJECT_PAGED_POOL_CHARGE, IoAdapterObjectType, IoCompletionObjectType, IoControllerObjectType, IoDeviceHandlerObjectSize, IoDeviceHandlerObjectType, IoDeviceObjectType, IoDriverObjectType, IoFileObjectType, IopCloseFile(), IopCompletionMapping, IopDeleteDevice(), IopDeleteDriver(), IopDeleteFile(), IopDeleteIoCompletion(), IopFileMapping, IopGetSetSecurityObject(), IopParseDevice(), IopParseFile(), IopQueryName(), L, NonPagedPool, NT_SUCCESS, NULL, OB_PARSE_METHOD, OB_QUERYNAME_METHOD, OB_SECURITY_METHOD, ObCreateObjectType(), RtlInitUnicodeString(), and TRUE.

Referenced by IoInitSystem().

01942 : 01943 01944 This routine creates the object types used by the I/O system and its 01945 components. The object types created are: 01946 01947 Adapter 01948 Controller 01949 Device 01950 Driver 01951 File 01952 I/O Completion 01953 01954 Arguments: 01955 01956 None. 01957 01958 Return Value: 01959 01960 The function value is a BOOLEAN indicating whether or not the object 01961 types were successfully created. 01962 01963 01964 --*/ 01965 01966 { 01967 OBJECT_TYPE_INITIALIZER objectTypeInitializer; 01968 UNICODE_STRING nameString; 01969 01970 // 01971 // Initialize the common fields of the Object Type Initializer record 01972 // 01973 01974 RtlZeroMemory( &objectTypeInitializer, sizeof( objectTypeInitializer ) ); 01975 objectTypeInitializer.Length = sizeof( objectTypeInitializer ); 01976 objectTypeInitializer.InvalidAttributes = OBJ_OPENLINK; 01977 objectTypeInitializer.GenericMapping = IopFileMapping; 01978 objectTypeInitializer.PoolType = NonPagedPool; 01979 objectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 01980 objectTypeInitializer.UseDefaultObject = TRUE; 01981 01982 01983 // 01984 // Create the object type for adapter objects. 01985 // 01986 01987 RtlInitUnicodeString( &nameString, L"Adapter" ); 01988 // objectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( struct _ADAPTER_OBJECT ); 01989 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 01990 &objectTypeInitializer, 01991 (PSECURITY_DESCRIPTOR) NULL, 01992 &IoAdapterObjectType ))) { 01993 return FALSE; 01994 } 01995 01996 #ifdef _PNP_POWER_ 01997 01998 // 01999 // Create the object type for device helper objects. 02000 // 02001 02002 RtlInitUnicodeString( &nameString, L"DeviceHandler" ); 02003 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02004 &objectTypeInitializer, 02005 (PSECURITY_DESCRIPTOR) NULL, 02006 &IoDeviceHandlerObjectType ))) { 02007 return FALSE; 02008 } 02009 IoDeviceHandlerObjectSize = sizeof(DEVICE_HANDLER_OBJECT); 02010 02011 #endif 02012 02013 // 02014 // Create the object type for controller objects. 02015 // 02016 02017 RtlInitUnicodeString( &nameString, L"Controller" ); 02018 objectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( CONTROLLER_OBJECT ); 02019 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02020 &objectTypeInitializer, 02021 (PSECURITY_DESCRIPTOR) NULL, 02022 &IoControllerObjectType ))) { 02023 return FALSE; 02024 } 02025 02026 // 02027 // Create the object type for device objects. 02028 // 02029 02030 RtlInitUnicodeString( &nameString, L"Device" ); 02031 objectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( DEVICE_OBJECT ); 02032 objectTypeInitializer.ParseProcedure = IopParseDevice; 02033 objectTypeInitializer.DeleteProcedure = IopDeleteDevice; 02034 objectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 02035 objectTypeInitializer.QueryNameProcedure = (OB_QUERYNAME_METHOD)NULL; 02036 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02037 &objectTypeInitializer, 02038 (PSECURITY_DESCRIPTOR) NULL, 02039 &IoDeviceObjectType ))) { 02040 return FALSE; 02041 } 02042 02043 // 02044 // Create the object type for driver objects. 02045 // 02046 02047 RtlInitUnicodeString( &nameString, L"Driver" ); 02048 objectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( DRIVER_OBJECT ); 02049 objectTypeInitializer.ParseProcedure = (OB_PARSE_METHOD) NULL; 02050 objectTypeInitializer.DeleteProcedure = IopDeleteDriver; 02051 objectTypeInitializer.SecurityProcedure = (OB_SECURITY_METHOD) NULL; 02052 objectTypeInitializer.QueryNameProcedure = (OB_QUERYNAME_METHOD)NULL; 02053 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02054 &objectTypeInitializer, 02055 (PSECURITY_DESCRIPTOR) NULL, 02056 &IoDriverObjectType ))) { 02057 return FALSE; 02058 } 02059 02060 // 02061 // Create the object type for I/O completion objects. 02062 // 02063 02064 RtlInitUnicodeString( &nameString, L"IoCompletion" ); 02065 objectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( KQUEUE ); 02066 objectTypeInitializer.InvalidAttributes = OBJ_PERMANENT | OBJ_OPENLINK; 02067 objectTypeInitializer.GenericMapping = IopCompletionMapping; 02068 objectTypeInitializer.ValidAccessMask = IO_COMPLETION_ALL_ACCESS; 02069 objectTypeInitializer.DeleteProcedure = IopDeleteIoCompletion; 02070 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02071 &objectTypeInitializer, 02072 (PSECURITY_DESCRIPTOR) NULL, 02073 &IoCompletionObjectType ))) { 02074 return FALSE; 02075 } 02076 02077 // 02078 // Create the object type for file objects. 02079 // 02080 02081 RtlInitUnicodeString( &nameString, L"File" ); 02082 objectTypeInitializer.DefaultPagedPoolCharge = IO_FILE_OBJECT_PAGED_POOL_CHARGE; 02083 objectTypeInitializer.DefaultNonPagedPoolCharge = IO_FILE_OBJECT_NON_PAGED_POOL_CHARGE + 02084 sizeof( FILE_OBJECT ); 02085 objectTypeInitializer.InvalidAttributes = OBJ_PERMANENT | OBJ_EXCLUSIVE | OBJ_OPENLINK; 02086 objectTypeInitializer.GenericMapping = IopFileMapping; 02087 objectTypeInitializer.ValidAccessMask = FILE_ALL_ACCESS; 02088 objectTypeInitializer.MaintainHandleCount = TRUE; 02089 objectTypeInitializer.CloseProcedure = IopCloseFile; 02090 objectTypeInitializer.DeleteProcedure = IopDeleteFile; 02091 objectTypeInitializer.ParseProcedure = IopParseFile; 02092 objectTypeInitializer.SecurityProcedure = IopGetSetSecurityObject; 02093 objectTypeInitializer.QueryNameProcedure = IopQueryName; 02094 objectTypeInitializer.UseDefaultObject = FALSE; 02095 02096 if (!NT_SUCCESS( ObCreateObjectType( &nameString, 02097 &objectTypeInitializer, 02098 (PSECURITY_DESCRIPTOR) NULL, 02099 &IoFileObjectType ))) { 02100 return FALSE; 02101 } 02102 02103 return TRUE; 02104 }

BOOLEAN IopCreateRootDirectories VOID   ) 
 

Definition at line 2155 of file ioinit.c.

References FALSE, L, NT_SUCCESS, NtClose(), NtCreateDirectoryObject(), NTSTATUS(), NULL, RtlInitUnicodeString(), TRUE, and VOID().

Referenced by IoInitSystem().

02161 : 02162 02163 This routine is invoked to create the object manager directory objects 02164 to contain the various device and file system driver objects. 02165 02166 Arguments: 02167 02168 None. 02169 02170 Return Value: 02171 02172 The function value is a BOOLEAN indicating whether or not the directory 02173 objects were successfully created. 02174 02175 02176 --*/ 02177 02178 { 02179 HANDLE handle; 02180 OBJECT_ATTRIBUTES objectAttributes; 02181 UNICODE_STRING nameString; 02182 NTSTATUS status; 02183 02184 // 02185 // Create the root directory object for the \Driver directory. 02186 // 02187 02188 RtlInitUnicodeString( &nameString, L"\\Driver" ); 02189 InitializeObjectAttributes( &objectAttributes, 02190 &nameString, 02191 OBJ_PERMANENT, 02192 (HANDLE) NULL, 02193 (PSECURITY_DESCRIPTOR) NULL ); 02194 02195 status = NtCreateDirectoryObject( &handle, 02196 DIRECTORY_ALL_ACCESS, 02197 &objectAttributes ); 02198 if (!NT_SUCCESS( status )) { 02199 return FALSE; 02200 } else { 02201 (VOID) NtClose( handle ); 02202 } 02203 02204 // 02205 // Create the root directory object for the \FileSystem directory. 02206 // 02207 02208 RtlInitUnicodeString( &nameString, L"\\FileSystem" ); 02209 02210 status = NtCreateDirectoryObject( &handle, 02211 DIRECTORY_ALL_ACCESS, 02212 &objectAttributes ); 02213 if (!NT_SUCCESS( status )) { 02214 return FALSE; 02215 } else { 02216 (VOID) NtClose( handle ); 02217 } 02218 02219 return TRUE; 02220 }

VOID IopFreeGroupTree PTREE_ENTRY  TreeEntry  ) 
 

Definition at line 2223 of file ioinit.c.

References ExFreePool(), _TREE_ENTRY::Left, _TREE_ENTRY::Right, and _TREE_ENTRY::Sibling.

Referenced by IoInitSystem().

02229 : 02230 02231 This routine is invoked to free a node from the group dependency tree. 02232 It is invoked the first time with the root of the tree, and thereafter 02233 recursively to walk the tree and remove the nodes. 02234 02235 Arguments: 02236 02237 TreeEntry - Supplies a pointer to the node to be freed. 02238 02239 Return Value: 02240 02241 None. 02242 02243 --*/ 02244 02245 { 02246 // 02247 // Simply walk the tree in ascending order from the bottom up and free 02248 // each node along the way. 02249 // 02250 02251 if (TreeEntry->Left) { 02252 IopFreeGroupTree( TreeEntry->Left ); 02253 } 02254 02255 if (TreeEntry->Sibling) { 02256 IopFreeGroupTree( TreeEntry->Sibling ); 02257 } 02258 02259 if (TreeEntry->Right) { 02260 IopFreeGroupTree( TreeEntry->Right ); 02261 } 02262 02263 // 02264 // All of the children and siblings for this node have been freed, so 02265 // now free this node as well. 02266 // 02267 02268 ExFreePool( TreeEntry ); 02269 }

VOID IopFreeGroupTree IN PTREE_ENTRY  TreeEntry  ) 
 

USHORT IopGetDriverTagPriority IN HANDLE  Servicehandle  ) 
 

Definition at line 4120 of file ioinit.c.

References ASSERT, ExFreePool(), IopGetRegistryValue(), IopOpenRegistryKeyEx(), IopRegistryDataToUnicodeString, KEY_VALUE_DATA, L, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, and USHORT.

Referenced by IopInitializeBootDrivers().

04126 : 04127 04128 This routine reads the Tag value of a driver and determine the tag's priority 04129 among its driver group. 04130 04131 Arguments: 04132 04133 ServiceHandle - specifies the handle of the driver's service key. 04134 04135 Return Value: 04136 04137 USHORT for priority. 04138 04139 --*/ 04140 04141 { 04142 NTSTATUS status; 04143 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 04144 PKEY_VALUE_FULL_INFORMATION keyValueInformation1; 04145 UNICODE_STRING groupName; 04146 HANDLE handle; 04147 USHORT index = (USHORT) -1; 04148 PULONG groupOrder; 04149 ULONG count, tag; 04150 04151 // 04152 // Open System\CurrentControlSet\Control\GroupOrderList 04153 // 04154 04155 PiWstrToUnicodeString(&groupName, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\GroupOrderList"); 04156 status = IopOpenRegistryKeyEx( &handle, 04157 NULL, 04158 &groupName, 04159 KEY_READ 04160 ); 04161 04162 if (!NT_SUCCESS( status )) { 04163 return index; 04164 } 04165 04166 // 04167 // Read service key's Group value 04168 // 04169 04170 status = IopGetRegistryValue (ServiceHandle, 04171 L"Group", 04172 &keyValueInformation); 04173 if (NT_SUCCESS(status)) { 04174 04175 // 04176 // Try to read what caller wants. 04177 // 04178 04179 if ((keyValueInformation->Type == REG_SZ) && 04180 (keyValueInformation->DataLength != 0)) { 04181 IopRegistryDataToUnicodeString(&groupName, 04182 (PWSTR)KEY_VALUE_DATA(keyValueInformation), 04183 keyValueInformation->DataLength 04184 ); 04185 } 04186 } else { 04187 04188 // 04189 // If we failed to read the Group value, or no Group value... 04190 // 04191 04192 NtClose(handle); 04193 return index; 04194 } 04195 04196 // 04197 // Read service key's Tag value 04198 // 04199 04200 status = IopGetRegistryValue (ServiceHandle, 04201 L"Tag", 04202 &keyValueInformation1); 04203 if (NT_SUCCESS(status)) { 04204 04205 // 04206 // Try to read what caller wants. 04207 // 04208 04209 if ((keyValueInformation1->Type == REG_DWORD) && 04210 (keyValueInformation1->DataLength != 0)) { 04211 tag = *(PULONG)KEY_VALUE_DATA(keyValueInformation1); 04212 } 04213 ExFreePool(keyValueInformation1); 04214 } else { 04215 04216 // 04217 // If we failed to read the Group value, or no Group value... 04218 // 04219 04220 ExFreePool(keyValueInformation); 04221 NtClose(handle); 04222 return index; 04223 } 04224 04225 // 04226 // Read group order list value for the driver's Group 04227 // 04228 04229 status = IopGetRegistryValue (handle, 04230 groupName.Buffer, 04231 &keyValueInformation1); 04232 ExFreePool(keyValueInformation); 04233 NtClose(handle); 04234 if (NT_SUCCESS(status)) { 04235 04236 // 04237 // Try to read what caller wants. 04238 // 04239 04240 if ((keyValueInformation1->Type == REG_BINARY) && 04241 (keyValueInformation1->DataLength != 0)) { 04242 groupOrder = (PULONG)KEY_VALUE_DATA(keyValueInformation1); 04243 count = *groupOrder; 04244 ASSERT((count + 1) * sizeof(ULONG) <= keyValueInformation1->DataLength); 04245 groupOrder++; 04246 for (index = 1; index <= count; index++) { 04247 if (tag == *groupOrder) { 04248 break; 04249 } else { 04250 groupOrder++; 04251 } 04252 } 04253 } 04254 ExFreePool(keyValueInformation1); 04255 } else { 04256 04257 // 04258 // If we failed to read the Group value, or no Group value... 04259 // 04260 04261 return index; 04262 } 04263 return index; 04264 }

NTSTATUS IopInitializeAttributesAndCreateObject IN PUNICODE_STRING  ObjectName,
IN OUT POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PDRIVER_OBJECT DriverObject
 

Definition at line 2272 of file ioinit.c.

References IoDriverObjectType, KernelMode, NTSTATUS(), NULL, ObCreateObject(), and ObjectAttributes.

Referenced by IopInitializeBuiltinDriver().

02280 : 02281 02282 This routine is invoked to initialize a set of object attributes and 02283 to create a driver object. 02284 02285 Arguments: 02286 02287 ObjectName - Supplies the name of the driver object. 02288 02289 ObjectAttributes - Supplies a pointer to the object attributes structure 02290 to be initialized. 02291 02292 DriverObject - Supplies a variable to receive a pointer to the resultant 02293 created driver object. 02294 02295 Return Value: 02296 02297 The function value is the final status of the operation. 02298 02299 --*/ 02300 02301 { 02302 NTSTATUS status; 02303 02304 // 02305 // Simply initialize the object attributes and create the driver object. 02306 // 02307 02308 InitializeObjectAttributes( ObjectAttributes, 02309 ObjectName, 02310 OBJ_PERMANENT | OBJ_CASE_INSENSITIVE, 02311 (HANDLE) NULL, 02312 (PSECURITY_DESCRIPTOR) NULL ); 02313 02314 status = ObCreateObject( KeGetPreviousMode(), 02315 IoDriverObjectType, 02316 ObjectAttributes, 02317 KernelMode, 02318 (PVOID) NULL, 02319 (ULONG) (sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )), 02320 0, 02321 0, 02322 (PVOID *)DriverObject ); 02323 return status; 02324 }

BOOLEAN IopInitializeBootDrivers IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
OUT PDRIVER_OBJECT PreviousDriver
 

Definition at line 2327 of file ioinit.c.

References ASSERT, BUS_DRIVER_GROUP, _REINIT_PACKET::Context, _DRIVER_EXTENSION::Count, _DRIVER_INFORMATION::DataTableEntry, DbgPrint, _DRIVER_OBJECT::DeviceObject, DRIVER_INFORMATION, _DRIVER_OBJECT::DriverExtension, _REINIT_PACKET::DriverObject, _DRIVER_INFORMATION::DriverObject, _REINIT_PACKET::DriverReinitializationRoutine, _TREE_ENTRY::DriversLoaded, _DRIVER_OBJECT::DriverUnload, DRVO_BOOTREINIT_REGISTERED, DRVO_REINIT_REGISTERED, DRVO_UNLOAD_INVOKED, ExAllocatePool, ExFreePool(), ExInterlockedRemoveHeadList(), _DRIVER_INFORMATION::Failed, FALSE, _DRIVER_OBJECT::Flags, IopAddDevicesToBootDriver(), IopAllocateBootResources(), IopBootConfigsReserved, IopBootDriverReinitializeQueueHead, IopCheckDependencies(), IopCreateArcNames(), IopDatabaseLock, IopGetDriverNameFromKeyNode(), IopGetDriverTagPriority(), IopGetGroupOrderIndex(), IopGetRegistryValue(), IopGroupIndex, IopGroupTable, IopInitHalResources, IopInitializeBuiltinDriver(), IopInitReservedResourceList, IopInsertDriverList(), IopIsLegacyDriver(), IopLookupGroupName(), IopMarkBootPartition(), IopNotifySetupDevices(), IopOpenRegistryKeyEx(), IopRequestDeviceAction(), IopReserveLegacyBootResources(), IopReserveResourcesRoutine, IopResourcesReleased, IopRootDeviceNode, IopStartTcpIpForRemoteBoot(), IopWaitForBootDevicesDeleted(), IopWaitForBootDevicesStarted(), IoRemoteBootClient, KeBugCheckEx(), L, _BOOT_DRIVER_LIST_ENTRY::LdrEntry, _DRIVER_INFORMATION::Link, MmCallDllInitialize(), NO_MORE_GROUP, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObDereferenceObject, ObMakeTemporaryObject(), ObReferenceObject, PagedPool, PDRIVER_INFORMATION, PDRIVER_INITIALIZE, PnpAsyncOk, PnPBootDriversInitialized, PnPBootDriversLoaded, _DRIVER_INFORMATION::Processed, PTREE_ENTRY, RawInitialize(), ReenumerateBootDevices, _BOOT_DRIVER_LIST_ENTRY::RegistryPath, RestartEnumeration, RtlInitUnicodeString(), _DRIVER_INFORMATION::ServiceHandle, SETUP_RESERVED_GROUP, START_CONTEXT, _DRIVER_INFORMATION::TagPosition, TRUE, USHORT, and VOID().

Referenced by IoInitSystem().

02334 : 02335 02336 This routine is invoked to initialize the boot drivers that were loaded 02337 by the OS Loader. The list of drivers is provided as part of the loader 02338 parameter block. 02339 02340 Arguments: 02341 02342 LoaderBlock - Supplies a pointer to the loader parameter block, created 02343 by the OS Loader. 02344 02345 Previous Driver - Supplies a variable to receive the address of the 02346 driver object chain created by initializing the drivers. 02347 02348 Return Value: 02349 02350 The function value is a BOOLEAN indicating whether or not the boot 02351 drivers were successfully initialized. 02352 02353 --*/ 02354 02355 { 02356 UNICODE_STRING completeName; 02357 UNICODE_STRING rawFsName; 02358 NTSTATUS status; 02359 PLIST_ENTRY nextEntry; 02360 PLIST_ENTRY entry; 02361 PREINIT_PACKET reinitEntry; 02362 PBOOT_DRIVER_LIST_ENTRY bootDriver; 02363 HANDLE keyHandle; 02364 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 02365 PDRIVER_OBJECT driverObject; 02366 USHORT i, j; 02367 PLDR_DATA_TABLE_ENTRY driverEntry; 02368 PLDR_DATA_TABLE_ENTRY dllEntry; 02369 UNICODE_STRING groupName; 02370 PTREE_ENTRY treeEntry; 02371 PDRIVER_INFORMATION driverInfo; 02372 START_CONTEXT startContext; 02373 BOOLEAN moreProcessing; 02374 BOOLEAN newDevice; 02375 BOOLEAN textModeSetup = FALSE; 02376 BOOLEAN bootReinitDriversFound; 02377 BOOLEAN bootConfigsOK; 02378 02379 UNREFERENCED_PARAMETER( PreviousDriver ); 02380 02381 // 02382 // Initialize the built-in RAW file system driver. 02383 // 02384 02385 RtlInitUnicodeString( &rawFsName, L"\\FileSystem\\RAW" ); 02386 RtlInitUnicodeString( &completeName, L"" ); 02387 if (!IopInitializeBuiltinDriver( &rawFsName, 02388 &completeName, 02389 RawInitialize, 02390 NULL, 02391 textModeSetup )) { 02392 #if DBG 02393 DbgPrint( "IOINIT: Failed to initialize RAW filsystem \n" ); 02394 02395 #endif 02396 02397 return FALSE; 02398 } 02399 02400 // 02401 // Determine number of group orders and build a list_entry array to link all the drivers 02402 // together based on their groups. 02403 // 02404 02405 IopGroupIndex = IopGetGroupOrderIndex(NULL); 02406 if (IopGroupIndex == NO_MORE_GROUP) { 02407 return FALSE; 02408 } 02409 02410 IopGroupTable = (PLIST_ENTRY) ExAllocatePool(PagedPool, IopGroupIndex * sizeof (LIST_ENTRY)); 02411 if (IopGroupTable == NULL) { 02412 return FALSE; 02413 } 02414 for (i = 0; i < IopGroupIndex; i++) { 02415 InitializeListHead(&IopGroupTable[i]); 02416 } 02417 02418 PnpAsyncOk = FALSE; 02419 02420 // 02421 // Call DllInitialize for driver dependent DLLs. 02422 // 02423 02424 nextEntry = LoaderBlock->LoadOrderListHead.Flink; 02425 while (nextEntry != &LoaderBlock->LoadOrderListHead) { 02426 dllEntry = CONTAINING_RECORD(nextEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks); 02427 if (dllEntry->Flags & LDRP_DRIVER_DEPENDENT_DLL) { 02428 (VOID)MmCallDllInitialize(dllEntry); 02429 } 02430 nextEntry = nextEntry->Flink; 02431 } 02432 // 02433 // Allocate pool to store driver's start information. 02434 // All the driver info records with the same group value will be linked into a list. 02435 // 02436 02437 nextEntry = LoaderBlock->BootDriverListHead.Flink; 02438 while (nextEntry != &LoaderBlock->BootDriverListHead) { 02439 bootDriver = CONTAINING_RECORD( nextEntry, 02440 BOOT_DRIVER_LIST_ENTRY, 02441 Link ); 02442 driverEntry = bootDriver->LdrEntry; 02443 driverInfo = (PDRIVER_INFORMATION) ExAllocatePool( 02444 PagedPool, sizeof(DRIVER_INFORMATION)); 02445 if (driverInfo) { 02446 RtlZeroMemory(driverInfo, sizeof(DRIVER_INFORMATION)); 02447 InitializeListHead(&driverInfo->Link); 02448 driverInfo->DataTableEntry = bootDriver; 02449 02450 // 02451 // Open the driver's registry key to find out if this is a 02452 // filesystem or a driver. 02453 // 02454 02455 status = IopOpenRegistryKeyEx( &keyHandle, 02456 (HANDLE)NULL, 02457 &bootDriver->RegistryPath, 02458 KEY_READ 02459 ); 02460 if (!NT_SUCCESS( status )) { 02461 ExFreePool(driverInfo); 02462 } else { 02463 driverInfo->ServiceHandle = keyHandle; 02464 j = IopGetGroupOrderIndex(keyHandle); 02465 if (j == SETUP_RESERVED_GROUP) { 02466 02467 textModeSetup = TRUE; 02468 02469 // 02470 // Special handling for setupdd.sys 02471 // 02472 02473 status = IopGetDriverNameFromKeyNode( keyHandle, 02474 &completeName ); 02475 if (NT_SUCCESS(status)) { 02476 driverObject = IopInitializeBuiltinDriver( 02477 &completeName, 02478 &bootDriver->RegistryPath, 02479 (PDRIVER_INITIALIZE) driverEntry->EntryPoint, 02480 driverEntry, 02481 textModeSetup ); 02482 ExFreePool( completeName.Buffer ); 02483 NtClose(keyHandle); 02484 ExFreePool(driverInfo); 02485 if (driverObject) { 02486 02487 // 02488 // Once we successfully initialized the setupdd.sys, we are ready 02489 // to notify it all the root enumerated devices. 02490 // 02491 02492 IopNotifySetupDevices(IopRootDeviceNode); 02493 } else { 02494 ExFreePool(IopGroupTable); 02495 return FALSE; 02496 } 02497 } 02498 02499 } else { 02500 driverInfo->TagPosition = IopGetDriverTagPriority(keyHandle); 02501 IopInsertDriverList(&IopGroupTable[j], driverInfo); 02502 } 02503 } 02504 } 02505 nextEntry = nextEntry->Flink; 02506 } 02507 02508 // 02509 // Process each driver base on its group. The group with lower index number (higher 02510 // priority) is processed first. 02511 // 02512 02513 for (i = 0; i < IopGroupIndex; i++) { 02514 nextEntry = IopGroupTable[i].Flink; 02515 while (nextEntry != &IopGroupTable[i]) { 02516 02517 driverInfo = CONTAINING_RECORD(nextEntry, DRIVER_INFORMATION, Link); 02518 keyHandle = driverInfo->ServiceHandle; 02519 bootDriver = driverInfo->DataTableEntry; 02520 driverEntry = bootDriver->LdrEntry; 02521 driverInfo->Processed = TRUE; 02522 02523 // 02524 // call the driver's driver entry 02525 // 02526 // See if this driver has an ObjectName value. If so, this value 02527 // overrides the default ("\Driver" or "\FileSystem"). 02528 // 02529 02530 status = IopGetDriverNameFromKeyNode( keyHandle, 02531 &completeName ); 02532 if (!NT_SUCCESS( status )) { 02533 02534 #if DBG 02535 DbgPrint( "IOINIT: Could not get driver name for %wZ\n", 02536 &bootDriver->RegistryPath ); 02537 #endif // DBG 02538 02539 driverInfo->Failed = TRUE; 02540 } else { 02541 02542 status = IopGetRegistryValue( keyHandle, 02543 L"Group", 02544 &keyValueInformation ); 02545 if (NT_SUCCESS( status )) { 02546 02547 if (keyValueInformation->DataLength) { 02548 groupName.Length = (USHORT) keyValueInformation->DataLength; 02549 groupName.MaximumLength = groupName.Length; 02550 groupName.Buffer = (PWSTR) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset); 02551 treeEntry = IopLookupGroupName( &groupName, TRUE ); 02552 } else { 02553 treeEntry = (PTREE_ENTRY) NULL; 02554 } 02555 ExFreePool( keyValueInformation ); 02556 } else { 02557 treeEntry = (PTREE_ENTRY) NULL; 02558 } 02559 02560 // 02561 // Check if this bus has a BOOT config. 02562 // Buses with BOOT configs allow assignment of BOOT configs on their level. 02563 // 02564 02565 bootConfigsOK = TRUE; 02566 status = IopGetRegistryValue( keyHandle, 02567 L"HasBootConfig", 02568 &keyValueInformation ); 02569 if (NT_SUCCESS(status)) { 02570 if (*(PULONG)((PUCHAR)keyValueInformation + keyValueInformation->DataOffset) == 0) { 02571 bootConfigsOK = FALSE; 02572 } 02573 ExFreePool(keyValueInformation); 02574 } 02575 02576 driverObject = NULL; 02577 if (IopCheckDependencies( keyHandle )) { 02578 // 02579 // The driver may already be initialized by IopInitializeBootFilterDriver 02580 // if it is boot filter driver. 02581 // If not, initialize it. 02582 // 02583 02584 driverObject = driverInfo->DriverObject; 02585 if (driverObject == NULL) { 02586 driverObject = IopInitializeBuiltinDriver( 02587 &completeName, 02588 &bootDriver->RegistryPath, 02589 (PDRIVER_INITIALIZE) driverEntry->EntryPoint, 02590 driverEntry, 02591 textModeSetup); 02592 // 02593 // Pnp might unload the driver before we get a chance to look at this. So take an extra 02594 // reference. 02595 // 02596 if (driverObject) { 02597 ObReferenceObject(driverObject); 02598 } 02599 } 02600 } 02601 if (driverObject) { 02602 if (treeEntry) { 02603 treeEntry->DriversLoaded++; 02604 } 02605 driverInfo->DriverObject = driverObject; 02606 02607 } else { 02608 driverInfo->Failed = TRUE; 02609 } 02610 ExFreePool( completeName.Buffer ); 02611 } 02612 if (!driverInfo->Failed) { 02613 02614 USHORT group; 02615 02616 IopAddDevicesToBootDriver(driverObject); 02617 02618 // 02619 // Scan the hardware tree looking for devices which need 02620 // resources or starting. 02621 // 02622 02623 IopRequestDeviceAction(NULL, ReenumerateBootDevices, NULL, (PNTSTATUS)&bootConfigsOK); 02624 02625 } 02626 02627 // 02628 // Before processing next boot driver, wait for IoRequestDeviceRemoval complete. 02629 // The driver to be processed may need the resources being released by 02630 // IoRequestDeviceRemoval. (For drivers report detected BOOT device if they fail to 02631 // get the resources in their DriverEntry. They will fail and we will bugcheck with 02632 // inaccessible boot device.) 02633 // 02634 02635 if (!IopWaitForBootDevicesDeleted()) { 02636 return FALSE; 02637 } 02638 02639 nextEntry = nextEntry->Flink; 02640 } 02641 02642 // 02643 // If we are done with Bus driver group, then it's time to reserved the Hal resources 02644 // and reserve boot resources 02645 // 02646 02647 if (i == BUS_DRIVER_GROUP) { 02648 if (textModeSetup == FALSE) { 02649 // 02650 // BUGBUG - There problems with Async ops, disable for now. 02651 // 02652 // PnpAsyncOk = TRUE; 02653 } 02654 02655 // 02656 // Reserve BOOT configs on Internal bus 0. 02657 // 02658 02659 IopReserveLegacyBootResources(Internal, 0); 02660 IopReserveResourcesRoutine = IopAllocateBootResources; 02661 ASSERT(IopInitHalResources == NULL); 02662 ASSERT(IopInitReservedResourceList == NULL); 02663 IopBootConfigsReserved = TRUE; 02664 02665 } 02666 } 02667 02668 // 02669 // If we started a network boot driver, then imitate what DHCP does 02670 // in sending IOCTLs. 02671 // 02672 02673 if (IoRemoteBootClient) { 02674 status = IopStartTcpIpForRemoteBoot(LoaderBlock); 02675 if (!NT_SUCCESS(status)) { 02676 KeBugCheckEx( NETWORK_BOOT_INITIALIZATION_FAILED, 02677 3, 02678 status, 02679 0, 02680 0 ); 02681 } 02682 } 02683 02684 // 02685 // Scan the hardware tree looking for devices which need 02686 // resources or starting. 02687 // 02688 PnPBootDriversLoaded = TRUE; 02689 IopResourcesReleased = TRUE; 02690 02691 IopRequestDeviceAction(NULL, RestartEnumeration, NULL, NULL); 02692 02693 // 02694 // If start irps are handled asynchronously, we need to make sure all the boot devices 02695 // started before continue. 02696 // 02697 02698 if (!IopWaitForBootDevicesStarted()) { 02699 return FALSE; 02700 } 02701 02702 bootReinitDriversFound = FALSE; 02703 02704 while (entry = ExInterlockedRemoveHeadList( &IopBootDriverReinitializeQueueHead, &IopDatabaseLock )) { 02705 bootReinitDriversFound = TRUE; 02706 reinitEntry = CONTAINING_RECORD( entry, REINIT_PACKET, ListEntry ); 02707 reinitEntry->DriverObject->DriverExtension->Count++; 02708 reinitEntry->DriverObject->Flags &= ~DRVO_BOOTREINIT_REGISTERED; 02709 reinitEntry->DriverReinitializationRoutine( reinitEntry->DriverObject, 02710 reinitEntry->Context, 02711 reinitEntry->DriverObject->DriverExtension->Count ); 02712 ExFreePool( reinitEntry ); 02713 } 02714 02715 // 02716 // If there were any drivers that registered for boot reinitialization, then 02717 // we need to wait one more time to make sure we catch any additional 02718 // devices that were created in response to the reinitialization callback. 02719 // 02720 02721 if (bootReinitDriversFound && !IopWaitForBootDevicesStarted()) { 02722 return FALSE; 02723 } 02724 02725 // 02726 // Link NT device names to ARC names now that all of the boot drivers 02727 // have intialized. 02728 // 02729 02730 IopCreateArcNames( LoaderBlock ); 02731 02732 // 02733 // Find and mark the boot partition device object so that if a subsequent 02734 // access or mount of the device during initialization occurs, an more 02735 // bugcheck can be produced that helps the user understand why the system 02736 // is failing to boot and run properly. This occurs when either one of the 02737 // device drivers or the file system fails to load, or when the file system 02738 // cannot mount the device for some other reason. 02739 // 02740 02741 if (!IopMarkBootPartition( LoaderBlock )) { 02742 return FALSE; 02743 } 02744 02745 // 02746 // BUGBUG - There problems with Async ops, disable for now. 02747 // 02748 // PnpAsyncOk = TRUE; 02749 PnPBootDriversInitialized = TRUE; 02750 02751 // 02752 // Go thru every driver that we initialized. If it supports AddDevice entry and 02753 // did not create any device object after we start it. We mark it as failure so 02754 // text mode setup knows this driver is not needed. 02755 // 02756 02757 for (i = 0; i < IopGroupIndex; i++) { 02758 while (IsListEmpty(&IopGroupTable[i]) == FALSE) { 02759 02760 BOOLEAN failed; 02761 02762 nextEntry = RemoveHeadList(&IopGroupTable[i]); 02763 driverInfo = CONTAINING_RECORD(nextEntry, DRIVER_INFORMATION, Link); 02764 driverObject = driverInfo->DriverObject; 02765 02766 if (textModeSetup && 02767 (driverInfo->Failed == FALSE) && 02768 !IopIsLegacyDriver(driverObject) && 02769 (driverObject->DeviceObject == NULL) && 02770 !(driverObject->Flags & DRVO_REINIT_REGISTERED)) { 02771 02772 // 02773 // If failed is not set and it's not a legacy driver and it has no device object 02774 // tread it as failure case. 02775 // 02776 02777 driverInfo->Failed = TRUE; 02778 02779 if (!(driverObject->Flags & DRVO_UNLOAD_INVOKED)) { 02780 driverObject->Flags |= DRVO_UNLOAD_INVOKED; 02781 if (driverObject->DriverUnload) { 02782 driverObject->DriverUnload(driverObject); 02783 } 02784 ObMakeTemporaryObject( driverObject ); // Reference taken while inserting into the object table. 02785 ObDereferenceObject(driverObject); // Reference taken when getting driver object pointer. 02786 } 02787 } 02788 if (driverObject) { 02789 ObDereferenceObject(driverObject); // Reference taken specifically for text mode setup. 02790 } 02791 02792 if (driverInfo->Failed) { 02793 driverInfo->DataTableEntry->LdrEntry->Flags |= LDRP_FAILED_BUILTIN_LOAD; 02794 } 02795 NtClose(driverInfo->ServiceHandle); 02796 ExFreePool(driverInfo); 02797 } 02798 } 02799 02800 ExFreePool(IopGroupTable); 02801 02802 // 02803 // Initialize the drivers necessary to dump all of physical memory to the 02804 // disk if the system is configured to do so. 02805 // 02806 02807 02808 return TRUE; 02809 }

PDRIVER_OBJECT IopInitializeBuiltinDriver IN PUNICODE_STRING  DriverName,
IN PUNICODE_STRING  RegistryPath,
IN PDRIVER_INITIALIZE  DriverInitializeRoutine,
IN PLDR_DATA_TABLE_ENTRY  TableEntry,
IN BOOLEAN  TextModeSetup
 

Definition at line 2812 of file ioinit.c.

References ASSERT, CmRegistryMachineHardwareDescriptionSystemName, DbgPrint, _DRIVER_OBJECT::DeviceObject, DriverEntry(), _DRIVER_OBJECT::DriverExtension, _DRIVER_OBJECT::DriverInit, _DRIVER_OBJECT::DriverName, _DRIVER_OBJECT::DriverSection, _DRIVER_OBJECT::DriverSize, _DRIVER_OBJECT::DriverStart, DRVO_LEGACY_DRIVER, DRVO_REINIT_REGISTERED, ExAllocatePool, exit, FALSE, _DRIVER_OBJECT::Flags, _DRIVER_OBJECT::HardwareDatabase, InbvIndicateProgress(), InitializeDriverObject, IoDriverObjectType, IopDeleteLegacyKey(), IopDriverLoadingFailed(), IopInitializeAttributesAndCreateObject(), IopIsAnyDeviceInstanceEnabled(), IopIsLegacyDriver(), IopOpenRegistryKeyEx(), IopPrepareDriverLoading(), IopReadyDeviceObjects(), KeQuerySystemTime(), KernelMode, NonPagedPool, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObDereferenceObject, ObInsertObject(), ObMakeTemporaryObject(), ObReferenceObjectByHandle(), PagedPool, PERFINFO_DRIVER_INIT, PERFINFO_DRIVER_INIT_COMPLETE, PsLoadedModuleList, RtlEqualString(), RtlImageNtHeader(), _DRIVER_EXTENSION::ServiceKeyName, TRUE, and USHORT.

Referenced by IopInitializeBootDrivers(), and IopLoadBootFilterDriver().

02822 : 02823 02824 This routine is invoked to initialize a built-in driver. 02825 02826 Arguments: 02827 02828 DriverName - Specifies the name to be used in creating the driver object. 02829 02830 RegistryPath - Specifies the path to be used by the driver to get to 02831 the registry. 02832 02833 DriverInitializeRoutine - Specifies the initialization entry point of 02834 the built-in driver. 02835 02836 DriverEntry - Specifies the driver data table entry to determine if the 02837 driver is a wdm driver. 02838 02839 TextModeSetup - Specifies if this is TextMode setup boot. 02840 02841 Return Value: 02842 02843 The function returns a pointer to a DRIVER_OBJECT if the built-in 02844 driver successfully initialized. Otherwise, a value of NULL is returned. 02845 02846 --*/ 02847 02848 { 02849 HANDLE handle; 02850 PDRIVER_OBJECT driverObject; 02851 PDRIVER_OBJECT tmpDriverObject; 02852 OBJECT_ATTRIBUTES objectAttributes; 02853 PWSTR buffer; 02854 NTSTATUS status; 02855 HANDLE serviceHandle; 02856 PWSTR pserviceName; 02857 USHORT serviceNameLength; 02858 PDRIVER_EXTENSION driverExtension; 02859 PIMAGE_NT_HEADERS ntHeaders; 02860 PVOID imageBase; 02861 #if DBG 02862 LARGE_INTEGER stime, etime; 02863 ULONG dtime; 02864 #endif 02865 PLIST_ENTRY entry; 02866 PLDR_DATA_TABLE_ENTRY DataTableEntry; 02867 02868 // 02869 // Begin by creating the driver object. 02870 // 02871 02872 status = IopInitializeAttributesAndCreateObject( DriverName, 02873 &objectAttributes, 02874 &driverObject ); 02875 if (!NT_SUCCESS( status )) { 02876 return NULL; 02877 } 02878 02879 // 02880 // Initialize the driver object. 02881 // 02882 02883 InitializeDriverObject( driverObject ); 02884 driverObject->DriverInit = DriverInitializeRoutine; 02885 02886 // 02887 // Insert the driver object into the object table. 02888 // 02889 02890 status = ObInsertObject( driverObject, 02891 NULL, 02892 FILE_READ_DATA, 02893 0, 02894 (PVOID *) NULL, 02895 &handle ); 02896 02897 if (!NT_SUCCESS( status )) { 02898 return NULL; 02899 } 02900 02901 // 02902 // Reference the handle and obtain a pointer to the driver object so that 02903 // the handle can be deleted without the object going away. 02904 // 02905 02906 status = ObReferenceObjectByHandle( handle, 02907 0, 02908 IoDriverObjectType, 02909 KernelMode, 02910 (PVOID *) &tmpDriverObject, 02911 (POBJECT_HANDLE_INFORMATION) NULL ); 02912 ASSERT(status == STATUS_SUCCESS); 02913 // 02914 // Fill in the DriverSection so the image will be automatically unloaded on 02915 // failures. We should use the entry from the PsModuleList. 02916 // 02917 02918 entry = PsLoadedModuleList.Flink; 02919 while (entry != &PsLoadedModuleList && DriverEntry) { 02920 DataTableEntry = CONTAINING_RECORD(entry, 02921 LDR_DATA_TABLE_ENTRY, 02922 InLoadOrderLinks); 02923 if (RtlEqualString((PSTRING)&DriverEntry->BaseDllName, 02924 (PSTRING)&DataTableEntry->BaseDllName, 02925 TRUE 02926 )) { 02927 driverObject->DriverSection = DataTableEntry; 02928 break; 02929 } 02930 entry = entry->Flink; 02931 } 02932 02933 // 02934 // The boot process takes a while loading drivers. Indicate that 02935 // progress is being made. 02936 // 02937 02938 InbvIndicateProgress(); 02939 02940 // 02941 // Get start and sice for the DriverObject. 02942 // 02943 02944 if (DriverEntry) { 02945 imageBase = DriverEntry->DllBase; 02946 ntHeaders = RtlImageNtHeader(imageBase); 02947 driverObject->DriverStart = imageBase; 02948 driverObject->DriverSize = ntHeaders->OptionalHeader.SizeOfImage; 02949 if (!(ntHeaders->OptionalHeader.DllCharacteristics & IMAGE_DLLCHARACTERISTICS_WDM_DRIVER)) { 02950 driverObject->Flags |= DRVO_LEGACY_DRIVER; 02951 } 02952 } else { 02953 ntHeaders = NULL; 02954 driverObject->Flags |= DRVO_LEGACY_DRIVER; 02955 } 02956 02957 // 02958 // Save the name of the driver so that it can be easily located by functions 02959 // such as error logging. 02960 // 02961 02962 buffer = ExAllocatePool( PagedPool, DriverName->MaximumLength + 2 ); 02963 02964 if (buffer) { 02965 driverObject->DriverName.Buffer = buffer; 02966 driverObject->DriverName.MaximumLength = DriverName->MaximumLength; 02967 driverObject->DriverName.Length = DriverName->Length; 02968 02969 RtlCopyMemory( driverObject->DriverName.Buffer, 02970 DriverName->Buffer, 02971 DriverName->MaximumLength ); 02972 buffer[DriverName->Length >> 1] = (WCHAR) '\0'; 02973 } 02974 02975 // 02976 // Save the name of the service key so that it can be easily located by PnP 02977 // mamager. 02978 // 02979 02980 driverExtension = driverObject->DriverExtension; 02981 if (RegistryPath && RegistryPath->Length != 0) { 02982 pserviceName = RegistryPath->Buffer + RegistryPath->Length / sizeof (WCHAR) - 1; 02983 if (*pserviceName == OBJ_NAME_PATH_SEPARATOR) { 02984 pserviceName--; 02985 } 02986 serviceNameLength = 0; 02987 while (pserviceName != RegistryPath->Buffer) { 02988 if (*pserviceName == OBJ_NAME_PATH_SEPARATOR) { 02989 pserviceName++; 02990 break; 02991 } else { 02992 serviceNameLength += sizeof(WCHAR); 02993 pserviceName--; 02994 } 02995 } 02996 if (pserviceName == RegistryPath->Buffer) { 02997 serviceNameLength += sizeof(WCHAR); 02998 } 02999 buffer = ExAllocatePool( NonPagedPool, serviceNameLength + sizeof(UNICODE_NULL) ); 03000 03001 if (buffer) { 03002 driverExtension->ServiceKeyName.Buffer = buffer; 03003 driverExtension->ServiceKeyName.MaximumLength = serviceNameLength + sizeof(UNICODE_NULL); 03004 driverExtension->ServiceKeyName.Length = serviceNameLength; 03005 03006 RtlCopyMemory( driverExtension->ServiceKeyName.Buffer, 03007 pserviceName, 03008 serviceNameLength ); 03009 buffer[driverExtension->ServiceKeyName.Length >> 1] = UNICODE_NULL; 03010 } else { 03011 status = STATUS_INSUFFICIENT_RESOURCES; 03012 driverExtension->ServiceKeyName.Buffer = NULL; 03013 driverExtension->ServiceKeyName.Length = 0; 03014 goto exit; 03015 } 03016 03017 // 03018 // Prepare driver initialization 03019 // 03020 03021 status = IopOpenRegistryKeyEx( &serviceHandle, 03022 NULL, 03023 RegistryPath, 03024 KEY_ALL_ACCESS 03025 ); 03026 if (NT_SUCCESS(status)) { 03027 status = IopPrepareDriverLoading(&driverExtension->ServiceKeyName, 03028 serviceHandle, 03029 ntHeaders); 03030 NtClose(serviceHandle); 03031 if (!NT_SUCCESS(status)) { 03032 goto exit; 03033 } 03034 } else { 03035 goto exit; 03036 } 03037 } else { 03038 driverExtension->ServiceKeyName.Buffer = NULL; 03039 driverExtension->ServiceKeyName.MaximumLength = 0; 03040 driverExtension->ServiceKeyName.Length = 0; 03041 } 03042 03043 // 03044 // Load the Registry information in the appropriate fields of the device 03045 // object. 03046 // 03047 03048 driverObject->HardwareDatabase = &CmRegistryMachineHardwareDescriptionSystemName; 03049 03050 #if DBG 03051 KeQuerySystemTime (&stime); 03052 #endif 03053 03054 // 03055 // Now invoke the driver's initialization routine to initialize itself. 03056 // 03057 03058 PERFINFO_DRIVER_INIT( driverObject); 03059 03060 status = driverObject->DriverInit( driverObject, RegistryPath ); 03061 03062 PERFINFO_DRIVER_INIT_COMPLETE( driverObject); 03063 03064 #if DBG 03065 03066 // 03067 // If DriverInit took longer than 5 seconds or the driver did not load, 03068 // print a message. 03069 // 03070 03071 KeQuerySystemTime (&etime); 03072 dtime = (ULONG) ((etime.QuadPart - stime.QuadPart) / 1000000); 03073 03074 if (dtime > 50 || !NT_SUCCESS( status )) { 03075 if (dtime < 10) { 03076 DbgPrint( "IOINIT: Built-in driver %wZ failed to initialize - %lX\n", 03077 DriverName, status ); 03078 03079 } else { 03080 DbgPrint( "IOINIT: Built-in driver %wZ took %d.%ds to ", 03081 DriverName, dtime/10, dtime%10 ); 03082 03083 if (NT_SUCCESS( status )) { 03084 DbgPrint ("initialize\n"); 03085 } else { 03086 DbgPrint ("fail initialization - %lX\n", status); 03087 } 03088 } 03089 } 03090 #endif 03091 exit: 03092 NtClose( handle ); 03093 03094 // 03095 // If we load the driver because we think it is a legacy driver and 03096 // it does not create any device object in its DriverEntry. We will 03097 // unload this driver. 03098 // 03099 03100 if (NT_SUCCESS(status) && !IopIsLegacyDriver(driverObject)) { 03101 if (driverObject->DeviceObject == NULL && 03102 driverExtension->ServiceKeyName.Buffer && 03103 !IopIsAnyDeviceInstanceEnabled(&driverExtension->ServiceKeyName, NULL, FALSE)) { 03104 if (TextModeSetup && !(driverObject->Flags & DRVO_REINIT_REGISTERED)) { 03105 03106 // 03107 // Clean up but leave driver object. Because it may be needed later. 03108 // After boot driver phase completes, we will process all the driver objects 03109 // which still have no device to control. 03110 // 03111 03112 IopDriverLoadingFailed(NULL, &driverObject->DriverExtension->ServiceKeyName); 03113 } 03114 } else { 03115 03116 // 03117 // Start the devices controlled by the driver and enumerate them 03118 // At this point, we know there is at least one device controlled by the driver. 03119 // 03120 03121 IopDeleteLegacyKey(driverObject); 03122 } 03123 } 03124 03125 if (NT_SUCCESS( status )) { 03126 IopReadyDeviceObjects( driverObject ); 03127 return driverObject; 03128 } else { 03129 if (status != STATUS_PLUGPLAY_NO_DEVICE) { 03130 03131 // 03132 // if STATUS_PLUGPLAY_NO_DEVICE, the driver was disable by hardware profile. 03133 // 03134 03135 IopDriverLoadingFailed(NULL, &driverObject->DriverExtension->ServiceKeyName); 03136 ObMakeTemporaryObject( driverObject ); 03137 ObDereferenceObject ( driverObject ); 03138 } 03139 return NULL; 03140 } 03141 }

VOID IopInitializeData VOID   ) 
 

BOOLEAN IopInitializeSingleBootDriver IN HANDLE  KeyHandle,
IN PBOOT_DRIVER_LIST_ENTRY  BootDriver,
OUT PUNICODE_STRING DriverName  OPTIONAL
 

BOOLEAN IopInitializeSystemDrivers VOID   ) 
 

Definition at line 3146 of file ioinit.c.

References _START_CONTEXT::AddContext, CmGetSystemDriverList(), _TREE_ENTRY::DriversLoaded, _ADD_CONTEXT::DriverStartType, ExFreePool(), FALSE, _ADD_CONTEXT::GroupsToStart, _ADD_CONTEXT::GroupToStartNext, InbvIndicateProgress(), IopCheckDependencies(), IopGetDriverNameFromKeyNode(), IopGetRegistryValue(), IopLoadDriver(), IopLookupGroupName(), IopOpenRegistryKeyEx(), IopProcessAddDevices(), IopProcessAssignResources(), IopProcessStartDevices(), IopReferenceDriverObjectByName(), IopRootDeviceNode, KEY_VALUE_DATA, L, _START_CONTEXT::LoadDriver, _START_CONTEXT::NewDevice, NO_MORE_GROUP, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, PnPInitialized, PTREE_ENTRY, RtlFreeUnicodeString(), TRUE, and USHORT.

Referenced by IoInitSystem().

03152 : 03153 03154 This routine is invoked to load and initialize all of the drivers that 03155 are supposed to be loaded during Phase 1 initialization of the I/O 03156 system. This is accomplished by calling the Configuration Manager to 03157 get a NULL-terminated array of handles to the open keys for each driver 03158 that is to be loaded, and then loading and initializing the driver. 03159 03160 Arguments: 03161 03162 None. 03163 03164 Return Value: 03165 03166 The function value is a BOOLEAN indicating whether or not the drivers 03167 were successfully loaded and initialized. 03168 03169 --*/ 03170 03171 { 03172 BOOLEAN newDevice, moreProcessing; 03173 NTSTATUS status; 03174 PHANDLE driverList; 03175 PHANDLE savedList; 03176 HANDLE enumHandle; 03177 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 03178 UNICODE_STRING groupName, enumName; 03179 PTREE_ENTRY treeEntry; 03180 UNICODE_STRING driverName; 03181 PDRIVER_OBJECT driverObject; 03182 START_CONTEXT startContext; 03183 03184 // 03185 // Scan the device node tree to process any device which have been enumerated 03186 // but not been added/started. 03187 // 03188 03189 startContext.LoadDriver = TRUE; 03190 startContext.AddContext.DriverStartType = SERVICE_DEMAND_START; 03191 03192 IopProcessAddDevices(IopRootDeviceNode, NO_MORE_GROUP, SERVICE_DEMAND_START); 03193 03194 // 03195 // Process the whole device tree to assign resources to those devices who 03196 // have been successfully added to their drivers. 03197 // 03198 03199 newDevice = TRUE; 03200 startContext.AddContext.GroupsToStart = NO_MORE_GROUP; 03201 startContext.AddContext.GroupToStartNext = NO_MORE_GROUP; 03202 while (newDevice || moreProcessing) { 03203 startContext.NewDevice = FALSE; 03204 moreProcessing = IopProcessAssignResources(IopRootDeviceNode, FALSE, TRUE); 03205 03206 // 03207 // Process the whole device tree to start those devices who have been allocated 03208 // resources and waiting to be started. 03209 // Note, the IopProcessStartDevices routine may enumerate new devices. 03210 // 03211 03212 IopProcessStartDevices(IopRootDeviceNode, &startContext); 03213 newDevice = startContext.NewDevice; 03214 } 03215 03216 // 03217 // Walk thru the service list to load the remaining system start drivers. 03218 // (Most likely these drivers are software drivers.) 03219 // 03220 03221 // 03222 // Get the list of drivers that are to be loaded during this phase of 03223 // system initialization, and invoke each driver in turn. Ensure that 03224 // the list really exists, otherwise get out now. 03225 // 03226 03227 if (!(driverList = CmGetSystemDriverList())) { 03228 return TRUE; 03229 } 03230 03231 // 03232 // Walk the entire list, loading each of the drivers if not already loaded, 03233 // until there are no more drivers in the list. 03234 // 03235 03236 for (savedList = driverList; *driverList; driverList++) { 03237 03238 // 03239 // Now check if the driver has been loaded already. 03240 // get the name of the driver object first ... 03241 // 03242 03243 status = IopGetDriverNameFromKeyNode( *driverList, 03244 &driverName ); 03245 if (NT_SUCCESS( status )) { 03246 03247 driverObject = IopReferenceDriverObjectByName(&driverName); 03248 RtlFreeUnicodeString(&driverName); 03249 if (driverObject) { 03250 03251 // 03252 // Driver was loaded already. Dereference the driver object 03253 // and skip it. 03254 // 03255 03256 ObDereferenceObject(driverObject); 03257 continue; 03258 } 03259 } 03260 03261 // 03262 // Open registry ServiceKeyName\Enum branch to check if the driver was 03263 // loaded before but failed. 03264 // 03265 03266 PiWstrToUnicodeString(&enumName, REGSTR_KEY_ENUM); 03267 status = IopOpenRegistryKeyEx( &enumHandle, 03268 *driverList, 03269 &enumName, 03270 KEY_READ 03271 ); 03272 03273 if (NT_SUCCESS( status )) { 03274 03275 ULONG startFailed = 0; 03276 03277 status = IopGetRegistryValue(enumHandle, L"INITSTARTFAILED", &keyValueInformation); 03278 03279 if (NT_SUCCESS( status )) { 03280 if (keyValueInformation->DataLength) { 03281 startFailed = *(PULONG)KEY_VALUE_DATA(keyValueInformation); 03282 } 03283 ExFreePool( keyValueInformation ); 03284 } 03285 ZwClose(enumHandle); 03286 if (startFailed != 0) { 03287 continue; 03288 } 03289 } 03290 03291 // 03292 // The driver is not loaded yet. Load it ... 03293 // 03294 03295 status = IopGetRegistryValue( *driverList, 03296 L"Group", 03297 &keyValueInformation ); 03298 if (NT_SUCCESS( status )) { 03299 if (keyValueInformation->DataLength) { 03300 groupName.Length = (USHORT) keyValueInformation->DataLength; 03301 groupName.MaximumLength = groupName.Length; 03302 groupName.Buffer = (PWSTR) ((PUCHAR) keyValueInformation + keyValueInformation->DataOffset); 03303 treeEntry = IopLookupGroupName( &groupName, TRUE ); 03304 } else { 03305 treeEntry = (PTREE_ENTRY) NULL; 03306 } 03307 ExFreePool( keyValueInformation ); 03308 } else { 03309 treeEntry = (PTREE_ENTRY) NULL; 03310 } 03311 03312 if (IopCheckDependencies( *driverList )) { 03313 if (NT_SUCCESS( IopLoadDriver( *driverList, TRUE ) )) { 03314 if (treeEntry) { 03315 treeEntry->DriversLoaded++; 03316 } 03317 } 03318 } 03319 03320 // 03321 // The boot process takes a while loading drivers. Indicate that 03322 // progress is being made. 03323 // 03324 03325 InbvIndicateProgress(); 03326 03327 } 03328 03329 // 03330 // Finally, free the pool that was allocated for the list and return 03331 // an indicator the load operation worked. 03332 // 03333 03334 ExFreePool( (PVOID) savedList ); 03335 03336 // 03337 // Walk the device tree again to enumerate any devices reported after the system drivers 03338 // started. 03339 // 03340 03341 startContext.LoadDriver = TRUE; 03342 startContext.AddContext.DriverStartType = SERVICE_DEMAND_START; 03343 03344 IopProcessAddDevices(IopRootDeviceNode, NO_MORE_GROUP, SERVICE_DEMAND_START); 03345 03346 // 03347 // Process the whole device tree to assign resources to those devices who 03348 // have been successfully added to their drivers. 03349 // 03350 03351 newDevice = TRUE; 03352 startContext.AddContext.GroupsToStart = NO_MORE_GROUP; 03353 startContext.AddContext.GroupToStartNext = NO_MORE_GROUP; 03354 do { 03355 startContext.NewDevice = FALSE; 03356 moreProcessing = IopProcessAssignResources(IopRootDeviceNode, newDevice, TRUE); 03357 03358 // 03359 // Process the whole device tree to start those devices who have been allocated 03360 // resources and waiting to be started. 03361 // Note, the IopProcessStartDevices routine may enumerate new devices. 03362 // 03363 03364 IopProcessStartDevices(IopRootDeviceNode, &startContext); 03365 newDevice = startContext.NewDevice; 03366 } while (newDevice || moreProcessing) ; 03367 03368 // 03369 // Mark pnp has completed the driver loading for both system and 03370 // autoload drivers. 03371 // 03372 03373 PnPInitialized = TRUE; 03374 03375 return TRUE; 03376 }

VOID IopInsertDriverList IN PLIST_ENTRY  ListHead,
IN PDRIVER_INFORMATION  DriverInfo
 

Definition at line 4267 of file ioinit.c.

References PDRIVER_INFORMATION, and _DRIVER_INFORMATION::TagPosition.

Referenced by IopInitializeBootDrivers().

04274 : 04275 04276 This routine reads the Tag value of a driver and determine the tag's priority 04277 among its driver group. 04278 04279 Arguments: 04280 04281 ServiceHandle - specifies the handle of the driver's service key. 04282 04283 Return Value: 04284 04285 USHORT for priority. 04286 04287 --*/ 04288 04289 { 04290 PLIST_ENTRY nextEntry; 04291 PDRIVER_INFORMATION info; 04292 04293 nextEntry = ListHead->Flink; 04294 while (nextEntry != ListHead) { 04295 info = CONTAINING_RECORD(nextEntry, DRIVER_INFORMATION, Link); 04296 04297 // 04298 // Scan the driver info list to find the driver whose priority is 04299 // lower than current driver's. 04300 // (Lower TagPosition value means higher Priority) 04301 // 04302 04303 if (info->TagPosition > DriverInfo->TagPosition) { 04304 break; 04305 } 04306 nextEntry = nextEntry->Flink; 04307 } 04308 04309 // 04310 // Insert the Driver info to the front of the nextEntry 04311 // 04312 04313 nextEntry = nextEntry->Blink; 04314 InsertHeadList(nextEntry, &DriverInfo->Link); 04315 }

PDRIVER_OBJECT IopLoadBootFilterDriver IN PUNICODE_STRING  DriverName,
IN ULONG  GroupIndex
 

Definition at line 4654 of file ioinit.c.

References _DRIVER_INFORMATION::DataTableEntry, _DRIVER_INFORMATION::DriverObject, ExFreePool(), FALSE, IopGetDriverNameFromKeyNode(), IopGroupIndex, IopGroupTable, IopInitializeBuiltinDriver(), _BOOT_DRIVER_LIST_ENTRY::LdrEntry, NT_SUCCESS, NTSTATUS(), NULL, ObReferenceObject, PDRIVER_INFORMATION, PDRIVER_INITIALIZE, _DRIVER_INFORMATION::Processed, _BOOT_DRIVER_LIST_ENTRY::RegistryPath, RtlEqualUnicodeString(), _DRIVER_INFORMATION::ServiceHandle, and TRUE.

Referenced by IopCallDriverAddDeviceQueryRoutine().

04661 : 04662 04663 This initializes boot filter drivers. 04664 04665 Arguments: 04666 04667 DriverName - specifies the name of the driver to be initialized. 04668 04669 GroupIndex - specifies the Driver's group index (could be anything) 04670 04671 Return Value: 04672 04673 PDRIVER_OBJECT 04674 04675 --*/ 04676 04677 { 04678 PDRIVER_OBJECT driverObject = NULL; 04679 PLIST_ENTRY nextEntry; 04680 PDRIVER_INFORMATION driverInfo; 04681 UNICODE_STRING completeName; 04682 PBOOT_DRIVER_LIST_ENTRY bootDriver; 04683 PLDR_DATA_TABLE_ENTRY driverEntry; 04684 HANDLE keyHandle; 04685 NTSTATUS status; 04686 04687 if (IopGroupTable == NULL || GroupIndex >= IopGroupIndex) { 04688 04689 // 04690 // If we have not reached the boot driver initialization phase or 04691 // the filter driver is not a boot driver. 04692 // 04693 04694 return driverObject; 04695 } 04696 04697 // 04698 // Go thru every driver that we initialized. If it supports AddDevice entry and 04699 // did not create any device object after we start it. We mark it as failure so 04700 // text mode setup knows this driver is not needed. 04701 // 04702 04703 nextEntry = IopGroupTable[GroupIndex].Flink; 04704 while (nextEntry != &IopGroupTable[GroupIndex]) { 04705 04706 driverInfo = CONTAINING_RECORD(nextEntry, DRIVER_INFORMATION, Link); 04707 if (driverInfo->Processed == FALSE) { 04708 04709 keyHandle = driverInfo->ServiceHandle; 04710 04711 status = IopGetDriverNameFromKeyNode( keyHandle, 04712 &completeName ); 04713 if (NT_SUCCESS( status )) { 04714 if (RtlEqualUnicodeString(DriverName, 04715 &completeName, 04716 TRUE)) { // case-insensitive 04717 04718 bootDriver = driverInfo->DataTableEntry; 04719 driverEntry = bootDriver->LdrEntry; 04720 04721 driverObject = IopInitializeBuiltinDriver( 04722 &completeName, 04723 &bootDriver->RegistryPath, 04724 (PDRIVER_INITIALIZE) driverEntry->EntryPoint, 04725 driverEntry, 04726 FALSE); 04727 driverInfo->DriverObject = driverObject; 04728 driverInfo->Processed = TRUE; 04729 // 04730 // Pnp might unload the driver before we get a chance to look at this. So take an extra 04731 // reference. 04732 // 04733 if (driverObject) { 04734 ObReferenceObject(driverObject); 04735 } 04736 ExFreePool(completeName.Buffer); 04737 break; 04738 } 04739 ExFreePool(completeName.Buffer); 04740 } 04741 } 04742 04743 nextEntry = nextEntry->Flink; 04744 } 04745 return driverObject; 04746 } #if 0

NTSTATUS IopLogErrorEvent IN ULONG  SequenceNumber,
IN ULONG  UniqueErrorValue,
IN NTSTATUS  FinalStatus,
IN NTSTATUS  SpecificIOStatus,
IN ULONG  LengthOfInsert1,
IN PWCHAR  Insert1,
IN ULONG  LengthOfInsert2,
IN PWCHAR  Insert2
 

Definition at line 4393 of file ioinit.c.

References IoAllocateErrorLogEntry(), IopErrorLogObject, IoWriteErrorLogEntry(), NULL, and USHORT.

Referenced by IopCompleteDumpInitialization(), IopConfigureCrashDump(), IopGetDumpStack(), and IopInitializeDCB().

04406 : 04407 04408 This routine allocates an error log entry, copies the supplied data 04409 to it, and requests that it be written to the error log file. 04410 04411 Arguments: 04412 SequenceNumber - A value that is unique to an IRP over the life of the irp in 04413 this driver. - 0 generally means an error not associated with an IRP 04414 04415 UniqueErrorValue - A unique long word that identifies the particular 04416 call to this function. 04417 04418 FinalStatus - The final status given to the irp that was associated 04419 with this error. If this log entry is being made during one of 04420 the retries this value will be STATUS_SUCCESS. 04421 04422 SpecificIOStatus - The IO status for a particular error. 04423 04424 LengthOfInsert1 - The length in bytes (including the terminating NULL) 04425 of the first insertion string. 04426 04427 Insert1 - The first insertion string. 04428 04429 LengthOfInsert2 - The length in bytes (including the terminating NULL) 04430 of the second insertion string. NOTE, there must 04431 be a first insertion string for their to be 04432 a second insertion string. 04433 04434 Insert2 - The second insertion string. 04435 04436 Return Value: 04437 04438 STATUS_SUCCESS - Success 04439 STATUS_INVALID_HANDLE - Uninitialized error log device object 04440 STATUS_NO_DATA_DETECTED - NULL Error log entry 04441 04442 --*/ 04443 04444 { 04445 PIO_ERROR_LOG_PACKET errorLogEntry; 04446 PUCHAR ptrToFirstInsert; 04447 PUCHAR ptrToSecondInsert; 04448 04449 if (!IopErrorLogObject) { 04450 return(STATUS_INVALID_HANDLE); 04451 } 04452 04453 04454 errorLogEntry = IoAllocateErrorLogEntry( 04455 IopErrorLogObject, 04456 (UCHAR)( sizeof(IO_ERROR_LOG_PACKET) + 04457 LengthOfInsert1 + 04458 LengthOfInsert2) ); 04459 04460 if ( errorLogEntry != NULL ) { 04461 04462 errorLogEntry->ErrorCode = SpecificIOStatus; 04463 errorLogEntry->SequenceNumber = SequenceNumber; 04464 errorLogEntry->MajorFunctionCode = 0; 04465 errorLogEntry->RetryCount = 0; 04466 errorLogEntry->UniqueErrorValue = UniqueErrorValue; 04467 errorLogEntry->FinalStatus = FinalStatus; 04468 errorLogEntry->DumpDataSize = 0; 04469 04470 ptrToFirstInsert = (PUCHAR)&errorLogEntry->DumpData[0]; 04471 04472 ptrToSecondInsert = ptrToFirstInsert + LengthOfInsert1; 04473 04474 if (LengthOfInsert1) { 04475 04476 errorLogEntry->NumberOfStrings = 1; 04477 errorLogEntry->StringOffset = (USHORT)(ptrToFirstInsert - 04478 (PUCHAR)errorLogEntry); 04479 RtlCopyMemory( 04480 ptrToFirstInsert, 04481 Insert1, 04482 LengthOfInsert1 04483 ); 04484 04485 if (LengthOfInsert2) { 04486 04487 errorLogEntry->NumberOfStrings = 2; 04488 RtlCopyMemory( 04489 ptrToSecondInsert, 04490 Insert2, 04491 LengthOfInsert2 04492 ); 04493 04494 } //LenghtOfInsert2 04495 04496 } // LenghtOfInsert1 04497 04498 IoWriteErrorLogEntry(errorLogEntry); 04499 return(STATUS_SUCCESS); 04500 04501 } // errorLogEntry != NULL 04502 04503 return(STATUS_NO_DATA_DETECTED); 04504 04505 } //IopLogErrorEvent

PTREE_ENTRY IopLookupGroupName IN PUNICODE_STRING  GroupName,
IN BOOLEAN  Insert
 

Definition at line 3379 of file ioinit.c.

References _TREE_ENTRY::GroupName, IopCreateEntry(), IopGroupListHead, _TREE_ENTRY::Left, NULL, PTREE_ENTRY, _TREE_ENTRY::Right, RtlEqualUnicodeString(), _TREE_ENTRY::Sibling, and TRUE.

Referenced by IopCheckDependencies(), IopInitializeBootDrivers(), and IopInitializeSystemDrivers().

03386 : 03387 03388 This routine looks up a group entry in the group load tree and either 03389 returns a pointer to it, or optionally creates the entry and inserts 03390 it into the tree. 03391 03392 Arguments: 03393 03394 GroupName - The name of the group to look up, or insert. 03395 03396 Insert - Indicates whether or not an entry is to be created and inserted 03397 into the tree if the name does not already exist. 03398 03399 Return Value: 03400 03401 The function value is a pointer to the entry for the specified group 03402 name, or NULL. 03403 03404 --*/ 03405 03406 { 03407 PTREE_ENTRY treeEntry; 03408 PTREE_ENTRY previousEntry; 03409 03410 // 03411 // Begin by determining whether or not there are any entries in the tree 03412 // whatsoever. If not, and it is OK to insert, then insert this entry 03413 // into the tree. 03414 // 03415 03416 if (!IopGroupListHead) { 03417 if (!Insert) { 03418 return (PTREE_ENTRY) NULL; 03419 } else { 03420 IopGroupListHead = IopCreateEntry( GroupName ); 03421 return IopGroupListHead; 03422 } 03423 } 03424 03425 // 03426 // The tree is not empty, so actually attempt to do a lookup. 03427 // 03428 03429 treeEntry = IopGroupListHead; 03430 03431 for (;;) { 03432 if (GroupName->Length < treeEntry->GroupName.Length) { 03433 if (treeEntry->Left) { 03434 treeEntry = treeEntry->Left; 03435 } else { 03436 if (!Insert) { 03437 return (PTREE_ENTRY) NULL; 03438 } else { 03439 treeEntry->Left = IopCreateEntry( GroupName ); 03440 return treeEntry->Left; 03441 } 03442 03443 } 03444 } else if (GroupName->Length > treeEntry->GroupName.Length) { 03445 if (treeEntry->Right) { 03446 treeEntry = treeEntry->Right; 03447 } else { 03448 if (!Insert) { 03449 return (PTREE_ENTRY) NULL; 03450 } else { 03451 treeEntry->Right = IopCreateEntry( GroupName ); 03452 return treeEntry->Right; 03453 } 03454 } 03455 } else { 03456 if (!RtlEqualUnicodeString( GroupName, &treeEntry->GroupName, TRUE )) { 03457 previousEntry = treeEntry; 03458 while (treeEntry->Sibling) { 03459 treeEntry = treeEntry->Sibling; 03460 if (RtlEqualUnicodeString( GroupName, &treeEntry->GroupName, TRUE )) { 03461 return treeEntry; 03462 } 03463 previousEntry = previousEntry->Sibling; 03464 } 03465 if (!Insert) { 03466 return (PTREE_ENTRY) NULL; 03467 } else { 03468 previousEntry->Sibling = IopCreateEntry( GroupName ); 03469 return previousEntry->Sibling; 03470 } 03471 } else { 03472 return treeEntry; 03473 } 03474 } 03475 } 03476 }

BOOLEAN IopMarkBootPartition IN PLOADER_PARAMETER_BLOCK  LoaderBlock  ) 
 

Definition at line 3479 of file ioinit.c.

References CHAR, DO_SYSTEM_BOOT_PARTITION, FALSE, IoFileObjectType, IopErrorLogObject, KeBugCheckEx(), KernelMode, NT_SUCCESS, NtClose(), NTSTATUS(), NULL, ObDereferenceObject, ObReferenceObject, ObReferenceObjectByHandle(), RtlAnsiStringToUnicodeString(), RtlFreeUnicodeString(), RtlInitAnsiString(), sprintf(), TRUE, and ZwOpenFile().

Referenced by IopInitializeBootDrivers().

03485 : 03486 03487 This routine is invoked to locate and mark the boot partition device object 03488 as a boot device so that subsequent operations can fail more cleanly and 03489 with a better explanation of why the system failed to boot and run properly. 03490 03491 Arguments: 03492 03493 LoaderBlock - Supplies a pointer to the loader parameter block created 03494 by the OS Loader during the boot process. This structure contains 03495 the various system partition and boot device names and paths. 03496 03497 Return Value: 03498 03499 The function value is TRUE if everything worked, otherwise FALSE. 03500 03501 Notes: 03502 03503 If the boot partition device object cannot be found, then the system will 03504 bugcheck. 03505 03506 --*/ 03507 03508 { 03509 OBJECT_ATTRIBUTES objectAttributes; 03510 STRING deviceNameString; 03511 UCHAR deviceNameBuffer[256]; 03512 UNICODE_STRING deviceNameUnicodeString; 03513 NTSTATUS status; 03514 HANDLE fileHandle; 03515 IO_STATUS_BLOCK ioStatus; 03516 PFILE_OBJECT fileObject; 03517 CHAR ArcNameFmt[12]; 03518 03519 ArcNameFmt[0] = '\\'; 03520 ArcNameFmt[1] = 'A'; 03521 ArcNameFmt[2] = 'r'; 03522 ArcNameFmt[3] = 'c'; 03523 ArcNameFmt[4] = 'N'; 03524 ArcNameFmt[5] = 'a'; 03525 ArcNameFmt[6] = 'm'; 03526 ArcNameFmt[7] = 'e'; 03527 ArcNameFmt[8] = '\\'; 03528 ArcNameFmt[9] = '%'; 03529 ArcNameFmt[10] = 's'; 03530 ArcNameFmt[11] = '\0'; 03531 // 03532 // Open the ARC boot device object. The boot device driver should have 03533 // created the object. 03534 // 03535 03536 sprintf( deviceNameBuffer, 03537 ArcNameFmt, 03538 LoaderBlock->ArcBootDeviceName ); 03539 03540 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 03541 03542 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 03543 &deviceNameString, 03544 TRUE ); 03545 03546 if (!NT_SUCCESS( status )) { 03547 return FALSE; 03548 } 03549 03550 InitializeObjectAttributes( &objectAttributes, 03551 &deviceNameUnicodeString, 03552 OBJ_CASE_INSENSITIVE, 03553 NULL, 03554 NULL ); 03555 03556 status = ZwOpenFile( &fileHandle, 03557 FILE_READ_ATTRIBUTES, 03558 &objectAttributes, 03559 &ioStatus, 03560 0, 03561 FILE_NON_DIRECTORY_FILE ); 03562 if (!NT_SUCCESS( status )) { 03563 KeBugCheckEx( INACCESSIBLE_BOOT_DEVICE, 03564 (ULONG_PTR) &deviceNameUnicodeString, 03565 status, 03566 0, 03567 0 ); 03568 } 03569 03570 // 03571 // Convert the file handle into a pointer to the device object itself. 03572 // 03573 03574 status = ObReferenceObjectByHandle( fileHandle, 03575 0, 03576 IoFileObjectType, 03577 KernelMode, 03578 (PVOID *) &fileObject, 03579 NULL ); 03580 if (!NT_SUCCESS( status )) { 03581 RtlFreeUnicodeString( &deviceNameUnicodeString ); 03582 return FALSE; 03583 } 03584 03585 // 03586 // Mark the device object represented by the file object. 03587 // 03588 03589 fileObject->DeviceObject->Flags |= DO_SYSTEM_BOOT_PARTITION; 03590 03591 03592 // 03593 // Reference the device object and store the reference. 03594 // 03595 ObReferenceObject(fileObject->DeviceObject); 03596 03597 IopErrorLogObject = fileObject->DeviceObject; 03598 03599 RtlFreeUnicodeString( &deviceNameUnicodeString ); 03600 03601 // 03602 // Finally, close the handle and dereference the file object. 03603 // 03604 03605 NtClose( fileHandle ); 03606 ObDereferenceObject( fileObject ); 03607 03608 return TRUE; 03609 }

VOID IopNotifySetupDevices PDEVICE_NODE  DeviceNode  ) 
 

Definition at line 4318 of file ioinit.c.

References _DEVICE_NODE::Child, _DEVICE_NODE::InstancePath, IopClearDevNodeProblem, IopDeviceObjectToDeviceInstance(), IopIsDevNodeProblem, IopNotifySetupDeviceArrival(), NT_SUCCESS, NTSTATUS(), _DEVICE_NODE::PhysicalDeviceObject, PpDeviceRegistration(), _DEVICE_NODE::ServiceName, _DEVICE_NODE::Sibling, and TRUE.

Referenced by IopInitializeBootDrivers().

04324 : 04325 04326 This routine notifies setupdd.sys for all the enumerated devices whose 04327 service have not been setup. 04328 04329 This routine only gets executed on textmode setup phase. 04330 04331 Parameters: 04332 04333 DeviceNode - specifies the root of the subtree to be processed. 04334 04335 Return Value: 04336 04337 None. 04338 04339 --*/ 04340 04341 { 04342 PDEVICE_NODE deviceNode = DeviceNode->Child; 04343 PDEVICE_OBJECT deviceObject; 04344 HANDLE handle; 04345 UNICODE_STRING unicodeString; 04346 NTSTATUS status; 04347 PKEY_VALUE_FULL_INFORMATION keyValueInformation; 04348 04349 while (deviceNode) { 04350 IopNotifySetupDevices(deviceNode); 04351 if (deviceNode->ServiceName.Length == 0) { 04352 04353 // 04354 // We only notify setupdd the device nodes which do not have service setup yet. 04355 // It is impossible that at this point, a device has a service setup and 04356 // setupdd has to change it. 04357 // 04358 04359 deviceObject = deviceNode->PhysicalDeviceObject; 04360 status = IopDeviceObjectToDeviceInstance(deviceObject, &handle, KEY_ALL_ACCESS); 04361 if (NT_SUCCESS(status)) { 04362 04363 // 04364 // Notify setup about the device. 04365 // 04366 04367 IopNotifySetupDeviceArrival(deviceObject, handle, TRUE); 04368 04369 // 04370 // Finally register the device 04371 // 04372 04373 status = PpDeviceRegistration( 04374 &deviceNode->InstancePath, 04375 TRUE, 04376 &unicodeString // registered ServiceName 04377 ); 04378 04379 if (NT_SUCCESS(status)) { 04380 deviceNode->ServiceName = unicodeString; 04381 if (IopIsDevNodeProblem(deviceNode, CM_PROB_NOT_CONFIGURED)) { 04382 IopClearDevNodeProblem(deviceNode); 04383 } 04384 } 04385 ZwClose(handle); 04386 } 04387 } 04388 deviceNode = deviceNode->Sibling; 04389 } 04390 }

BOOLEAN IopReassignSystemRoot IN PLOADER_PARAMETER_BLOCK  LoaderBlock,
OUT PSTRING  NtDeviceName
 

Definition at line 3612 of file ioinit.c.

References CHAR, FALSE, INIT_SYSTEMROOT_LINKNAME, NT_SUCCESS, NtClose(), NtCreateSymbolicLinkObject(), NtMakeTemporaryObject(), NtOpenSymbolicLinkObject(), NtQuerySymbolicLinkObject(), NTSTATUS(), NULL, RtlAnsiStringToUnicodeString(), RtlCopyString(), RtlFreeUnicodeString(), RtlInitAnsiString(), RtlUnicodeStringToAnsiString(), sprintf(), strlen(), and TRUE.

Referenced by IoInitSystem().

03619 : 03620 03621 This routine is invoked to reassign \SystemRoot from being an ARC path 03622 name to its NT path name equivalent. This is done by looking up the 03623 ARC device name as a symbolic link and determining which NT device object 03624 is referred to by it. The link is then replaced with the new name. 03625 03626 Arguments: 03627 03628 LoaderBlock - Supplies a pointer to the loader parameter block created 03629 by the OS Loader during the boot process. This structure contains 03630 the various system partition and boot device names and paths. 03631 03632 NtDeviceName - Specifies a pointer to a STRING to receive the NT name of 03633 the device from which the system was booted. 03634 03635 Return Value: 03636 03637 The function value is a BOOLEAN indicating whether or not the ARC name 03638 was resolved to an NT name. 03639 03640 --*/ 03641 03642 { 03643 OBJECT_ATTRIBUTES objectAttributes; 03644 NTSTATUS status; 03645 UCHAR deviceNameBuffer[256]; 03646 WCHAR arcNameUnicodeBuffer[64]; 03647 UCHAR arcNameStringBuffer[256]; 03648 STRING deviceNameString; 03649 STRING arcNameString; 03650 STRING linkString; 03651 UNICODE_STRING linkUnicodeString; 03652 UNICODE_STRING deviceNameUnicodeString; 03653 UNICODE_STRING arcNameUnicodeString; 03654 HANDLE linkHandle; 03655 03656 #if DBG 03657 03658 UCHAR debugBuffer[256]; 03659 STRING debugString; 03660 UNICODE_STRING debugUnicodeString; 03661 03662 #endif 03663 CHAR ArcNameFmt[12]; 03664 03665 ArcNameFmt[0] = '\\'; 03666 ArcNameFmt[1] = 'A'; 03667 ArcNameFmt[2] = 'r'; 03668 ArcNameFmt[3] = 'c'; 03669 ArcNameFmt[4] = 'N'; 03670 ArcNameFmt[5] = 'a'; 03671 ArcNameFmt[6] = 'm'; 03672 ArcNameFmt[7] = 'e'; 03673 ArcNameFmt[8] = '\\'; 03674 ArcNameFmt[9] = '%'; 03675 ArcNameFmt[10] = 's'; 03676 ArcNameFmt[11] = '\0'; 03677 03678 // 03679 // Open the ARC boot device symbolic link object. The boot device 03680 // driver should have created the object. 03681 // 03682 03683 sprintf( deviceNameBuffer, 03684 ArcNameFmt, 03685 LoaderBlock->ArcBootDeviceName ); 03686 03687 RtlInitAnsiString( &deviceNameString, deviceNameBuffer ); 03688 03689 status = RtlAnsiStringToUnicodeString( &deviceNameUnicodeString, 03690 &deviceNameString, 03691 TRUE ); 03692 03693 if (!NT_SUCCESS( status )) { 03694 return FALSE; 03695 } 03696 03697 InitializeObjectAttributes( &objectAttributes, 03698 &deviceNameUnicodeString, 03699 OBJ_CASE_INSENSITIVE, 03700 NULL, 03701 NULL ); 03702 03703 status = NtOpenSymbolicLinkObject( &linkHandle, 03704 SYMBOLIC_LINK_ALL_ACCESS, 03705 &objectAttributes ); 03706 03707 if (!NT_SUCCESS( status )) { 03708 03709 #if DBG 03710 03711 sprintf( debugBuffer, "IOINIT: unable to resolve %s, Status == %X\n", 03712 deviceNameBuffer, 03713 status ); 03714 03715 RtlInitAnsiString( &debugString, debugBuffer ); 03716 03717 status = RtlAnsiStringToUnicodeString( &debugUnicodeString, 03718 &debugString, 03719 TRUE ); 03720 03721 if (NT_SUCCESS( status )) { 03722 ZwDisplayString( &debugUnicodeString ); 03723 RtlFreeUnicodeString( &debugUnicodeString ); 03724 } 03725 03726 #endif // DBG 03727 03728 RtlFreeUnicodeString( &deviceNameUnicodeString ); 03729 return FALSE; 03730 } 03731 03732 // 03733 // Get handle to \SystemRoot symbolic link. 03734 // 03735 03736 arcNameUnicodeString.Buffer = arcNameUnicodeBuffer; 03737 arcNameUnicodeString.Length = 0; 03738 arcNameUnicodeString.MaximumLength = sizeof( arcNameUnicodeBuffer ); 03739 03740 status = NtQuerySymbolicLinkObject( linkHandle, 03741 &arcNameUnicodeString, 03742 NULL ); 03743 03744 if (!NT_SUCCESS( status )) { 03745 return FALSE; 03746 } 03747 03748 arcNameString.Buffer = arcNameStringBuffer; 03749 arcNameString.Length = 0; 03750 arcNameString.MaximumLength = sizeof( arcNameStringBuffer ); 03751 03752 status = RtlUnicodeStringToAnsiString( &arcNameString, 03753 &arcNameUnicodeString, 03754 FALSE ); 03755 03756 arcNameStringBuffer[arcNameString.Length] = '\0'; 03757 03758 NtClose( linkHandle ); 03759 RtlFreeUnicodeString( &deviceNameUnicodeString ); 03760 03761 RtlInitAnsiString( &linkString, INIT_SYSTEMROOT_LINKNAME ); 03762 03763 status = RtlAnsiStringToUnicodeString( &linkUnicodeString, 03764 &linkString, 03765 TRUE); 03766 03767 if (!NT_SUCCESS( status )) { 03768 return FALSE; 03769 } 03770 03771 InitializeObjectAttributes( &objectAttributes, 03772 &linkUnicodeString, 03773 OBJ_CASE_INSENSITIVE, 03774 NULL, 03775 NULL ); 03776 03777 status = NtOpenSymbolicLinkObject( &linkHandle, 03778 SYMBOLIC_LINK_ALL_ACCESS, 03779 &objectAttributes ); 03780 03781 if (!NT_SUCCESS( status )) { 03782 return FALSE; 03783 } 03784 03785 NtMakeTemporaryObject( linkHandle ); 03786 NtClose( linkHandle ); 03787 03788 sprintf( deviceNameBuffer, 03789 "%Z%s", 03790 &arcNameString, 03791 LoaderBlock->NtBootPathName ); 03792 03793 // 03794 // Get NT device name for \SystemRoot assignment. 03795 // 03796 03797 RtlCopyString( NtDeviceName, &arcNameString ); 03798 03799 deviceNameBuffer[strlen(deviceNameBuffer)-1] = '\0'; 03800 03801 RtlInitAnsiString(&deviceNameString, deviceNameBuffer); 03802 03803 InitializeObjectAttributes( &objectAttributes, 03804 &linkUnicodeString, 03805 OBJ_CASE_INSENSITIVE | OBJ_PERMANENT, 03806 NULL, 03807 NULL ); 03808 03809 status = RtlAnsiStringToUnicodeString( &arcNameUnicodeString, 03810 &deviceNameString, 03811 TRUE); 03812 03813 if (!NT_SUCCESS( status )) { 03814 return FALSE; 03815 } 03816 03817 status = NtCreateSymbolicLinkObject( &linkHandle, 03818 SYMBOLIC_LINK_ALL_ACCESS, 03819 &objectAttributes, 03820 &arcNameUnicodeString ); 03821 03822 RtlFreeUnicodeString( &arcNameUnicodeString ); 03823 RtlFreeUnicodeString( &linkUnicodeString ); 03824 NtClose( linkHandle ); 03825 03826 #if DBG 03827 03828 if (NT_SUCCESS( status )) { 03829 03830 sprintf( debugBuffer, 03831 "INIT: Reassigned %s => %s\n", 03832 INIT_SYSTEMROOT_LINKNAME, 03833 deviceNameBuffer ); 03834 03835 } else { 03836 03837 sprintf( debugBuffer, 03838 "INIT: unable to create %s => %s, Status == %X\n", 03839 INIT_SYSTEMROOT_LINKNAME, 03840 deviceNameBuffer, 03841 status ); 03842 } 03843 03844 RtlInitAnsiString( &debugString, debugBuffer ); 03845 03846 status = RtlAnsiStringToUnicodeString( &debugUnicodeString, 03847 &debugString, 03848 TRUE ); 03849 03850 if (NT_SUCCESS( status )) { 03851 03852 ZwDisplayString( &debugUnicodeString ); 03853 RtlFreeUnicodeString( &debugUnicodeString ); 03854 } 03855 03856 #endif // DBG 03857 03858 return TRUE; 03859 }

VOID IopSetIoRoutines  ) 
 

Definition at line 953 of file ioinit.c.

References IopAllocateIrpPrivate(), IopfCallDriver(), IopfCompleteRequest(), IopFreeIrp(), NULL, pIoAllocateIrp, pIofCallDriver, pIofCompleteRequest, and pIoFreeIrp.

Referenced by IoInitSystem().

00954 { 00955 if (pIofCallDriver == NULL) { 00956 00957 pIofCallDriver = IopfCallDriver; 00958 } 00959 00960 if (pIofCompleteRequest == NULL) { 00961 00962 pIofCompleteRequest = IopfCompleteRequest; 00963 } 00964 00965 if (pIoAllocateIrp == NULL) { 00966 00967 pIoAllocateIrp = IopAllocateIrpPrivate; 00968 } 00969 00970 if (pIoFreeIrp == NULL) { 00971 00972 pIoFreeIrp = IopFreeIrp; 00973 } 00974 }

VOID IopSetIoRoutines IN  VOID  ) 
 

VOID IopStoreSystemPartitionInformation IN PUNICODE_STRING  NtSystemPartitionDeviceName,
IN OUT PUNICODE_STRING  OsLoaderPathName
 

Definition at line 3862 of file ioinit.c.

References ASSERT, CmRegistryMachineSystemName, DbgPrint, IopCreateRegistryKeyEx(), IopOpenRegistryKeyEx(), L, NT_SUCCESS, NtClose(), NtOpenSymbolicLinkObject(), NtQuerySymbolicLinkObject(), NtSetValueKey(), NTSTATUS(), NULL, and TITLE_INDEX_VALUE.

Referenced by IopCreateArcNames().

03869 : 03870 03871 This routine writes two values to the registry (under HKLM\SYSTEM\Setup)--one 03872 containing the NT device name of the system partition and the other containing 03873 the path to the OS loader. These values will later be migrated into a 03874 Win95-compatible registry location (NT path converted to DOS path), so that 03875 installation programs (including our own setup) have a rock-solid way of knowing 03876 what the system partition is, on both ARC and x86. 03877 03878 ERRORS ENCOUNTERED IN THIS ROUTINE ARE NOT CONSIDERED FATAL. 03879 03880 Arguments: 03881 03882 NtSystemPartitionDeviceName - supplies the NT device name of the system partition. 03883 This is the \Device\Harddisk<n>\Partition<m> name, which used to be the actual 03884 device name, but now is a symbolic link to a name of the form \Device\Volume<x>. 03885 We open up this symbolic link, and retrieve the name that it points to. The 03886 target name is the one we store away in the registry. 03887 03888 OsLoaderPathName - supplies the path (on the partition specified in the 1st parameter) 03889 where the OS loader is located. Upon return, this path will have had its trailing 03890 backslash removed (if present, and path isn't root). 03891 03892 Return Value: 03893 03894 None. 03895 03896 --*/ 03897 03898 { 03899 NTSTATUS status; 03900 HANDLE linkHandle; 03901 OBJECT_ATTRIBUTES objectAttributes; 03902 HANDLE systemHandle, setupHandle; 03903 UNICODE_STRING nameString, volumeNameString; 03904 WCHAR voumeNameStringBuffer[256]; 03905 // 03906 // Declare a unicode buffer big enough to contain the longest string we'll be using. 03907 // (ANSI string in 'sizeof()' below on purpose--we want the number of chars here.) 03908 // 03909 WCHAR nameBuffer[sizeof("SystemPartition")]; 03910 03911 // 03912 // Both UNICODE_STRING buffers should be NULL-terminated. 03913 // 03914 03915 ASSERT( NtSystemPartitionDeviceName->MaximumLength >= NtSystemPartitionDeviceName->Length + sizeof(WCHAR) ); 03916 ASSERT( NtSystemPartitionDeviceName->Buffer[NtSystemPartitionDeviceName->Length / sizeof(WCHAR)] == L'\0' ); 03917 03918 ASSERT( OsLoaderPathName->MaximumLength >= OsLoaderPathName->Length + sizeof(WCHAR) ); 03919 ASSERT( OsLoaderPathName->Buffer[OsLoaderPathName->Length / sizeof(WCHAR)] == L'\0' ); 03920 03921 // 03922 // Open the NtSystemPartitionDeviceName symbolic link, and find out the volume device 03923 // it points to. 03924 // 03925 03926 InitializeObjectAttributes(&objectAttributes, 03927 NtSystemPartitionDeviceName, 03928 OBJ_CASE_INSENSITIVE, 03929 NULL, 03930 NULL 03931 ); 03932 03933 status = NtOpenSymbolicLinkObject(&linkHandle, 03934 SYMBOLIC_LINK_QUERY, 03935 &objectAttributes 03936 ); 03937 03938 if (!NT_SUCCESS(status)) { 03939 #if DBG 03940 DbgPrint("IopStoreSystemPartitionInformation: couldn't open symbolic link %wZ - %x\n", 03941 NtSystemPartitionDeviceName, 03942 status 03943 ); 03944 #endif // DBG 03945 return; 03946 } 03947 03948 volumeNameString.Buffer = voumeNameStringBuffer; 03949 volumeNameString.Length = 0; 03950 // 03951 // Leave room at the end of the buffer for a terminating null, in case we need to add one. 03952 // 03953 volumeNameString.MaximumLength = sizeof(voumeNameStringBuffer) - sizeof(WCHAR); 03954 03955 status = NtQuerySymbolicLinkObject(linkHandle, 03956 &volumeNameString, 03957 NULL 03958 ); 03959 03960 // 03961 // We don't need the handle to the symbolic link any longer. 03962 // 03963 03964 NtClose(linkHandle); 03965 03966 if (!NT_SUCCESS(status)) { 03967 #if DBG 03968 DbgPrint("IopStoreSystemPartitionInformation: couldn't query symbolic link %wZ - %x\n", 03969 NtSystemPartitionDeviceName, 03970 status 03971 ); 03972 #endif // DBG 03973 return; 03974 } 03975 03976 // 03977 // Make sure the volume name string is null-terminated. 03978 // 03979 03980 volumeNameString.Buffer[volumeNameString.Length / sizeof(WCHAR)] = L'\0'; 03981 03982 // 03983 // Open HKLM\SYSTEM key. 03984 // 03985 03986 status = IopOpenRegistryKeyEx( &systemHandle, 03987 NULL, 03988 &CmRegistryMachineSystemName, 03989 KEY_ALL_ACCESS 03990 ); 03991 03992 if (!NT_SUCCESS(status)) { 03993 #if DBG 03994 DbgPrint("IopStoreSystemPartitionInformation: couldn't open \\REGISTRY\\MACHINE\\SYSTEM - %x\n", status); 03995 #endif // DBG 03996 return; 03997 } 03998 03999 // 04000 // Now open/create the setup subkey. 04001 // 04002 04003 ASSERT( sizeof(L"Setup") <= sizeof(nameBuffer) ); 04004 04005 nameBuffer[0] = L'S'; 04006 nameBuffer[1] = L'e'; 04007 nameBuffer[2] = L't'; 04008 nameBuffer[3] = L'u'; 04009 nameBuffer[4] = L'p'; 04010 nameBuffer[5] = L'\0'; 04011 04012 nameString.MaximumLength = sizeof(L"Setup"); 04013 nameString.Length = sizeof(L"Setup") - sizeof(WCHAR); 04014 nameString.Buffer = nameBuffer; 04015 04016 status = IopCreateRegistryKeyEx( &setupHandle, 04017 systemHandle, 04018 &nameString, 04019 KEY_ALL_ACCESS, 04020 REG_OPTION_NON_VOLATILE, 04021 NULL 04022 ); 04023 04024 NtClose(systemHandle); // Don't need the handle to the HKLM\System key anymore. 04025 04026 if (!NT_SUCCESS(status)) { 04027 #if DBG 04028 DbgPrint("IopStoreSystemPartitionInformation: couldn't open Setup subkey - %x\n", status); 04029 #endif // DBG 04030 return; 04031 } 04032 04033 ASSERT( sizeof(L"SystemPartition") <= sizeof(nameBuffer) ); 04034 04035 nameBuffer[0] = L'S'; 04036 nameBuffer[1] = L'y'; 04037 nameBuffer[2] = L's'; 04038 nameBuffer[3] = L't'; 04039 nameBuffer[4] = L'e'; 04040 nameBuffer[5] = L'm'; 04041 nameBuffer[6] = L'P'; 04042 nameBuffer[7] = L'a'; 04043 nameBuffer[8] = L'r'; 04044 nameBuffer[9] = L't'; 04045 nameBuffer[10] = L'i'; 04046 nameBuffer[11] = L't'; 04047 nameBuffer[12] = L'i'; 04048 nameBuffer[13] = L'o'; 04049 nameBuffer[14] = L'n'; 04050 nameBuffer[15] = L'\0'; 04051 04052 nameString.MaximumLength = sizeof(L"SystemPartition"); 04053 nameString.Length = sizeof(L"SystemPartition") - sizeof(WCHAR); 04054 04055 04056 04057 status = NtSetValueKey(setupHandle, 04058 &nameString, 04059 TITLE_INDEX_VALUE, 04060 REG_SZ, 04061 volumeNameString.Buffer, 04062 volumeNameString.Length + sizeof(WCHAR) 04063 ); 04064 04065 04066 #if DBG 04067 if (!NT_SUCCESS(status)) { 04068 DbgPrint("IopStoreSystemPartitionInformation: couldn't write SystemPartition value - %x\n", status); 04069 } 04070 #endif // DBG 04071 04072 ASSERT( sizeof(L"OsLoaderPath") <= sizeof(nameBuffer) ); 04073 04074 nameBuffer[0] = L'O'; 04075 nameBuffer[1] = L's'; 04076 nameBuffer[2] = L'L'; 04077 nameBuffer[3] = L'o'; 04078 nameBuffer[4] = L'a'; 04079 nameBuffer[5] = L'd'; 04080 nameBuffer[6] = L'e'; 04081 nameBuffer[7] = L'r'; 04082 nameBuffer[8] = L'P'; 04083 nameBuffer[9] = L'a'; 04084 nameBuffer[10] = L't'; 04085 nameBuffer[11] = L'h'; 04086 nameBuffer[12] = L'\0'; 04087 04088 nameString.MaximumLength = sizeof(L"OsLoaderPath"); 04089 nameString.Length = sizeof(L"OsLoaderPath") - sizeof(WCHAR); 04090 04091 // 04092 // Strip off the trailing backslash from the path (unless, of course, the path is a 04093 // single backslash). 04094 // 04095 04096 if ((OsLoaderPathName->Length > sizeof(WCHAR)) && 04097 (*(PWCHAR)((PCHAR)OsLoaderPathName->Buffer + OsLoaderPathName->Length - sizeof(WCHAR)) == L'\\')) { 04098 04099 OsLoaderPathName->Length -= sizeof(WCHAR); 04100 *(PWCHAR)((PCHAR)OsLoaderPathName->Buffer + OsLoaderPathName->Length) = L'\0'; 04101 } 04102 04103 status = NtSetValueKey(setupHandle, 04104 &nameString, 04105 TITLE_INDEX_VALUE, 04106 REG_SZ, 04107 OsLoaderPathName->Buffer, 04108 OsLoaderPathName->Length + sizeof(WCHAR) 04109 ); 04110 #if DBG 04111 if (!NT_SUCCESS(status)) { 04112 DbgPrint("IopStoreSystemPartitionInformation: couldn't write OsLoaderPath value - %x\n", status); 04113 } 04114 #endif // DBG 04115 04116 NtClose(setupHandle); 04117 }

BOOLEAN IopWaitForBootDevicesDeleted IN  VOID  ) 
 

Definition at line 4617 of file ioinit.c.

References Executive, FALSE, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, and PiEventQueueEmpty.

Referenced by IopInitializeBootDrivers().

04623 : 04624 04625 This routine waits for IoRequestDeviceRemoval to be completed. 04626 04627 Arguments: 04628 04629 None. 04630 04631 Return Value: 04632 04633 BOOLEAN. 04634 04635 --*/ 04636 04637 { 04638 NTSTATUS status; 04639 04640 // 04641 // Wait on device removal event to make sure all the deleted devcies are processed 04642 // before moving on to process next boot driver. 04643 // 04644 04645 status = KeWaitForSingleObject( &PiEventQueueEmpty, 04646 Executive, 04647 KernelMode, 04648 FALSE, 04649 NULL ); 04650 return NT_SUCCESS(status); 04651 }

BOOLEAN IopWaitForBootDevicesStarted IN  VOID  ) 
 

Definition at line 4508 of file ioinit.c.

References _DEVICE_NODE::Child, DNF_ASYNC_REQUEST_PENDING, Executive, exit, FALSE, _DEVICE_NODE::Flags, IopPnPSpinLock, IopRootDeviceNode, KeClearEvent, KernelMode, KeWaitForSingleObject(), NT_SUCCESS, NTSTATUS(), NULL, _DEVICE_NODE::Parent, PiEnumerationLock, PnpAsyncOk, _DEVICE_NODE::Sibling, and TRUE.

Referenced by IopInitializeBootDrivers().

04514 : 04515 04516 This routine waits for enumeration lock to be released for ALL devices. 04517 04518 Arguments: 04519 04520 None. 04521 04522 Return Value: 04523 04524 BOOLEAN. 04525 04526 --*/ 04527 04528 { 04529 PDEVICE_NODE deviceNode; 04530 NTSTATUS status; 04531 KIRQL oldIrql; 04532 04533 // 04534 // Wait on IoInvalidateDeviceRelations event to make sure all the devcies are enumerated 04535 // before progressing to mark boot partitions. 04536 // 04537 04538 status = KeWaitForSingleObject( &PiEnumerationLock, 04539 Executive, 04540 KernelMode, 04541 FALSE, 04542 NULL ); 04543 if (!NT_SUCCESS(status)) { 04544 return FALSE; 04545 } 04546 04547 if (PnpAsyncOk) { 04548 04549 // 04550 // Perform top-down check to make sure all the devices with Async start and Async Query 04551 // Device Relations are done. 04552 // 04553 04554 deviceNode = IopRootDeviceNode; 04555 for (; ;) { 04556 04557 ExAcquireSpinLock(&IopPnPSpinLock, &oldIrql); 04558 04559 if (deviceNode->Flags & DNF_ASYNC_REQUEST_PENDING) { 04560 04561 KeClearEvent(&PiEnumerationLock); 04562 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 04563 04564 // 04565 // Wait on PiEnumerationLock to be signaled before proceeding. 04566 // At this point if a device node is marked ASYNC request pending, this 04567 // must be an ASYNC start or enumeration which will queue an enumeration 04568 // request and once the enumeration completes, the PiEnumerationLock 04569 // will be signaled. 04570 // 04571 04572 status = KeWaitForSingleObject( &PiEnumerationLock, 04573 Executive, 04574 KernelMode, 04575 FALSE, 04576 NULL ); 04577 if (!NT_SUCCESS(status)) { 04578 return FALSE; 04579 } 04580 continue; // Make sure this device is done. 04581 } else { 04582 ExReleaseSpinLock(&IopPnPSpinLock, oldIrql); 04583 } 04584 04585 if (deviceNode->Child) { 04586 deviceNode = deviceNode->Child; 04587 continue; 04588 } 04589 if (deviceNode->Sibling) { 04590 deviceNode = deviceNode->Sibling; 04591 continue; 04592 } 04593 04594 for (; ;) { 04595 deviceNode = deviceNode->Parent; 04596 04597 // 04598 // If that was the last node to check, then exit loop 04599 // 04600 04601 if (deviceNode == IopRootDeviceNode) { 04602 goto exit; 04603 } 04604 if (deviceNode->Sibling) { 04605 deviceNode = deviceNode->Sibling; 04606 break; 04607 } 04608 } 04609 } 04610 exit: 04611 ; 04612 } 04613 return TRUE; 04614 }

NTSTATUS RawInitialize IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPath
 

Referenced by IopInitializeBootDrivers().


Variable Documentation

GENERIC_MAPPING IopCompletionMapping
 

Initial value:

{ STANDARD_RIGHTS_READ | IO_COMPLETION_QUERY_STATE, STANDARD_RIGHTS_WRITE | IO_COMPLETION_MODIFY_STATE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE, IO_COMPLETION_ALL_ACCESS }

Definition at line 1925 of file ioinit.c.

Referenced by IopCreateObjectTypes().

PVOID IopErrorLogObject = NULL
 

Definition at line 75 of file ioinit.c.

Referenced by IopLogErrorEvent(), and IopMarkBootPartition().

GENERIC_MAPPING IopFileMapping
 

Initial value:

{ STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE, STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE, STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS }

Definition at line 1915 of file ioinit.c.

Referenced by IoGetFileObjectGenericMapping(), and IopCreateObjectTypes().

ULONG IopGroupIndex
 

Definition at line 81 of file ioinit.c.

Referenced by IopInitializeBootDrivers(), and IopLoadBootFilterDriver().

PTREE_ENTRY IopGroupListHead
 

Definition at line 70 of file ioinit.c.

Referenced by IoInitSystem(), and IopLookupGroupName().

PLIST_ENTRY IopGroupTable
 

Definition at line 82 of file ioinit.c.

Referenced by IopInitializeBootDrivers(), and IopLoadBootFilterDriver().


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