00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
#include "iop.h"
00027
#include <setupblk.h>
00028
#include <inbv.h>
00029
#include <ntddstor.h>
00030
00031
00032
00033
00034
00035
00036
00037 #define DEFAULT_LARGE_IRP_LOCATIONS 8
00038
00039
00040
00041
00042
00043
00044 #define DEFAULT_LOOKASIDE_IRP_LIMIT 512
00045
00046
00047
00048
00049
00050
00051 typedef struct _TREE_ENTRY {
00052 struct _TREE_ENTRY *
Left;
00053 struct _TREE_ENTRY *
Right;
00054 struct _TREE_ENTRY *
Sibling;
00055 ULONG
DriversThisType;
00056 ULONG
DriversLoaded;
00057 UNICODE_STRING
GroupName;
00058 }
TREE_ENTRY, *
PTREE_ENTRY;
00059
00060 typedef struct _DRIVER_INFORMATION {
00061 LIST_ENTRY
Link;
00062 PDRIVER_OBJECT DriverObject;
00063 PBOOT_DRIVER_LIST_ENTRY DataTableEntry;
00064 HANDLE
ServiceHandle;
00065 USHORT TagPosition;
00066 BOOLEAN
Failed;
00067 BOOLEAN
Processed;
00068 }
DRIVER_INFORMATION, *
PDRIVER_INFORMATION;
00069
00070 PTREE_ENTRY IopGroupListHead;
00071
00072
00073
00074
00075 PVOID
IopErrorLogObject =
NULL;
00076
00077
00078
00079
00080
00081 ULONG
IopGroupIndex;
00082 PLIST_ENTRY
IopGroupTable;
00083
00084
00085
00086
00087
00088 #define InitializeDriverObject( Object ) { \
00089
ULONG i; \
00090
RtlZeroMemory( Object, \
00091
sizeof( DRIVER_OBJECT ) + sizeof ( DRIVER_EXTENSION )); \
00092
Object->DriverExtension = (PDRIVER_EXTENSION) (Object + 1); \
00093
Object->DriverExtension->DriverObject = Object; \
00094
for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) \
00095
Object->MajorFunction[i] = IopInvalidDeviceRequest; \
00096
Object->Type = IO_TYPE_DRIVER; \
00097
Object->Size = sizeof( DRIVER_OBJECT ); \
00098
}
00099
00100
00101
00102
00103
00104
VOID
00105
IopInitializeData(
00106 VOID
00107 );
00108
00109
NTSTATUS
00110
RawInitialize(
00111 IN
PDRIVER_OBJECT DriverObject,
00112 IN PUNICODE_STRING RegistryPath
00113 );
00114
00115
00116
00117
00118
00119 BOOLEAN
00120
IopCheckDependencies(
00121 IN HANDLE KeyHandle
00122 );
00123
00124
VOID
00125
IopCreateArcNames(
00126 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00127 );
00128
00129 BOOLEAN
00130
IopCreateObjectTypes(
00131 VOID
00132 );
00133
00134
PTREE_ENTRY
00135
IopCreateEntry(
00136 IN PUNICODE_STRING GroupName
00137 );
00138
00139 BOOLEAN
00140
IopCreateRootDirectories(
00141 VOID
00142 );
00143
00144
VOID
00145
IopFreeGroupTree(
00146 IN PTREE_ENTRY TreeEntry
00147 );
00148
00149
NTSTATUS
00150
IopInitializeAttributesAndCreateObject(
00151 IN PUNICODE_STRING ObjectName,
00152 IN OUT POBJECT_ATTRIBUTES ObjectAttributes,
00153 OUT
PDRIVER_OBJECT *DriverObject
00154 );
00155
00156 BOOLEAN
00157
IopInitializeBootDrivers(
00158 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
00159 OUT
PDRIVER_OBJECT *PreviousDriver
00160 );
00161
00162
PDRIVER_OBJECT
00163
IopInitializeBuiltinDriver(
00164 IN PUNICODE_STRING DriverName,
00165 IN PUNICODE_STRING RegistryPath,
00166 IN PDRIVER_INITIALIZE DriverInitializeRoutine,
00167 IN PLDR_DATA_TABLE_ENTRY TableEntry,
00168 IN BOOLEAN TextModeSetup
00169 );
00170
00171
00172 BOOLEAN
00173
IopInitializeSingleBootDriver(
00174 IN HANDLE KeyHandle,
00175 IN
PBOOT_DRIVER_LIST_ENTRY BootDriver,
00176 OUT PUNICODE_STRING DriverName OPTIONAL
00177 );
00178
00179 BOOLEAN
00180
IopInitializeSystemDrivers(
00181 VOID
00182 );
00183
00184
PTREE_ENTRY
00185
IopLookupGroupName(
00186 IN PUNICODE_STRING GroupName,
00187 IN BOOLEAN Insert
00188 );
00189
00190 BOOLEAN
00191
IopMarkBootPartition(
00192 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
00193 );
00194
00195 BOOLEAN
00196
IopReassignSystemRoot(
00197 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
00198 OUT PSTRING NtDeviceName
00199 );
00200
00201
VOID
00202
IopStoreSystemPartitionInformation(
00203 IN PUNICODE_STRING NtSystemPartitionDeviceName,
00204 IN OUT PUNICODE_STRING OsLoaderPathName
00205 );
00206
00207
USHORT
00208
IopGetDriverTagPriority (
00209 IN HANDLE Servicehandle
00210 );
00211
00212
VOID
00213
IopInsertDriverList (
00214 IN PLIST_ENTRY ListHead,
00215 IN PDRIVER_INFORMATION DriverInfo
00216 );
00217
00218
VOID
00219
IopNotifySetupDevices (
00220
PDEVICE_NODE DeviceNode
00221 );
00222
00223 BOOLEAN
00224
IopWaitForBootDevicesStarted (
00225 IN VOID
00226 );
00227
00228 BOOLEAN
00229
IopWaitForBootDevicesDeleted (
00230 IN VOID
00231 );
00232
VOID
00233
IopSetIoRoutines(
00234 IN VOID
00235 );
00236
00237
00238
00239
00240
00241
00242
#ifdef ALLOC_PRAGMA
00243
#pragma alloc_text(INIT,IoInitSystem)
00244
#pragma alloc_text(INIT,IopCheckDependencies)
00245
#pragma alloc_text(INIT,IopCreateArcNames)
00246
#pragma alloc_text(INIT,IopCreateEntry)
00247
#pragma alloc_text(INIT,IopCreateObjectTypes)
00248
#pragma alloc_text(INIT,IopCreateRootDirectories)
00249
#pragma alloc_text(INIT,IopFreeGroupTree)
00250
#pragma alloc_text(INIT,IopInitializeAttributesAndCreateObject)
00251
#pragma alloc_text(INIT,IopInitializeBootDrivers)
00252
#pragma alloc_text(INIT,IopInitializeBuiltinDriver)
00253
#pragma alloc_text(INIT,IopInitializeSingleBootDriver)
00254
#pragma alloc_text(INIT,IopInitializeSystemDrivers)
00255
#pragma alloc_text(INIT,IopLookupGroupName)
00256
#pragma alloc_text(INIT,IopMarkBootPartition)
00257
#pragma alloc_text(INIT,IopReassignSystemRoot)
00258
#pragma alloc_text(INIT,IopStoreSystemPartitionInformation)
00259
#pragma alloc_text(INIT,IopInsertDriverList)
00260
#pragma alloc_text(INIT,IopGetDriverTagPriority)
00261
#pragma alloc_text(INIT,IopNotifySetupDevices)
00262
#pragma alloc_text(INIT,IopWaitForBootDevicesStarted)
00263
#pragma alloc_text(INIT,IopWaitForBootDevicesDeleted)
00264
#pragma alloc_text(INIT,IopLoadBootFilterDriver)
00265
#pragma alloc_text(INIT,IopSetIoRoutines)
00266
#endif
00267
00268
00269 BOOLEAN
00270 IoInitSystem(
00271
PLOADER_PARAMETER_BLOCK LoaderBlock
00272 )
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
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
00337
00338
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
00364
00365
00366
IopUniqueDeviceObjectNumber = 0;
00367
00368
00369
00370
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
00418
00419
00420
ExInitializeNPagedLookasideList( &
IopCompletionLookasideList,
00421
NULL,
00422
NULL,
00423 0,
00424
sizeof(
IOP_MINI_COMPLETION_PACKET),
00425 ' pcI',
00426 completionZoneSize );
00427
00428
00429
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
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
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
00469
00470
00471
for (
Index = 0;
Index < (ULONG)
KeNumberProcessors;
Index += 1) {
00472 prcb =
KiProcessorBlock[
Index];
00473
00474
00475
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
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
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
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
00573
00574
00575
KeInitializeSpinLock( &
IopCompletionLock );
00576
00577
00578
00579
00580
00581
KeInitializeSpinLock( &
IopErrorLogLock );
00582
KeInitializeSpinLock( &
IopErrorLogAllocationLock );
00583 InitializeListHead( &
IopErrorLogListHead );
00584
00585
00586
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
00613
00614
IopErrorLogDisabledThisBoot =
TRUE;
00615 }
else {
00616
IopErrorLogDisabledThisBoot =
FALSE;
00617 }
00618 }
else {
00619
00620
00621
00622
IopErrorLogDisabledThisBoot =
TRUE;
00623 }
00624 }
else {
00625
00626
00627
00628
IopErrorLogDisabledThisBoot =
TRUE;
00629 }
00630
00631
00632
00633
00634
00635
KeInitializeSemaphore( &
IopRegistrySemaphore, 1, 1 );
00636
00637
00638
00639
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
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
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
00706
00707
00708
if (!
IopCreateObjectTypes()) {
00709
#if DBG
00710
DbgPrint(
"IOINIT: IopCreateObjectTypes failed\n" );
00711
#endif
00712
return FALSE;
00713 }
00714
00715
00716
00717
00718
00719
if (!
IopCreateRootDirectories()) {
00720
#if DBG
00721
DbgPrint(
"IOINIT: IopCreateRootDirectories failed\n" );
00722
#endif
00723
return FALSE;
00724 }
00725
00726
00727
00728
00729
00730
IopInitializeResourceMap (LoaderBlock);
00731
00732
00733
00734
00735
00736 status =
IopInitializePlugPlayServices(LoaderBlock, 0);
00737
if (!
NT_SUCCESS(status)) {
00738
return FALSE;
00739 }
00740
00741
00742
00743
00744
00745
PoInitDriverServices(0);
00746
00747
00748
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
00765
00766
00767
00768
WMIInitialize();
00769
00770
00771
00772
00773
00774
00775
IopLoaderBlock = (PVOID)LoaderBlock;
00776
00777
00778
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
00794
00795
00796 status =
IopInitializePlugPlayServices(LoaderBlock, 1);
00797
if (!
NT_SUCCESS(status)) {
00798
return FALSE;
00799 }
00800
00801
00802
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
00816
00817
00818
00819
IopLoaderBlock =
NULL;
00820
00821
00822
00823
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
00839
00840
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
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
00867
00868
00869
if (
IopGroupListHead) {
00870
IopFreeGroupTree(
IopGroupListHead );
00871 }
00872
00873
00874
00875
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
00890
00891
00892
if (!
IopReassignSystemRoot( LoaderBlock, &ntDeviceName )) {
00893
return FALSE;
00894 }
00895
00896
00897
00898
00899
00900
if (!
IopProtectSystemPartition( LoaderBlock )) {
00901
return(
FALSE);
00902 }
00903
00904
00905
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
00936
00937
00938
NtGlobalFlag = oldNtGlobalFlag;
00939
00940
00941
00942
00943
PoInitDriverServices(1);
00944
00945
00946
00947
00948
00949
return TRUE;
00950 }
00951
00952
VOID
00953 IopSetIoRoutines()
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 }
00975
00976
00977 BOOLEAN
00978 IopCheckDependencies(
00979 IN HANDLE KeyHandle
00980 )
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
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
01012
01013
01014
01015
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 }
01044
01045
01046
VOID
01047 IopCreateArcNames(
01048 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
01049 )
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
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
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
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
01152
01153
01154
01155
01156
01157
if (totalPnpDisksFound < totalDriverDisksFound) {
01158 useLegacyEnumeration =
TRUE;
01159 }
01160
01161 }
01162
01163
01164
01165
01166
01167
01168 singleBiosDiskFound = (arcInformation->
DiskSignatures.Flink->Flink ==
01169 &arcInformation->
DiskSignatures) ? (
TRUE) : (
FALSE);
01170
01171
01172
01173
01174
01175
01176
sprintf( arcNameBuffer,
"\\ArcName\\%s", LoaderBlock->ArcHalDeviceName );
01177
RtlInitAnsiString( &arcNameString, arcNameBuffer );
01178
RtlAnsiStringToUnicodeString (&
IoArcHalDeviceName, &arcNameString,
TRUE);
01179
01180
01181
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
01199
01200
01201
RtlInitAnsiString( &arcBootDeviceString,
01202 LoaderBlock->ArcBootDeviceName );
01203
01204
01205
01206
01207
01208
RtlInitAnsiString( &arcSystemDeviceString,
01209 LoaderBlock->ArcHalDeviceName );
01210
01211
01212
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
01237
01238
01239
IoCreateSymbolicLink( &arcNameUnicodeString,
01240 &deviceNameUnicodeString );
01241
RtlFreeUnicodeString( &arcNameUnicodeString );
01242
01243
01244
01245
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
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287 totalDriverDisksFound =
max(totalPnpDisksFound,totalDriverDisksFound);
01288
01289
if (useLegacyEnumeration && (totalPnpDisksFound == 0)) {
01290
01291
01292
01293
01294
01295 totalDriverDisksFound +=20;
01296 }
01297
01298
for (diskNumber = 0;
01299 diskNumber < totalDriverDisksFound;
01300 diskNumber++) {
01301
01302
01303
01304
01305
01306
if (pDiskNameList && (*pDiskNameList !=
L'\0')) {
01307
01308
01309
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
01324
01325
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
01368
01369
01370
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
01404
01405
01406 pnpDiskDeviceNumber.DeviceNumber = 0xFFFFFFFF;
01407
01408 }
01409
01410
01411
if (!
NT_SUCCESS( status )) {
01412
01413
continue;
01414 }
01415
01416
01417
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
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
01471
01472
01473
if (diskGeometry.BytesPerSector < 512) {
01474 diskGeometry.BytesPerSector = 512;
01475 }
01476
01477
01478
01479
01480
01481
01482
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
01500
01501
01502
01503 offset.QuadPart = 512;
01504
#endif //_X86_
01505
}
01506
01507
01508
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
01554
01555
01556 checkSum = 0;
01557
for (i = 0; i < 128; i++) {
01558 checkSum += buffer[i];
01559 }
01560
01561
01562
01563
01564
01565
01566
01567
for (listEntry = arcInformation->
DiskSignatures.Flink;
01568 listEntry != &arcInformation->
DiskSignatures;
01569 listEntry = listEntry->Flink) {
01570
01571
01572
01573
01574
01575 diskBlock = CONTAINING_RECORD( listEntry,
01576
ARC_DISK_SIGNATURE,
01577 ListEntry );
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
if ((singleBiosDiskFound && (totalDriverDisksFound == 1)) ||
01588 (diskBlock->
Signature == driveLayout->Signature &&
01589 !(diskBlock->
CheckSum + checkSum) &&
01590 diskBlock->
ValidPartitionTable)) {
01591
01592
01593
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
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
01636
01637
01638
IoCreateSymbolicLink( &arcNameUnicodeString,
01639 &deviceNameUnicodeString );
01640
RtlFreeUnicodeString( &arcNameUnicodeString );
01641
RtlFreeUnicodeString( &deviceNameUnicodeString );
01642
01643
01644
01645
01646
01647
for (partitionNumber = 0;
01648 partitionNumber < driveLayout->PartitionCount;
01649 partitionNumber++) {
01650
01651
01652
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
01682
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
01698
01699
if (
RtlEqualString( &arcNameString,
01700 &arcSystemDeviceString,
01701
TRUE )) {
01702
01703
01704
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
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
01743
01744
01745
IoCreateSymbolicLink( &arcNameUnicodeString,
01746 &deviceNameUnicodeString );
01747
RtlFreeUnicodeString( &arcNameUnicodeString );
01748
RtlFreeUnicodeString( &deviceNameUnicodeString );
01749 }
01750
01751 }
else {
01752
01753
#if DBG
01754
01755
01756
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
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
01796
01797
01798
01799
01800 irp =
NULL;
01801 buffer =
ExAllocatePool(
NonPagedPoolCacheAlignedMustS,
01802 2048 );
01803
if (buffer) {
01804
01805
01806
01807
01808
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
01831
01832
01833
RtlFreeUnicodeString( &deviceNameUnicodeString );
01834
break;
01835 }
01836
01837
01838
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
01869
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
01883
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 }
01914
01915 GENERIC_MAPPING
IopFileMapping = {
01916 STANDARD_RIGHTS_READ |
01917 FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE,
01918 STANDARD_RIGHTS_WRITE |
01919 FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE,
01920 STANDARD_RIGHTS_EXECUTE |
01921 SYNCHRONIZE | FILE_READ_ATTRIBUTES | FILE_EXECUTE,
01922 FILE_ALL_ACCESS
01923 };
01924
01925 GENERIC_MAPPING
IopCompletionMapping = {
01926 STANDARD_RIGHTS_READ |
01927 IO_COMPLETION_QUERY_STATE,
01928 STANDARD_RIGHTS_WRITE |
01929 IO_COMPLETION_MODIFY_STATE,
01930 STANDARD_RIGHTS_EXECUTE |
01931 SYNCHRONIZE,
01932 IO_COMPLETION_ALL_ACCESS
01933 };
01934
01935 BOOLEAN
01936 IopCreateObjectTypes(
01937 VOID
01938 )
01939
01940
01941
01942
01943
01944
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957
01958
01959
01960
01961
01962
01963
01964
01965
01966 {
01967
OBJECT_TYPE_INITIALIZER objectTypeInitializer;
01968 UNICODE_STRING nameString;
01969
01970
01971
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
01985
01986
01987
RtlInitUnicodeString( &nameString,
L"Adapter" );
01988
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
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
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
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
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
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
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 }
02105
02106
PTREE_ENTRY
02107 IopCreateEntry(
02108 IN PUNICODE_STRING GroupName
02109 )
02110
02111
02112
02113
02114
02115
02116
02117
02118
02119
02120
02121
02122
02123
02124
02125
02126
02127
02128
02129 {
02130
PTREE_ENTRY treeEntry;
02131
02132
02133
02134
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 }
02153
02154 BOOLEAN
02155 IopCreateRootDirectories(
02156 VOID
02157 )
02158
02159
02160
02161
02162
02163
02164
02165
02166
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178 {
02179 HANDLE handle;
02180 OBJECT_ATTRIBUTES objectAttributes;
02181 UNICODE_STRING nameString;
02182
NTSTATUS status;
02183
02184
02185
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
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 }
02221
02222
VOID
02223 IopFreeGroupTree(
02224 PTREE_ENTRY TreeEntry
02225 )
02226
02227
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237
02238
02239
02240
02241
02242
02243
02244
02245 {
02246
02247
02248
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
02265
02266
02267
02268
ExFreePool( TreeEntry );
02269 }
02270
02271
NTSTATUS
02272 IopInitializeAttributesAndCreateObject(
02273 IN PUNICODE_STRING ObjectName,
02274 IN OUT POBJECT_ATTRIBUTES ObjectAttributes,
02275 OUT
PDRIVER_OBJECT *DriverObject
02276 )
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296
02297
02298
02299
02300
02301 {
02302
NTSTATUS status;
02303
02304
02305
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 }
02325
02326 BOOLEAN
02327 IopInitializeBootDrivers(
02328 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
02329 OUT
PDRIVER_OBJECT *PreviousDriver
02330 )
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351
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
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
02402
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
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
02434
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
02452
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
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
02489
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
02510
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
02525
02526
02527
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
02562
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
02580
02581
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
02594
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
02620
02621
02622
02623
IopRequestDeviceAction(
NULL,
ReenumerateBootDevices,
NULL, (PNTSTATUS)&bootConfigsOK);
02624
02625 }
02626
02627
02628
02629
02630
02631
02632
02633
02634
02635
if (!
IopWaitForBootDevicesDeleted()) {
02636
return FALSE;
02637 }
02638
02639 nextEntry = nextEntry->Flink;
02640 }
02641
02642
02643
02644
02645
02646
02647
if (i ==
BUS_DRIVER_GROUP) {
02648
if (textModeSetup ==
FALSE) {
02649
02650
02651
02652
02653 }
02654
02655
02656
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
02670
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
02686
02687
02688
PnPBootDriversLoaded =
TRUE;
02689
IopResourcesReleased =
TRUE;
02690
02691
IopRequestDeviceAction(
NULL,
RestartEnumeration,
NULL,
NULL);
02692
02693
02694
02695
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
02717
02718
02719
02720
02721
if (bootReinitDriversFound && !
IopWaitForBootDevicesStarted()) {
02722
return FALSE;
02723 }
02724
02725
02726
02727
02728
02729
02730
IopCreateArcNames( LoaderBlock );
02731
02732
02733
02734
02735
02736
02737
02738
02739
02740
02741
if (!
IopMarkBootPartition( LoaderBlock )) {
02742
return FALSE;
02743 }
02744
02745
02746
02747
02748
02749
PnPBootDriversInitialized =
TRUE;
02750
02751
02752
02753
02754
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
02774
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 );
02785
ObDereferenceObject(driverObject);
02786 }
02787 }
02788
if (driverObject) {
02789
ObDereferenceObject(driverObject);
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
02804
02805
02806
02807
02808
return TRUE;
02809 }
02810
02811
PDRIVER_OBJECT
02812 IopInitializeBuiltinDriver(
02813 IN PUNICODE_STRING DriverName,
02814 IN PUNICODE_STRING RegistryPath,
02815 IN PDRIVER_INITIALIZE DriverInitializeRoutine,
02816 IN PLDR_DATA_TABLE_ENTRY DriverEntry,
02817 IN BOOLEAN TextModeSetup
02818 )
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831
02832
02833
02834
02835
02836
02837
02838
02839
02840
02841
02842
02843
02844
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
02870
02871
02872 status =
IopInitializeAttributesAndCreateObject( DriverName,
02873 &objectAttributes,
02874 &driverObject );
02875
if (!
NT_SUCCESS( status )) {
02876
return NULL;
02877 }
02878
02879
02880
02881
02882
02883
InitializeDriverObject( driverObject );
02884 driverObject->
DriverInit = DriverInitializeRoutine;
02885
02886
02887
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
02903
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
02915
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
02935
02936
02937
02938
InbvIndicateProgress();
02939
02940
02941
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
02959
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
02977
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
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
03045
03046
03047
03048 driverObject->
HardwareDatabase = &
CmRegistryMachineHardwareDescriptionSystemName;
03049
03050
#if DBG
03051
KeQuerySystemTime (&stime);
03052
#endif
03053
03054
03055
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
03068
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
03096
03097
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
03108
03109
03110
03111
03112
IopDriverLoadingFailed(
NULL, &driverObject->
DriverExtension->
ServiceKeyName);
03113 }
03114 }
else {
03115
03116
03117
03118
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
03133
03134
03135
IopDriverLoadingFailed(
NULL, &driverObject->
DriverExtension->
ServiceKeyName);
03136
ObMakeTemporaryObject( driverObject );
03137
ObDereferenceObject ( driverObject );
03138 }
03139
return NULL;
03140 }
03141 }
03142
03143
03144
03145 BOOLEAN
03146 IopInitializeSystemDrivers(
03147 VOID
03148 )
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158
03159
03160
03161
03162
03163
03164
03165
03166
03167
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
03186
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
03196
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
03208
03209
03210
03211
03212
IopProcessStartDevices(
IopRootDeviceNode, &startContext);
03213 newDevice = startContext.
NewDevice;
03214 }
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
if (!(driverList =
CmGetSystemDriverList())) {
03228
return TRUE;
03229 }
03230
03231
03232
03233
03234
03235
03236
for (savedList = driverList; *driverList; driverList++) {
03237
03238
03239
03240
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
03253
03254
03255
03256
ObDereferenceObject(driverObject);
03257
continue;
03258 }
03259 }
03260
03261
03262
03263
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
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
03322
03323
03324
03325
InbvIndicateProgress();
03326
03327 }
03328
03329
03330
03331
03332
03333
03334
ExFreePool( (PVOID) savedList );
03335
03336
03337
03338
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
03348
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
03360
03361
03362
03363
03364
IopProcessStartDevices(
IopRootDeviceNode, &startContext);
03365 newDevice = startContext.
NewDevice;
03366 }
while (newDevice || moreProcessing) ;
03367
03368
03369
03370
03371
03372
03373
PnPInitialized =
TRUE;
03374
03375
return TRUE;
03376 }
03377
03378
PTREE_ENTRY
03379 IopLookupGroupName(
03380 IN PUNICODE_STRING GroupName,
03381 IN BOOLEAN Insert
03382 )
03383
03384
03385
03386
03387
03388
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402
03403
03404
03405
03406 {
03407
PTREE_ENTRY treeEntry;
03408
PTREE_ENTRY previousEntry;
03409
03410
03411
03412
03413
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
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 }
03477
03478 BOOLEAN
03479 IopMarkBootPartition(
03480 IN
PLOADER_PARAMETER_BLOCK LoaderBlock
03481 )
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
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
03533
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
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
03587
03588
03589 fileObject->DeviceObject->Flags |=
DO_SYSTEM_BOOT_PARTITION;
03590
03591
03592
03593
03594
03595
ObReferenceObject(fileObject->DeviceObject);
03596
03597
IopErrorLogObject = fileObject->DeviceObject;
03598
03599
RtlFreeUnicodeString( &deviceNameUnicodeString );
03600
03601
03602
03603
03604
03605
NtClose( fileHandle );
03606
ObDereferenceObject( fileObject );
03607
03608
return TRUE;
03609 }
03610
03611 BOOLEAN
03612 IopReassignSystemRoot(
03613 IN
PLOADER_PARAMETER_BLOCK LoaderBlock,
03614 OUT PSTRING NtDeviceName
03615 )
03616
03617
03618
03619
03620
03621
03622
03623
03624
03625
03626
03627
03628
03629
03630
03631
03632
03633
03634
03635
03636
03637
03638
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
03680
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
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
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 }
03860
03861
VOID
03862 IopStoreSystemPartitionInformation(
03863 IN PUNICODE_STRING NtSystemPartitionDeviceName,
03864 IN OUT PUNICODE_STRING OsLoaderPathName
03865 )
03866
03867
03868
03869
03870
03871
03872
03873
03874
03875
03876
03877
03878
03879
03880
03881
03882
03883
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
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
03907
03908
03909 WCHAR nameBuffer[
sizeof(
"SystemPartition")];
03910
03911
03912
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
03923
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
03952
03953 volumeNameString.MaximumLength =
sizeof(voumeNameStringBuffer) -
sizeof(WCHAR);
03954
03955 status =
NtQuerySymbolicLinkObject(linkHandle,
03956 &volumeNameString,
03957
NULL
03958 );
03959
03960
03961
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
03978
03979
03980 volumeNameString.Buffer[volumeNameString.Length /
sizeof(WCHAR)] =
L'\0';
03981
03982
03983
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
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);
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
04093
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 }
04118
04119
USHORT
04120 IopGetDriverTagPriority (
04121 IN HANDLE ServiceHandle
04122 )
04123
04124
04125
04126
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
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
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
04168
04169
04170 status =
IopGetRegistryValue (ServiceHandle,
04171
L"Group",
04172 &keyValueInformation);
04173
if (
NT_SUCCESS(status)) {
04174
04175
04176
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
04190
04191
04192
NtClose(handle);
04193
return index;
04194 }
04195
04196
04197
04198
04199
04200 status =
IopGetRegistryValue (ServiceHandle,
04201
L"Tag",
04202 &keyValueInformation1);
04203
if (
NT_SUCCESS(status)) {
04204
04205
04206
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
04218
04219
04220
ExFreePool(keyValueInformation);
04221
NtClose(handle);
04222
return index;
04223 }
04224
04225
04226
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
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
04259
04260
04261
return index;
04262 }
04263
return index;
04264 }
04265
04266
VOID
04267 IopInsertDriverList (
04268 IN PLIST_ENTRY ListHead,
04269 IN PDRIVER_INFORMATION DriverInfo
04270 )
04271
04272
04273
04274
04275
04276
04277
04278
04279
04280
04281
04282
04283
04284
04285
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
04299
04300
04301
04302
04303
if (info->
TagPosition > DriverInfo->TagPosition) {
04304
break;
04305 }
04306 nextEntry = nextEntry->Flink;
04307 }
04308
04309
04310
04311
04312
04313 nextEntry = nextEntry->Blink;
04314 InsertHeadList(nextEntry, &DriverInfo->Link);
04315 }
04316
04317
VOID
04318 IopNotifySetupDevices (
04319
PDEVICE_NODE DeviceNode
04320 )
04321
04322
04323
04324
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
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
04355
04356
04357
04358
04359 deviceObject = deviceNode->
PhysicalDeviceObject;
04360 status =
IopDeviceObjectToDeviceInstance(deviceObject, &handle, KEY_ALL_ACCESS);
04361
if (
NT_SUCCESS(status)) {
04362
04363
04364
04365
04366
04367
IopNotifySetupDeviceArrival(deviceObject, handle,
TRUE);
04368
04369
04370
04371
04372
04373 status =
PpDeviceRegistration(
04374 &deviceNode->
InstancePath,
04375
TRUE,
04376 &unicodeString
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 }
04391
04392
NTSTATUS
04393 IopLogErrorEvent(
04394 IN ULONG SequenceNumber,
04395 IN ULONG UniqueErrorValue,
04396 IN NTSTATUS FinalStatus,
04397 IN NTSTATUS SpecificIOStatus,
04398 IN ULONG LengthOfInsert1,
04399 IN PWCHAR Insert1,
04400 IN ULONG LengthOfInsert2,
04401 IN PWCHAR Insert2
04402 )
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436
04437
04438
04439
04440
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 }
04495
04496 }
04497
04498
IoWriteErrorLogEntry(errorLogEntry);
04499
return(STATUS_SUCCESS);
04500
04501 }
04502
04503
return(STATUS_NO_DATA_DETECTED);
04504
04505 }
04506
04507 BOOLEAN
04508 IopWaitForBootDevicesStarted (
04509 IN VOID
04510 )
04511
04512
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525
04526
04527
04528 {
04529
PDEVICE_NODE deviceNode;
04530
NTSTATUS status;
04531 KIRQL oldIrql;
04532
04533
04534
04535
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
04551
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
04566
04567
04568
04569
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;
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
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 }
04615
04616 BOOLEAN
04617 IopWaitForBootDevicesDeleted (
04618 IN VOID
04619 )
04620
04621
04622
04623
04624
04625
04626
04627
04628
04629
04630
04631
04632
04633
04634
04635
04636
04637 {
04638
NTSTATUS status;
04639
04640
04641
04642
04643
04644
04645 status =
KeWaitForSingleObject( &
PiEventQueueEmpty,
04646
Executive,
04647
KernelMode,
04648
FALSE,
04649
NULL );
04650
return NT_SUCCESS(status);
04651 }
04652
04653
PDRIVER_OBJECT
04654 IopLoadBootFilterDriver (
04655 IN PUNICODE_STRING DriverName,
04656 IN ULONG GroupIndex
04657 )
04658
04659
04660
04661
04662
04663
04664
04665
04666
04667
04668
04669
04670
04671
04672
04673
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
04691
04692
04693
04694
return driverObject;
04695 }
04696
04697
04698
04699
04700
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)) {
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
04731
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 }
04747
#if 0
04748
04749
VOID
04750 IopCheckClassFiltersForBootDevice (
04751
PDEVICE_NODE DeviceNode
04752 )
04753
04754
04755
04756
04757
04758
04759
04760
04761
04762
04763
04764
04765
04766
04767
04768
04769
04770
04771
04772
04773 {
04774
PDEVICE_OBJECT deviceObject;
04775 HANDLE handle;
04776 UNICODE_STRING unicodeString, unicodeName;
04777
NTSTATUS status;
04778 PKEY_VALUE_FULL_INFORMATION keyValueInformation;
04779
04780
if (DeviceNode->
ServiceName.Length != 0) {
04781
04782 deviceObject = DeviceNode->
PhysicalDeviceObject;
04783 status =
IopDeviceObjectToDeviceInstance(deviceObject, &handle, KEY_ALL_ACCESS);
04784
if (
NT_SUCCESS(status)) {
04785
04786
04787
04788
04789
04790
04791
04792
04793
04794
04795
04796 status =
IopGetRegistryValue(handle,
04797 REGSTR_VALUE_CLASSGUID,
04798 &keyValueInformation);
04799
04800
if (
NT_SUCCESS(status) &&
04801 ((keyValueInformation->Type == REG_SZ) && (keyValueInformation->DataLength != 0))) {
04802
04803 HANDLE controlKey, classKey =
NULL;
04804 UNICODE_STRING unicodeClassGuid;
04805 RTL_QUERY_REGISTRY_TABLE queryTable[2];
04806
04807
IopRegistryDataToUnicodeString(
04808 &unicodeClassGuid,
04809 (PWSTR)
KEY_VALUE_DATA(keyValueInformation),
04810 keyValueInformation->DataLength);
04811
04812
04813
04814
04815
04816 status =
IopOpenRegistryKeyEx( &controlKey,
04817 NULL,
04818 &CmRegistryMachineSystemCurrentControlSetControlClass,
04819 KEY_READ
04820 );
04821
04822
if (!
NT_SUCCESS(status)) {
04823 classKey =
NULL;
04824 }
else {
04825 status =
IopOpenRegistryKeyEx( &classKey,
04826 controlKey,
04827 &unicodeClassGuid,
04828 KEY_READ
04829 );
04830
04831
NtClose(controlKey);
04832
if (!
NT_SUCCESS(status)) {
04833 classKey =
NULL;
04834 }
04835 }
04836
ExFreePool(keyValueInformation);
04837
04838
if (classKey) {
04839
04840 RTL_QUERY_REGISTRY_TABLE queryTable;
04841
04842 RtlZeroMemory(&queryTable,
sizeof(queryTable));
04843
04844 queryTable.QueryRoutine =
04845 (PRTL_QUERY_REGISTRY_ROUTINE) IopAddDeviceInstanceForClassFilters;
04846 queryTable.Name = REGSTR_VAL_LOWERFILTERS;
04847
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
04848 (PWSTR) classKey,
04849 &queryTable,
04850 &deviceNode->InstancePath,
04851 NULL);
04852
04853 queryTable.QueryRoutine =
04854 (PRTL_QUERY_REGISTRY_ROUTINE) IopAddDeviceInstanceForClassFilters;
04855 queryTable.Name = REGSTR_VAL_UPPERFILTERS;
04856
RtlQueryRegistryValues(RTL_REGISTRY_HANDLE,
04857 (PWSTR) classKey,
04858 &queryTable,
04859 &deviceNode->InstancePath,
04860 NULL);
04861
NtClose(classKey);
04862 }
04863 }
04864
04865 ZwClose(handle);
04866 }
04867 }
04868 }
04869
04870
NTSTATUS
04871 IopAddDeviceInstanceForClassFilters(
04872 IN PWSTR ValueName,
04873 IN ULONG ValueType,
04874 IN PWCHAR ValueData,
04875 IN ULONG ValueLength,
04876 IN PUNICODE_STRING DeviceInstancePath,
04877 IN ULONG notUse
04878 )
04879
04880
04881
04882
04883
04884
04885
04886
04887
04888
04889
04890
04891
04892
04893
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911
04912
04913 {
04914 UNICODE_STRING serviceName;
04915 UNICODE_STRING matchingDeviceInstance;
04916 UNICODE_STRING unicodeString;
04917
CHAR unicodeBuffer[20];
04918 HANDLE serviceEnumHandle;
04919 ULONG count;
04920
NTSTATUS status;
04921
04922
RtlInitUnicodeString(&serviceName, ValueData);
04923 status =
IopOpenServiceEnumKeys(&serviceName,
04924 KEY_ALL_ACCESS,
04925 NULL,
04926 &serviceEnumHandle,
04927 TRUE
04928 );
04929
if (!
NT_SUCCESS(status)) {
04930
return STATUS_SUCCESS;
04931 }
04932
04933
04934
04935
04936
04937
04938 status = PiFindDevInstMatch(serviceEnumHandle,
04939 DeviceInstancePath,
04940 &count,
04941 &matchingDeviceInstance);
04942
04943
if (!
NT_SUCCESS(status)) {
04944
return STATUS_SUCCESS;
04945 }
04946
04947
if (!matchingDeviceInstance.Buffer) {
04948
04949
04950
04951
04952
04953 PiUlongToUnicodeString(&unicodeString, unicodeBuffer, 20, count);
04954 status = ZwSetValueKey(
04955 serviceEnumHandle,
04956 &unicodeString,
04957 TITLE_INDEX_VALUE,
04958 REG_SZ,
04959 DeviceInstancePath->Buffer,
04960 DeviceInstancePath->Length
04961 );
04962 count++;
04963 PiWstrToUnicodeString(&unicodeString, REGSTR_VALUE_COUNT);
04964 ZwSetValueKey(
04965 serviceEnumHandle,
04966 &unicodeString,
04967 TITLE_INDEX_VALUE,
04968 REG_DWORD,
04969 &count,
04970
sizeof(count)
04971 );
04972 PiWstrToUnicodeString(&unicodeString, REGSTR_VALUE_NEXT_INSTANCE);
04973 ZwSetValueKey(
04974 serviceEnumHandle,
04975 &unicodeString,
04976 TITLE_INDEX_VALUE,
04977 REG_DWORD,
04978 &count,
04979
sizeof(count)
04980 );
04981 }
else {
04982
RtlFreeUnicodeString(&matchingDeviceInstance);
04983 }
04984
NtClose(serviceEnumHandle);
04985
return STATUS_SUCCESS;
04986 }
04987
#endif