From 5753152b64246f6953ea9556e34be2732b9d626f Mon Sep 17 00:00:00 2001 From: Filip Navara Date: Wed, 15 Oct 2003 17:04:39 +0000 Subject: [PATCH] Fixed driver loading order, cleaned up relevant functions, and moved boot driver initializing to separate function IopInitializeBootDrivers in io/driver.c. These functions has been renamed: LdrInitializeBootStartDriver -> IopInitializeBuiltinDriver (moved to io/driver.c) LdrLoadAutoConfigDrivers -> IopInitializeSystemDrivers How the driver loading works now: - The root bus driver is enumerated by IoInit2 and it causes all drivers marked as boot start to be initialized and attached to respective device tree node. - Other boot drivers are initialized by IopInitializeBootDrivers (called from ExpInitializeExecutive). - After creating system root link (by IoCreateSystemRootLink) the device tree is travesed by IopInitializePnpServices and all non-boot start drivers all loaded. - At last, system start drivers are loaded by IopInitializeSystemDrivers. svn path=/trunk/; revision=6325 --- reactos/bootc.lst | 1 + reactos/bootdata/hivesys.inf | 175 ++-- reactos/include/ntos/zwtypes.h | 3 + reactos/ntoskrnl/cm/rtlfunc.c | 2 +- reactos/ntoskrnl/include/internal/io.h | 38 +- reactos/ntoskrnl/include/internal/ke.h | 5 + reactos/ntoskrnl/include/internal/ps.h | 4 +- reactos/ntoskrnl/io/device.c | 131 +-- reactos/ntoskrnl/io/driver.c | 1102 ++++++++++++++++------- reactos/ntoskrnl/io/iomgr.c | 10 +- reactos/ntoskrnl/io/pnpmgr.c | 1124 ++++++++++++------------ reactos/ntoskrnl/ke/main.c | 89 +- reactos/ntoskrnl/ldr/loader.c | 7 +- 13 files changed, 1510 insertions(+), 1181 deletions(-) diff --git a/reactos/bootc.lst b/reactos/bootc.lst index 5aeba5689f6..354211a32f2 100644 --- a/reactos/bootc.lst +++ b/reactos/bootc.lst @@ -1,3 +1,4 @@ +system32\drivers\pci.sys system32\drivers\scsiport.sys system32\drivers\atapi.sys system32\drivers\class2.sys diff --git a/reactos/bootdata/hivesys.inf b/reactos/bootdata/hivesys.inf index 295c35fa1dc..7752dfe2926 100644 --- a/reactos/bootdata/hivesys.inf +++ b/reactos/bootdata/hivesys.inf @@ -55,9 +55,8 @@ HKLM,"SYSTEM\CurrentControlSet\Control\ServiceGroupOrder","List",0x00010000, \ "Video", \ "File System", \ "Event log", \ - "NDIS Wrapper" \ - "PNP_TDI", \ "NDIS", \ + "PNP_TDI", \ "TDI", \ "Extended Base" @@ -94,15 +93,15 @@ HKLM,"SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management","Pagin ; --------------------------- BUS drivers --------------------------- ; PCI driver -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ErrorControl",0x00010001,0x00000000 -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Group",0x00000000,"Boot Bus Extender" -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ImagePath",0x00020000,"system32\drivers\pci.sys" -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Start",0x00010001,0x00000003 -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Tag",0x00010001,0x00000002 -;HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Type",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","Service",0x00000000,"Pci" -;HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","Class",0x00000000,"Computer" -;HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","ClassGUID",0x00000000,"{4D36E966-E325-11CE-BFC1-08002BE10318}" +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ErrorControl",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Group",0x00000000,"Boot Bus Extender" +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","ImagePath",0x00020000,"system32\drivers\pci.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Start",0x00010001,0x00000000 +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Tag",0x00010001,0x00000002 +HKLM,"SYSTEM\CurrentControlSet\Services\Pci","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","Service",0x00000000,"Pci" +HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","Class",0x00000000,"Computer" +HKLM,"SYSTEM\CurrentControlSet\Enum\Root\PCI\0000","ClassGUID",0x00000000,"{4D36E966-E325-11CE-BFC1-08002BE10318}" ; ----------------------- End of BUS drivers ------------------------ @@ -220,28 +219,28 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Msfs","Type",0x00010001,0x00000002 ; NDIS driver - the only boot-start network driver HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Group",0x00000000,"NDIS Wrapper" +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Group",0x00000000,"NDIS" HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","ImagePath",0x00020000,"system32\drivers\ndis.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Start",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Start",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Type",0x00010001,0x00000001 ; NIC drivers are like any other drivers - but no card-specific info here. bind/route/export ; should have one entry per child device object. ; Comment the networking stuff out if you don't have hte card and don't want to see errors ; NE2000 NIC driver -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ErrorControl",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Group",0x00000000,"NDIS" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ImagePath",0x00020000,"system32\drivers\ne2000.sys" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Start",0x00010001,0x00000003 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Type",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Test",0x00010001,0xbaadf00d -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Route",0x00000000,"Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Bind",0x00010000,"\Device\Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Export",0x00010000,"\Device\Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Route",0x00010000,"Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","0",0x00000000,"Root\POSVPN\0000" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","Count",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","NextInstance",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Group",0x00000000,"NDIS" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","ImagePath",0x00020000,"system32\drivers\ne2000.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Test",0x00010001,0xbaadf00d +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000","Route",0x00000000,"Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Bind",0x00010000,"\Device\Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Export",0x00010000,"\Device\Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Linkage","Route",0x00010000,"Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","0",0x00000000,"Root\POSVPN\0000" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","Count",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne2000\Enum","NextInstance",0x00010001,0x00000001 ; one day this will happen automatically; until then we need this since ndis5 drivers ; rely on the fact that their resources are handed to them by ndis, so we have to find @@ -255,65 +254,25 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Ndis","Type",0x00010001,0x00000001 ; for the parent driver plus a globally-increasing serial number (i.e. across all ndis miniports) ; TODO: create this with NDI ; NE2000 Adapter 1 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","ErrorControl",0x00010001,0x00000001 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","Start",0x00010001,0x00000003 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","Type",0x00010001,0x00000004 -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Bind",0x00010000,"\Device\Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Export",0x00010000,"\Device\Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Route",0x00010000,"Ne20001" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","Port",0x00000000,"280" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","Irq",0x00000000,"9" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","DwordTest",0x00000000,"baadf00d" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","StringTest",0x00000000,"StringTest" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","NetworkAddress",0x00000000,"001122334455" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","DefaultGateway",0x00010000,"10.0.0.1" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","IPAddress",0x00010000,"10.0.0.100" -;HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","SubnetMask",0x00010000,"255.255.255.0" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001","Type",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Bind",0x00010000,"\Device\Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Export",0x00010000,"\Device\Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Linkage","Route",0x00010000,"Ne20001" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","Port",0x00000000,"280" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","Irq",0x00000000,"9" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","DwordTest",0x00000000,"baadf00d" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","StringTest",0x00000000,"StringTest" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters","NetworkAddress",0x00000000,"001122334455" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","DefaultGateway",0x00010000,"10.0.0.1" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","IPAddress",0x00010000,"10.0.0.100" +HKLM,"SYSTEM\CurrentControlSet\Services\Ne20001\Parameters\Tcpip","SubnetMask",0x00010000,"255.255.255.0" ; AMD PCNet NIC driver -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Group",0x00000000,"NDIS" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ImagePath",0x00020000,"system32\drivers\pcntn5m.sys" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Start",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Type",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Bind",0x00010000,"\Device\PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Export",0x00010000,"\Device\PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Route",0x00010000,"PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","0",0x00000000,"PCI\VEN_1022&DEV_2000\0000" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","Count",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","NextInstance",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","Service",0x00000000,"PCNet" -HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","Class",0x00000000,"Net" -HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","ClassGUID",0x00000000,"{4D36E972-E325-11CE-BFC1-08002BE10318}" - -; AMD PCNet Adapter 1 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","ErrorControl",0x00010001,0x00000001 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Start",0x00010001,0x00000003 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Type",0x00010001,0x00000004 -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Bind",0x00010000,"\Device\PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Export",0x00010000,"\Device\PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Route",0x00010000,"PCNet1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUS_TO_SCAN",0x00000000,"ALL" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUSTIMER",0x00000000,"0" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUSTYPE",0x00000000,"5" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","EXTPHY",0x00000000,"0" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","FDUP",0x00000000,"0" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED0",0x00000000,"10000" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED1",0x00000000,"10000" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED2",0x00000000,"10000" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED3",0x00000000,"10000" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","MPMODE",0x00000000,"0" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","TP",0x00000000,"1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","SlotNumber",0x00000000,"10" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BusNumber",0x00000000,"0" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","DefaultGateway",0x00010000,"10.1.0.1" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","IPAddress",0x00010000,"10.1.0.100" -HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","SubnetMask",0x00010000,"255.255.255.0" - -; ReactOS PCNet Driver ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ErrorControl",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Group",0x00000000,"NDIS" -;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ImagePath",0x00020000,"system32\drivers\pcnet.sys" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ImagePath",0x00020000,"system32\drivers\pcntn5m.sys" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Start",0x00010001,0x00000003 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Type",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Bind",0x00010000,"\Device\PCNet1" @@ -326,19 +285,59 @@ HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","SubnetMask",0x ;HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","Class",0x00000000,"Net" ;HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","ClassGUID",0x00000000,"{4D36E972-E325-11CE-BFC1-08002BE10318}" -; PCNet Adapter 1 +; AMD PCNet Adapter 1 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","ErrorControl",0x00010001,0x00000001 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Start",0x00010001,0x00000003 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Type",0x00010001,0x00000004 ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Bind",0x00010000,"\Device\PCNet1" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Export",0x00010000,"\Device\PCNet1" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Route",0x00010000,"PCNet1" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUS_TO_SCAN",0x00000000,"ALL" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUSTIMER",0x00000000,"0" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BUSTYPE",0x00000000,"5" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","EXTPHY",0x00000000,"0" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","FDUP",0x00000000,"0" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED0",0x00000000,"10000" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED1",0x00000000,"10000" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED2",0x00000000,"10000" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","LED3",0x00000000,"10000" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","MPMODE",0x00000000,"0" +;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","TP",0x00000000,"1" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","SlotNumber",0x00000000,"10" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BusNumber",0x00000000,"0" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","DefaultGateway",0x00010000,"10.1.0.1" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","IPAddress",0x00010000,"10.1.0.100" ;HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","SubnetMask",0x00010000,"255.255.255.0" +; ReactOS PCNet Driver +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Group",0x00000000,"NDIS" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","ImagePath",0x00020000,"system32\drivers\pcnet.sys" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet","Type",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Bind",0x00010000,"\Device\PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Export",0x00010000,"\Device\PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Linkage","Route",0x00010000,"PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","0",0x00000000,"PCI\VEN_1022&DEV_2000\0000" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","Count",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet\Enum","NextInstance",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","Service",0x00000000,"PCNet" +HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","Class",0x00000000,"Net" +HKLM,"SYSTEM\CurrentControlSet\Enum\PCI\VEN_1022&DEV_2000&SUBSYS_20001022&REV_10\0000","ClassGUID",0x00000000,"{4D36E972-E325-11CE-BFC1-08002BE10318}" + +; PCNet Adapter 1 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","ErrorControl",0x00010001,0x00000001 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Start",0x00010001,0x00000003 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1","Type",0x00010001,0x00000004 +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Bind",0x00010000,"\Device\PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Export",0x00010000,"\Device\PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Linkage","Route",0x00010000,"PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","SlotNumber",0x00000000,"10" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters","BusNumber",0x00000000,"0" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","DefaultGateway",0x00010000,"10.1.0.1" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","IPAddress",0x00010000,"10.1.0.100" +HKLM,"SYSTEM\CurrentControlSet\Services\PCNet1\Parameters\Tcpip","SubnetMask",0x00010000,"255.255.255.0" + ; Named Pipe filesystem driver HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","ErrorControl",0x00010001,0x00000000 HKLM,"SYSTEM\CurrentControlSet\Services\Npfs","Group",0x00000000,"File System" @@ -429,12 +428,12 @@ HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip","Type",0x00010001,0x00000001 ; These bindings are of the windows 2000 type, and will probably need to be ; twiddled to get 3rd-party network-related software to work. ; NT4 puts additional stuff in the Bind, Export, and Route values. -;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Bind",0x00010000,"\Device\PCNet1", "\Device\Ne20001" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Bind",0x00010000, "\Device\PCNet1" -;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Export",0x00010000,"\Device\Tcpip_PCNet1", "\Device\Tcpip_Ne20001" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Export",0x00010000, "\Device\Tcpip_PCNet1" -;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Route",0x00010000,"PCNet1", "Ne20001" -HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Route",0x00010000,"PCNet1" +;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Bind",0x00010000,"\Device\PCNet1", "\Device\Ne20001", "\Device\PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Bind",0x00010000, "\Device\Ne20001" +;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Export",0x00010000,"\Device\Tcpip_PCNet1", "\Device\Tcpip_Ne20001", "\Device\Tcpip_PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Export",0x00010000, "\Device\Tcpip_Ne20001" +;HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Route",0x00010000,"PCNet1", "Ne20001", "PCNet1" +HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Linkage","Route",0x00010000,"Ne20001" HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","DataBasePath",0x00000000,"DataBasePath" HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Domain",0x00000000,"" HKLM,"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters","Hostname",0x00000000,"ROSHost" diff --git a/reactos/include/ntos/zwtypes.h b/reactos/include/ntos/zwtypes.h index 30d2c279845..bd977138e82 100755 --- a/reactos/include/ntos/zwtypes.h +++ b/reactos/include/ntos/zwtypes.h @@ -1576,6 +1576,8 @@ struct _SYSTEM_QUOTA_INFORMATION /* object information class */ +#ifndef __USE_W32API + typedef enum _OBJECT_INFORMATION_CLASS { ObjectBasicInformation, @@ -1594,6 +1596,7 @@ typedef struct _DIRECTORY_BASIC_INFORMATION UNICODE_STRING ObjectTypeName; // Directory, Device ... } DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION; +#endif /* __USE_W32API */ /* Action is one of the following values: diff --git a/reactos/ntoskrnl/cm/rtlfunc.c b/reactos/ntoskrnl/cm/rtlfunc.c index 1ba12204436..f431e69ec1e 100644 --- a/reactos/ntoskrnl/cm/rtlfunc.c +++ b/reactos/ntoskrnl/cm/rtlfunc.c @@ -590,7 +590,7 @@ RtlpGetRegistryHandle(ULONG RelativeTo, if (RelativeTo & RTL_REGISTRY_HANDLE) { - Status = NtDuplicateObject(NtCurrentProcess(), + Status = ZwDuplicateObject(NtCurrentProcess(), (HANDLE)Path, NtCurrentProcess(), KeyHandle, diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index fd57b5a2e91..6c276dd8fb4 100644 --- a/reactos/ntoskrnl/include/internal/io.h +++ b/reactos/ntoskrnl/include/internal/io.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: io.h,v 1.36 2003/09/30 15:46:59 navaraf Exp $ +/* $Id: io.h,v 1.37 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -258,11 +258,7 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, PDEVICE_NODE *DeviceNode); NTSTATUS IopFreeDeviceNode(PDEVICE_NODE DeviceNode); -NTSTATUS -IopInvalidateDeviceRelations(PDEVICE_NODE DeviceNode, - DEVICE_RELATION_TYPE Type); -VOID -IopLoadBootStartDrivers(VOID); + NTSTATUS IopCreateDriverObject(PDRIVER_OBJECT *DriverObject, PUNICODE_STRING ServiceName, @@ -270,8 +266,6 @@ IopCreateDriverObject(PDRIVER_OBJECT *DriverObject, PVOID DriverImageStart, ULONG DriverImageSize); NTSTATUS -IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode); -NTSTATUS IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry, PDEVICE_NODE DeviceNode, BOOLEAN FileSystemDriver, @@ -385,4 +379,32 @@ NTSTATUS PnpRootCreateDevice( PDEVICE_OBJECT *PhysicalDeviceObject); +/* driver.c */ + +VOID +IopInitializeBootDrivers( + VOID); + +VOID +IopInitializeSystemDrivers( + VOID); + +NTSTATUS +IopInitializeDeviceNodeService( + PDEVICE_NODE DeviceNode, + BOOLEAN BootDriverOnly); + +/* pnpmgr.c */ + +NTSTATUS +IopInitializePnpServices( + IN PDEVICE_NODE DeviceNode, + IN BOOLEAN BootDrivers); + +NTSTATUS +IopInvalidateDeviceRelations( + IN PDEVICE_NODE DeviceNode, + IN DEVICE_RELATION_TYPE Type, + IN BOOLEAN BootDriver); + #endif diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 6a5d3dcacff..90ccefafde3 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -31,6 +31,11 @@ /* INTERNAL KERNEL FUNCTIONS ************************************************/ +#ifdef __USE_W32API +struct _KPROCESS* KeGetCurrentProcess(VOID); +VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2); +#endif + #ifndef __ASM__ struct _KTHREAD; diff --git a/reactos/ntoskrnl/include/internal/ps.h b/reactos/ntoskrnl/include/internal/ps.h index b6b2bacda69..6d3f13f797e 100644 --- a/reactos/ntoskrnl/include/internal/ps.h +++ b/reactos/ntoskrnl/include/internal/ps.h @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: ps.h,v 1.52 2003/08/19 23:59:08 dwelch Exp $ +/* $Id: ps.h,v 1.53 2003/10/15 17:04:39 navaraf Exp $ * * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Process manager definitions @@ -43,7 +43,7 @@ struct _KTRAPFRAME; #include #include -#ifndef __USE_W32API +#ifndef KeGetCurrentProcessorNumber #define KeGetCurrentProcessorNumber() (KeGetCurrentKPCR()->ProcessorNumber) #endif diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index 0b5b6626238..e987acae342 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -1,4 +1,4 @@ -/* $Id: device.c,v 1.62 2003/09/30 15:46:59 navaraf Exp $ +/* $Id: device.c,v 1.63 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -424,23 +424,12 @@ IopInitializeDevice(PDEVICE_NODE DeviceNode, { DPRINT("Bus extender found\n"); - /* - * Don't initialize boot bus drivers here, because - * it will not be able to load the required drivers - * for the devices found. - * - * FiN - */ - if (!BootDriver) + Status = IopInvalidateDeviceRelations( + DeviceNode, BusRelations, BootDriver); + if (!NT_SUCCESS(Status)) { - Status = IopInvalidateDeviceRelations( - DeviceNode, BusRelations); -/* IopInterrogateBusExtender(DeviceNode, Fdo); */ - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Fdo); - return(Status); - } + ObDereferenceObject(Fdo); + return(Status); } } else if (Fdo->DeviceType == FILE_DEVICE_ACPI) @@ -496,119 +485,13 @@ IopInitializeService( } } else { + /* FIXME: This doesn't work for two devices with the same driver */ Status = IopInitializeDevice(DeviceNode, FALSE); } return(Status); } -NTSTATUS -IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode) -{ -#if 1 - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - UNICODE_STRING ImagePath; - NTSTATUS Status; - WCHAR FullImagePathBuffer[MAX_PATH]; - UNICODE_STRING FullImagePath; - CHAR TextBuffer [256]; - ULONG x, y, cx, cy; - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - - RtlInitUnicodeString(&ImagePath, NULL); - - QueryTable[0].Name = L"ImagePath"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &ImagePath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, - DeviceNode->ServiceName.Buffer, - QueryTable, - NULL, - NULL); - - DPRINT("RtlQueryRegistryValues() returned status %x\n", Status); - - if (NT_SUCCESS(Status)) - { - DPRINT("Got ImagePath %S\n", ImagePath.Buffer); - - if (ImagePath.Buffer[0] != L'\\') - { - wcscpy(FullImagePathBuffer, L"\\SystemRoot\\"); - wcscat(FullImagePathBuffer, ImagePath.Buffer); - } - else - { - wcscpy(FullImagePathBuffer, ImagePath.Buffer); - } - - RtlFreeUnicodeString(&ImagePath); - RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer); - - HalQueryDisplayParameters(&x, &y, &cx, &cy); - RtlFillMemory(TextBuffer, x, ' '); - TextBuffer[x] = '\0'; - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - - sprintf(TextBuffer, "PnP Loading %S...\n", DeviceNode->ServiceName.Buffer); - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - HalSetDisplayParameters(cx, cy); - - Status = IopInitializeService(DeviceNode, &FullImagePath); - } - - return(Status); -#else - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - UNICODE_STRING ImagePath; - HANDLE KeyHandle; - NTSTATUS Status; - - Status = RtlpGetRegistryHandle( - RTL_REGISTRY_SERVICES, - DeviceNode->ServiceName.Buffer, - TRUE, - &KeyHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status); - return(Status); - } - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - - RtlInitUnicodeString(&ImagePath, NULL); - - QueryTable[0].Name = L"ImagePath"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &ImagePath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, - (PWSTR)KeyHandle, - QueryTable, - NULL, - NULL); - NtClose(KeyHandle); - - DPRINT("RtlQueryRegistryValues() returned status %x\n", Status); - - if (NT_SUCCESS(Status)) - { - DPRINT("Got ImagePath %S\n", ImagePath.Buffer); - - Status = IopInitializeService(DeviceNode, &ImagePath); - - RtlFreeUnicodeString(&ImagePath); - } - - return(Status); -#endif -} - NTSTATUS IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry, PDEVICE_NODE DeviceNode, diff --git a/reactos/ntoskrnl/io/driver.c b/reactos/ntoskrnl/io/driver.c index 8afc3bf84b3..21c734d495a 100644 --- a/reactos/ntoskrnl/io/driver.c +++ b/reactos/ntoskrnl/io/driver.c @@ -1,15 +1,16 @@ -/* $Id: driver.c,v 1.23 2003/10/12 17:05:44 hbirr Exp $ +/* $Id: driver.c,v 1.24 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/io/driver.c - * PURPOSE: Manage devices + * PURPOSE: Loading and unloading of drivers * PROGRAMMER: David Welch (welch@cwcom.net) + * Filip Navara (xnavara@volny.cz) * UPDATE HISTORY: * 15/05/98: Created */ -/* INCLUDES ****************************************************************/ +/* INCLUDES *******************************************************************/ #include #include @@ -19,23 +20,36 @@ #include #include #include +#include +#include +#include +#include #include #define NDEBUG #include +/* ke/main.c */ +extern LOADER_PARAMETER_BLOCK EXPORTED KeLoaderBlock; + +NTSTATUS +IopInitializeService( + PDEVICE_NODE DeviceNode, + PUNICODE_STRING ImagePath); + +NTSTATUS +LdrProcessModule(PVOID ModuleLoadBase, + PUNICODE_STRING ModuleName, + PMODULE_OBJECT *ModuleObject); typedef struct _SERVICE_GROUP { LIST_ENTRY GroupListEntry; UNICODE_STRING GroupName; - BOOLEAN ServicesRunning; - } SERVICE_GROUP, *PSERVICE_GROUP; - typedef struct _SERVICE { LIST_ENTRY ServiceListEntry; @@ -49,12 +63,10 @@ typedef struct _SERVICE ULONG ErrorControl; ULONG Tag; - BOOLEAN ServiceRunning; // needed ?? - +/* BOOLEAN ServiceRunning;*/ // needed ?? } SERVICE, *PSERVICE; - -/* GLOBALS *******************************************************************/ +/* GLOBALS ********************************************************************/ static LIST_ENTRY GroupListHead = {NULL, NULL}; static LIST_ENTRY ServiceListHead = {NULL, NULL}; @@ -64,8 +76,7 @@ POBJECT_TYPE EXPORTED IoDriverObjectType = NULL; #define TAG_DRIVER TAG('D', 'R', 'V', 'R') #define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E') - -/* FUNCTIONS ***************************************************************/ +/* PRIVATE FUNCTIONS **********************************************************/ NTSTATUS STDCALL IopCreateDriver(PVOID ObjectBody, @@ -113,229 +124,6 @@ IopInitDriverImplementation(VOID) ObpCreateTypeObject(IoDriverObjectType); } -/********************************************************************** - * NAME EXPORTED - * NtLoadDriver - * - * DESCRIPTION - * Loads a device driver. - * - * ARGUMENTS - * DriverServiceName - * Name of the service to load (registry key). - * - * RETURN VALUE - * Status. - * - * REVISIONS - */ -NTSTATUS STDCALL -NtLoadDriver(IN PUNICODE_STRING DriverServiceName) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[3]; - WCHAR FullImagePathBuffer[MAX_PATH]; - UNICODE_STRING ImagePath; - UNICODE_STRING FullImagePath; - NTSTATUS Status; - ULONG Type; - PDEVICE_NODE DeviceNode; - PMODULE_OBJECT ModuleObject; - LPWSTR Start; - - DPRINT("NtLoadDriver(%wZ) called\n", DriverServiceName); - - RtlInitUnicodeString(&ImagePath, NULL); - - /* Get service data */ - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); - - QueryTable[0].Name = L"Type"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[0].EntryContext = &Type; - - QueryTable[1].Name = L"ImagePath"; - QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[1].EntryContext = &ImagePath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - DriverServiceName->Buffer, - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); - RtlFreeUnicodeString(&ImagePath); - return(Status); - } - - if (ImagePath.Length == 0) - { - wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers"); - wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\')); - wcscat(FullImagePathBuffer, L".sys"); - } - else if (ImagePath.Buffer[0] != L'\\') - { - wcscpy(FullImagePathBuffer, L"\\SystemRoot\\"); - wcscat(FullImagePathBuffer, ImagePath.Buffer); - } - else - { - wcscpy(FullImagePathBuffer, ImagePath.Buffer); - } - - RtlFreeUnicodeString(&ImagePath); - RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer); - - DPRINT("FullImagePath: '%S'\n", FullImagePathBuffer); - DPRINT("Type %lx\n", Type); - - /* Use IopRootDeviceNode for now */ - Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); - return(Status); - } - - ModuleObject = LdrGetModuleObject(DriverServiceName); - if (ModuleObject != NULL) - { - return(STATUS_IMAGE_ALREADY_LOADED); - } - - Status = LdrLoadModule(&FullImagePath, &ModuleObject); - if (!NT_SUCCESS(Status)) - { - DPRINT1("LdrLoadModule() failed (Status %lx)\n", Status); - IopFreeDeviceNode(DeviceNode); - return(Status); - } - - /* Set a service name for the device node */ - Start = wcsrchr(DriverServiceName->Buffer, L'\\'); - if (Start == NULL) - Start = DriverServiceName->Buffer; - else - Start++; - RtlCreateUnicodeString(&DeviceNode->ServiceName, Start); - - Status = IopInitializeDriver(ModuleObject->EntryPoint, - DeviceNode, - (Type == 2 || Type == 8), - ModuleObject->Base, - ModuleObject->Length, - FALSE); - if (!NT_SUCCESS(Status)) - { - DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status); - LdrUnloadModule(ModuleObject); - IopFreeDeviceNode(DeviceNode); - } - - return(Status); -} - - -NTSTATUS STDCALL -NtUnloadDriver(IN PUNICODE_STRING DriverServiceName) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - WCHAR FullImagePathBuffer[MAX_PATH]; - UNICODE_STRING ImagePath; - UNICODE_STRING FullImagePath; - UNICODE_STRING ObjectName; - PDRIVER_OBJECT DriverObject; - NTSTATUS Status; - PMODULE_OBJECT ModuleObject; - LPWSTR Start; - - DPRINT("DriverServiceName: '%wZ'\n", DriverServiceName); - - /* Get the service name from the module name */ - Start = wcsrchr(DriverServiceName->Buffer, L'\\'); - if (Start == NULL) - Start = DriverServiceName->Buffer; - else - Start++; - - ObjectName.Length = wcslen(Start) + 8; - ObjectName.Buffer = ExAllocatePool(NonPagedPool, - ObjectName.Length * sizeof(WCHAR)); - wcscpy(ObjectName.Buffer, L"\\Driver\\"); - memcpy(ObjectName.Buffer + 8, Start, (ObjectName.Length - 8) * sizeof(WCHAR)); - - /* Find the driver object */ - Status = ObReferenceObjectByName(&ObjectName, 0, 0, 0, IoDriverObjectType, - KernelMode, 0, (PVOID*)&DriverObject); - if (!NT_SUCCESS(Status)) - { - DPRINT("Can't locate driver object for %wZ\n", ObjectName); - return Status; - } - ObDereferenceObject(DriverObject); - - RtlInitUnicodeString(&ImagePath, NULL); - - /* Get service data */ - RtlZeroMemory(&QueryTable, - sizeof(QueryTable)); - - QueryTable[0].Name = L"ImagePath"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = &ImagePath; - - Status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, - DriverServiceName->Buffer, - QueryTable, - NULL, - NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT1("RtlQueryRegistryValues() failed (Status %lx)\n", Status); - RtlFreeUnicodeString(&ImagePath); - return(Status); - } - - if (ImagePath.Length == 0) - { - wcscpy(FullImagePathBuffer, L"\\SystemRoot\\system32\\drivers"); - wcscat(FullImagePathBuffer, wcsrchr(DriverServiceName->Buffer, L'\\')); - wcscat(FullImagePathBuffer, L".sys"); - } - else if (ImagePath.Buffer[0] != L'\\') - { - wcscpy(FullImagePathBuffer, L"\\SystemRoot\\"); - wcscat(FullImagePathBuffer, ImagePath.Buffer); - } - else - { - wcscpy(FullImagePathBuffer, ImagePath.Buffer); - } - - RtlFreeUnicodeString(&ImagePath); - RtlInitUnicodeString(&FullImagePath, FullImagePathBuffer); - - ModuleObject = LdrGetModuleObject(DriverServiceName); - if (ModuleObject == NULL) - { - return STATUS_UNSUCCESSFUL; - } - - /* Unload the module and release the references to the device object */ - - if (DriverObject->DriverUnload) - (*DriverObject->DriverUnload)(DriverObject); - ObDereferenceObject(DriverObject); - ObDereferenceObject(DriverObject); - LdrUnloadModule(ModuleObject); - - return STATUS_SUCCESS; -} - - static NTSTATUS STDCALL IopCreateGroupListEntry(PWSTR ValueName, ULONG ValueType, @@ -564,93 +352,6 @@ IoCreateDriverList(VOID) return(STATUS_SUCCESS); } - -VOID INIT_FUNCTION -LdrLoadAutoConfigDrivers(VOID) -{ - PLIST_ENTRY GroupEntry; - PLIST_ENTRY ServiceEntry; - PSERVICE_GROUP CurrentGroup; - PSERVICE CurrentService; - NTSTATUS Status; - - CHAR TextBuffer [256]; - ULONG x, y, cx, cy; - - DPRINT("LdrLoadAutoConfigDrivers() called\n"); - - GroupEntry = GroupListHead.Flink; - while (GroupEntry != &GroupListHead) - { - CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry); - - DPRINT("Group: %wZ\n", &CurrentGroup->GroupName); - - ServiceEntry = ServiceListHead.Flink; - while (ServiceEntry != &ServiceListHead) - { - CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry); - - if ((RtlCompareUnicodeString(&CurrentGroup->GroupName, &CurrentService->ServiceGroup, TRUE) == 0) && - (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/)) - { - - HalQueryDisplayParameters(&x, &y, &cx, &cy); - RtlFillMemory(TextBuffer, x, ' '); - TextBuffer[x] = '\0'; - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - - sprintf(TextBuffer, "Loading %S...\n", CurrentService->ServiceName.Buffer); - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - HalSetDisplayParameters(cx, cy); - - DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath); - Status = NtLoadDriver(&CurrentService->RegistryPath); - if (!NT_SUCCESS(Status)) - { - DPRINT("NtLoadDriver() failed (Status %lx)\n", Status); -#if 0 - if (CurrentService->ErrorControl == 1) - { - /* Log error */ - - } - else if (CurrentService->ErrorControl == 2) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ - - } - } - else if (CurrentService->ErrorControl == 3) - { - if (IsLastKnownGood == FALSE) - { - /* Boot last known good configuration */ - - } - else - { - /* BSOD! */ - - } - } -#endif - } - } - ServiceEntry = ServiceEntry->Flink; - } - - GroupEntry = GroupEntry->Flink; - } - - DPRINT("LdrLoadAutoConfigDrivers() done\n"); -} - - NTSTATUS INIT_FUNCTION IoDestroyDriverList(VOID) { @@ -695,4 +396,761 @@ IoDestroyDriverList(VOID) return(STATUS_SUCCESS); } +VOID STATIC +MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length) +{ + ULONG i; + + for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++) + { + MmDeleteVirtualMapping(NULL, StartAddress + i * PAGE_SIZE, TRUE, NULL, NULL); + } +} + +/* + * IopDisplayLoadingMessage + * + * Display 'Loading XXX...' message. + */ + +VOID +IopDisplayLoadingMessage(PWCHAR ServiceName) +{ + CHAR TextBuffer[256]; + sprintf(TextBuffer, "Loading %S...\n", ServiceName); + HalDisplayString(TextBuffer); +} + +/* + * IopInitializeBuiltinDriver + * + * Initialize a driver that is already loaded in memory. + */ + +NTSTATUS INIT_FUNCTION +IopInitializeBuiltinDriver( + PDEVICE_NODE ModuleDeviceNode, + PVOID ModuleLoadBase, + PCHAR FileName, + ULONG ModuleLength) +{ + PMODULE_OBJECT ModuleObject; + PDEVICE_NODE DeviceNode; + NTSTATUS Status; + CHAR TextBuffer[256]; + PCHAR FileNameWithoutPath; + + DPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n", + FileName, ModuleLoadBase, ModuleLength); + + /* + * Display 'Initializing XXX...' message + */ + sprintf(TextBuffer, "Initializing %s...\n", FileName); + HalDisplayString(TextBuffer); + + /* + * Determine the right device object + */ + if (ModuleDeviceNode == NULL) + { + /* Use IopRootDeviceNode for now */ + Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); + if (!NT_SUCCESS(Status)) + { + CPRINT("Driver load failed, status (%x)\n", Status); + return(Status); + } + } else + { + DeviceNode = ModuleDeviceNode; + } + + /* + * Generate filename without patch (not needed by freeldr) + */ + FileNameWithoutPath = strrchr(FileName, '\\'); + if (FileNameWithoutPath == NULL) + FileNameWithoutPath = FileName; + + /* + * Load the module + */ + RtlCreateUnicodeStringFromAsciiz(&DeviceNode->ServiceName, + FileNameWithoutPath); + Status = LdrProcessModule(ModuleLoadBase, &DeviceNode->ServiceName, + &ModuleObject); + if (ModuleObject == NULL) + { + if (ModuleDeviceNode == NULL) + IopFreeDeviceNode(DeviceNode); + CPRINT("Driver load failed, status (%x)\n", Status); + return STATUS_UNSUCCESSFUL; + } + + /* + * Initialize the driver + */ + Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, + FALSE, ModuleObject->Base, ModuleObject->Length, TRUE); + if (!NT_SUCCESS(Status)) + { + if (ModuleDeviceNode == NULL) + IopFreeDeviceNode(DeviceNode); + CPRINT("Driver load failed, status (%x)\n", Status); + } + + return Status; +} + +/* + * IopInitializeBootDrivers + * + * Initialize boot drivers and free memory for boot files. + * + * Parameters + * None + * + * Return Value + * None + */ + +VOID INIT_FUNCTION +IopInitializeBootDrivers(VOID) +{ + ULONG BootDriverCount; + ULONG ModuleStart; + ULONG ModuleSize; + ULONG ModuleLoaded; + PCHAR ModuleName; + PCHAR Extension; + PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr; + ULONG i; + + DPRINT("IopInitializeBootDrivers()\n"); + + BootDriverCount = 0; + for (i = 2; i < KeLoaderBlock.ModsCount; i++) + { + ModuleStart = KeLoaderModules[i].ModStart; + ModuleSize = KeLoaderModules[i].ModEnd - ModuleStart; + ModuleName = (PCHAR)KeLoaderModules[i].String; + ModuleLoaded = KeLoaderModules[i].Reserved; + Extension = strrchr(ModuleName, '.'); + if (Extension == NULL) + Extension = ""; + + /* + * Pass symbol files to kernel debugger + */ + if (!_stricmp(Extension, ".sym")) + { + KDB_SYMBOLFILE_HOOK(ModuleLoadBase, FileName, Length); + } else + + /* + * Load builtin driver + */ + if (!_stricmp(Extension, ".sys")) + { + if (!ModuleLoaded) + { + IopInitializeBuiltinDriver(NULL, (PVOID)ModuleStart, ModuleName, + ModuleSize); + } + ++BootDriverCount; + } + + /* + * Free memory for all boot files, except ntoskrnl.exe and hal.dll + */ +#ifdef KDBG + /* + * Do not free the memory from symbol files, if the kernel debugger + * is active + */ + if (!_stricmp(Extension, ".sym")) +#endif + { + MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart, + KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); + } + } + + if (BootDriverCount == 0) + { + DbgPrint("No boot drivers available.\n"); + KEBUGCHECK(0); + } +} + +/* + * IopInitializeSystemDrivers + * + * Load drivers marked as system start. + * + * Parameters + * None + * + * Return Value + * None + */ + +VOID INIT_FUNCTION +IopInitializeSystemDrivers(VOID) +{ + PLIST_ENTRY GroupEntry; + PLIST_ENTRY ServiceEntry; + PSERVICE_GROUP CurrentGroup; + PSERVICE CurrentService; + NTSTATUS Status; + + DPRINT("IopInitializeSystemDrivers()\n"); + + GroupEntry = GroupListHead.Flink; + while (GroupEntry != &GroupListHead) + { + CurrentGroup = CONTAINING_RECORD(GroupEntry, SERVICE_GROUP, GroupListEntry); + + DPRINT("Group: %wZ\n", &CurrentGroup->GroupName); + + ServiceEntry = ServiceListHead.Flink; + while (ServiceEntry != &ServiceListHead) + { + CurrentService = CONTAINING_RECORD(ServiceEntry, SERVICE, ServiceListEntry); + + if ((RtlCompareUnicodeString(&CurrentGroup->GroupName, + &CurrentService->ServiceGroup, TRUE) == 0) && + (CurrentService->Start == 1 /*SERVICE_SYSTEM_START*/)) + { + DPRINT(" Path: %wZ\n", &CurrentService->RegistryPath); + IopDisplayLoadingMessage(CurrentService->ServiceName.Buffer); + Status = NtLoadDriver(&CurrentService->RegistryPath); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtLoadDriver() failed (Status %lx)\n", Status); +#if 0 + if (CurrentService->ErrorControl == 1) + { + /* Log error */ + } else + if (CurrentService->ErrorControl == 2) + { + if (IsLastKnownGood == FALSE) + { + /* Boot last known good configuration */ + } + } else + if (CurrentService->ErrorControl == 3) + { + if (IsLastKnownGood == FALSE) + { + /* Boot last known good configuration */ + } else + { + /* BSOD! */ + } + } +#endif + } + } + ServiceEntry = ServiceEntry->Flink; + } + + GroupEntry = GroupEntry->Flink; + } + + DPRINT("IopInitializeSystemDrivers() done\n"); +} + +/* + * IopGetDriverNameFromKeyNode + * + * Returns a module path from service registry key node. + * + * Parameters + * ImagePath + * The result path. + * KeyHandle + * Registry handle for service registry key node + * (\Registry\Machine\System\CurrentControlSet\Services\...) + * + * Return Value + * Status + */ + +NTSTATUS STDCALL +IopGetDriverNameFromKeyNode(PUNICODE_STRING ImagePath, HANDLE KeyHandle) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + UNICODE_STRING RegistryImagePath; + NTSTATUS Status; + PKEY_NODE_INFORMATION NodeInformation; + ULONG ResultLength; + + RtlZeroMemory(&QueryTable, sizeof(QueryTable)); + RtlInitUnicodeString(&RegistryImagePath, NULL); + + QueryTable[0].Name = L"ImagePath"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &RegistryImagePath; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWSTR)KeyHandle, QueryTable, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + RtlFreeUnicodeString(&RegistryImagePath); + return STATUS_UNSUCCESSFUL; + } + + if (RegistryImagePath.Length == 0) + { + RtlFreeUnicodeString(&RegistryImagePath); + ZwQueryKey(KeyHandle, KeyNodeInformation, 0, 0, &ResultLength); + NodeInformation = ExAllocatePool(NonPagedPool, ResultLength); + if (NodeInformation == NULL) + { + return STATUS_UNSUCCESSFUL; + } + Status = ZwQueryKey(KeyHandle, KeyNodeInformation, NodeInformation, + ResultLength, &ResultLength); + if (!NT_SUCCESS(Status)) + { + ExFreePool(NodeInformation); + return STATUS_UNSUCCESSFUL; + } + ImagePath->Length = sizeof(UNICODE_NULL) + + ((33 + NodeInformation->NameLength) * sizeof(WCHAR)); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->Length); + if (ImagePath->Buffer == NULL) + { + ExFreePool(NodeInformation); + return STATUS_UNSUCCESSFUL; + } + wcscpy(ImagePath->Buffer, L"\\SystemRoot\\system32\\drivers\\"); + wcscat(ImagePath->Buffer, NodeInformation->Name); + wcscat(ImagePath->Buffer, L".sys"); + } else + if (RegistryImagePath.Buffer[0] != L'\\') + { + ImagePath->Length = sizeof(UNICODE_NULL) + + ((12 + wcslen(RegistryImagePath.Buffer)) * sizeof(WCHAR)); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->Length); + if (ImagePath->Buffer == NULL) + { + RtlFreeUnicodeString(&RegistryImagePath); + return STATUS_UNSUCCESSFUL; + } + wcscpy(ImagePath->Buffer, L"\\SystemRoot\\"); + wcscat(ImagePath->Buffer, RegistryImagePath.Buffer); + RtlFreeUnicodeString(&RegistryImagePath); + } else + { + ImagePath->Length = RegistryImagePath.Length; + ImagePath->Buffer = RegistryImagePath.Buffer; + } + + return STATUS_SUCCESS; +} + +/* + * IopInitializeDeviceNodeService + * + * Initialize service for given device node. + * + * Parameters + * DeviceNode + * The device node to initialize service for. + * BootDriverOnly + * Initialize driver only if it's marked as boot start. + * + * Return Value + * Status + */ + +NTSTATUS +IopInitializeDeviceNodeService(PDEVICE_NODE DeviceNode, BOOLEAN BootDriverOnly) +{ + HANDLE KeyHandle; + NTSTATUS Status; + + if (DeviceNode->ServiceName.Buffer == NULL) + { + return STATUS_UNSUCCESSFUL; + } + + Status = RtlpGetRegistryHandle(RTL_REGISTRY_SERVICES, + DeviceNode->ServiceName.Buffer, FALSE, &KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status); + return Status; + } + + if (BootDriverOnly) + { + ULONG ServiceStart; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr; + + /* + * Get service start value + */ + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + QueryTable[0].Name = L"Start"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &ServiceStart; + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, + (PWCHAR)KeyHandle, QueryTable, NULL, NULL); + NtClose(KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); + return Status; + } + + /* + * Find and initialize boot driver + */ + if (ServiceStart == 0 /*SERVICE_BOOT_START*/) + { + ULONG i; + CHAR SearchName[256]; + ULONG ModuleStart, ModuleSize; + PCHAR ModuleName; + + /* FIXME: Guard for buffer overflow */ + sprintf(SearchName, "%S.sys", DeviceNode->ServiceName.Buffer); + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + ModuleStart = KeLoaderModules[i].ModStart; + ModuleSize = KeLoaderModules[i].ModEnd - ModuleStart; + ModuleName = (PCHAR)KeLoaderModules[i].String; + if (!strcmp(ModuleName, SearchName)) + { + IopInitializeBuiltinDriver(DeviceNode, + (PVOID)ModuleStart, ModuleName, ModuleSize); + /* Tell, that the module is already loaded */ + KeLoaderModules[i].Reserved = 1; + } + } + return STATUS_SUCCESS; + } else + { + return STATUS_UNSUCCESSFUL; + } + } else + { + UNICODE_STRING ImagePath; + + /* + * Get service path + */ + Status = IopGetDriverNameFromKeyNode(&ImagePath, KeyHandle); + NtClose(KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); + return Status; + } + + /* + * Display loading message + */ + IopDisplayLoadingMessage(DeviceNode->ServiceName.Buffer); + + /* + * Load the service + */ + Status = IopInitializeService(DeviceNode, &ImagePath); + + /* + * Free the service path + */ + RtlFreeUnicodeString(&ImagePath); + } + + return Status; +} + +/* + * IopUnloadDriver + * + * Unloads a device driver. + * + * Parameters + * DriverServiceName + * Name of the service to unload (registry key). + * UnloadPnpDrivers + * Whether to unload Plug & Plug or only legacy drivers. If this + * parameter is set to FALSE, the routine will unload only legacy + * drivers. + * + * Return Value + * Status + * + * To do + * Guard the whole function by SEH. + */ + +NTSTATUS STDCALL +IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) +{ + UNICODE_STRING ImagePath; + UNICODE_STRING ObjectName; + PDRIVER_OBJECT DriverObject; + PMODULE_OBJECT ModuleObject; + HANDLE KeyHandle; + NTSTATUS Status; + LPWSTR Start; + + DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers); + + /* + * Get the service name from the module name + */ + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); + if (Start == NULL) + Start = DriverServiceName->Buffer; + else + Start++; + + /* + * Construct the driver object name + */ + ObjectName.Length = wcslen(Start) + 8; + ObjectName.Buffer = ExAllocatePool(NonPagedPool, + ObjectName.Length * sizeof(WCHAR)); + wcscpy(ObjectName.Buffer, L"\\Driver\\"); + memcpy(ObjectName.Buffer + 8, Start, (ObjectName.Length - 8) * sizeof(WCHAR)); + + /* + * Find the driver object + */ + Status = ObReferenceObjectByName(&ObjectName, 0, 0, 0, IoDriverObjectType, + KernelMode, 0, (PVOID*)&DriverObject); + if (!NT_SUCCESS(Status)) + { + DPRINT("Can't locate driver object for %wZ\n", ObjectName); + return Status; + } + + /* + * Free the buffer for driver object name + */ + ExFreePool(ObjectName.Buffer); + + /* + * Get path of service... + */ + Status = RtlpGetRegistryHandle(RTL_REGISTRY_ABSOLUTE, + DriverServiceName->Buffer, FALSE, &KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status); + return Status; + } + Status = IopGetDriverNameFromKeyNode(&ImagePath, KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); + NtClose(KeyHandle); + return Status; + } + NtClose(KeyHandle); + + /* + * ... and check if it's loaded + */ + ModuleObject = LdrGetModuleObject(&ImagePath); + if (ModuleObject == NULL) + { + return STATUS_UNSUCCESSFUL; + } + + /* + * Free the service path + */ + RtlFreeUnicodeString(&ImagePath); + + /* + * Unload the module and release the references to the device object + */ + if (DriverObject->DriverUnload) + (*DriverObject->DriverUnload)(DriverObject); + ObDereferenceObject(DriverObject); + ObDereferenceObject(DriverObject); + LdrUnloadModule(ModuleObject); + + return STATUS_SUCCESS; +} + +/* FUNCTIONS ******************************************************************/ + +/* + * NtLoadDriver + * + * Loads a device driver. + * + * Parameters + * DriverServiceName + * Name of the service to load (registry key). + * + * Return Value + * Status + */ + +NTSTATUS STDCALL +NtLoadDriver(IN PUNICODE_STRING DriverServiceName) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + UNICODE_STRING ImagePath; + HANDLE KeyHandle; + NTSTATUS Status; + ULONG Type; + PDEVICE_NODE DeviceNode; + PMODULE_OBJECT ModuleObject; + LPWSTR Start; + + DPRINT("NtLoadDriver('%wZ')\n", DriverServiceName); + + /* + * Check security privileges + */ +#if 0 + if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, KeGetPreviousMode())) + return STATUS_PRIVILEGE_NOT_HELD; +#endif + + RtlInitUnicodeString(&ImagePath, NULL); + + /* + * Open service registry key + */ + Status = RtlpGetRegistryHandle(RTL_REGISTRY_ABSOLUTE, + DriverServiceName->Buffer, FALSE, &KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status); + return Status; + } + + /* + * Get service type + */ + RtlZeroMemory(&QueryTable, sizeof(QueryTable)); + QueryTable[0].Name = L"Type"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT | RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[0].EntryContext = &Type; + Status = RtlQueryRegistryValues(RTL_REGISTRY_HANDLE, (PWSTR)KeyHandle, + QueryTable, NULL, NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); + RtlFreeUnicodeString(&ImagePath); + NtClose(KeyHandle); + return Status; + } + + /* + * Get module path + */ + Status = IopGetDriverNameFromKeyNode(&ImagePath, KeyHandle); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); + NtClose(KeyHandle); + return Status; + } + + /* + * Close service registry key + */ + NtClose(KeyHandle); + + DPRINT("FullImagePath: '%S'\n", ImagePath.Buffer); + DPRINT("Type: %lx\n", Type); + + /* + * See, if the driver module isn't already loaded + */ + ModuleObject = LdrGetModuleObject(&ImagePath); + if (ModuleObject != NULL) + { + return STATUS_IMAGE_ALREADY_LOADED; + } + + /* + * Create device node + */ + /* Use IopRootDeviceNode for now */ + Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status); + return Status; + } + + /* + * Load the driver module + */ + Status = LdrLoadModule(&ImagePath, &ModuleObject); + if (!NT_SUCCESS(Status)) + { + DPRINT("LdrLoadModule() failed (Status %lx)\n", Status); + IopFreeDeviceNode(DeviceNode); + return Status; + } + + /* + * Set a service name for the device node + */ + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); + if (Start == NULL) + Start = DriverServiceName->Buffer; + else + Start++; + RtlCreateUnicodeString(&DeviceNode->ServiceName, Start); + + /* + * Initialize the driver module + */ + Status = IopInitializeDriver( + ModuleObject->EntryPoint, + DeviceNode, + (Type == 2 /*SERVICE_FILE_SYSTEM_DRIVER*/ || + Type == 8 /*SERVICE_RECOGNIZER_DRIVER*/), + ModuleObject->Base, + ModuleObject->Length, + FALSE); + if (!NT_SUCCESS(Status)) + { + DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status); + LdrUnloadModule(ModuleObject); + IopFreeDeviceNode(DeviceNode); + } + + return Status; +} + +/* + * NtUnloadDriver + * + * Unloads a legacy device driver. + * + * Parameters + * DriverServiceName + * Name of the service to unload (registry key). + * + * Return Value + * Status + */ + +NTSTATUS STDCALL +NtUnloadDriver(IN PUNICODE_STRING DriverServiceName) +{ + return IopUnloadDriver(DriverServiceName, FALSE); +} + /* EOF */ diff --git a/reactos/ntoskrnl/io/iomgr.c b/reactos/ntoskrnl/io/iomgr.c index 315d6844427..1cb4984dfed 100644 --- a/reactos/ntoskrnl/io/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr.c @@ -1,4 +1,4 @@ -/* $Id: iomgr.c,v 1.40 2003/10/12 17:05:45 hbirr Exp $ +/* $Id: iomgr.c,v 1.41 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -389,6 +389,14 @@ IoInit2(VOID) CPRINT("IopInitializeDriver() failed with status (%x)\n", Status); return; } + + /* + * Initialize PnP root releations + */ + IopInvalidateDeviceRelations( + IopRootDeviceNode, + BusRelations, + TRUE); } /* diff --git a/reactos/ntoskrnl/io/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr.c index ad241ab1072..53ba52f3ca4 100644 --- a/reactos/ntoskrnl/io/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr.c @@ -1,4 +1,4 @@ -/* $Id: pnpmgr.c,v 1.20 2003/10/12 17:05:45 hbirr Exp $ +/* $Id: pnpmgr.c,v 1.21 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -571,667 +571,683 @@ IopTraverseDeviceTree( } +/* + * IopActionInterrogateDeviceStack + * + * Retrieve information for all (direct) child nodes of a parent node. + * + * Parameters + * DeviceNode + * Pointer to device node. + * Context + * Pointer to parent node to retrieve child node information for. + * + * Remarks + * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) + * when we reach a device node which is not a direct child of the device + * node for which we retrieve information of child nodes for. Any errors + * that occur is logged instead so that all child services have a chance + * of being interrogated. + */ + NTSTATUS IopActionInterrogateDeviceStack( - PDEVICE_NODE DeviceNode, - PVOID Context) -/* - * FUNCTION: Retrieve information for all (direct) child nodes of a parent node - * ARGUMENTS: - * DeviceNode = Pointer to device node - * Context = Pointer to parent node to retrieve child node information for - * NOTES: - * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) - * when we reach a device node which is not a direct child of the device node - * for which we retrieve information of child nodes for. Any errors that occur - * is logged instead so that all child services have a chance of beeing - * interrogated. - */ + PDEVICE_NODE DeviceNode, + PVOID Context) { - IO_STATUS_BLOCK IoStatusBlock; - PDEVICE_NODE ParentDeviceNode; - WCHAR InstancePath[MAX_PATH]; - IO_STACK_LOCATION Stack; - NTSTATUS Status; - PWSTR KeyBuffer; + IO_STATUS_BLOCK IoStatusBlock; + PDEVICE_NODE ParentDeviceNode; + WCHAR InstancePath[MAX_PATH]; + IO_STACK_LOCATION Stack; + NTSTATUS Status; + PWSTR KeyBuffer; - DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context); + DPRINT("IopActionInterrogateDeviceStack(%p, %p)\n", DeviceNode, Context); + DPRINT("PDO %x\n", DeviceNode->Pdo); - DPRINT("PDO %x\n", DeviceNode->Pdo); + ParentDeviceNode = (PDEVICE_NODE)Context; + /* + * We are called for the parent too, but we don't need to do special + * handling for this node + */ - ParentDeviceNode = (PDEVICE_NODE)Context; + if (DeviceNode == ParentDeviceNode) + { + DPRINT("Success\n"); + return STATUS_SUCCESS; + } - /* We are called for the parent too, but we don't need to do special - handling for this node */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } + /* + * Make sure this device node is a direct child of the parent device node + * that is given as an argument + */ - /* Make sure this device node is a direct child of the parent device node - that is given as an argument */ - if (DeviceNode->Parent != ParentDeviceNode) - { - /* Stop the traversal immediately and indicate successful operation */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } + if (DeviceNode->Parent != ParentDeviceNode) + { + /* Stop the traversal immediately and indicate successful operation */ + DPRINT("Stop\n"); + return STATUS_UNSUCCESSFUL; + } + /* + * FIXME: For critical errors, cleanup and disable device, but always + * return STATUS_SUCCESS. + */ - /* FIXME: For critical errors, cleanup and disable device, but always return STATUS_SUCCESS */ + DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n"); + Stack.Parameters.QueryId.IdType = BusQueryDeviceID; + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_ID, + &Stack); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString( + &DeviceNode->DeviceID, + (LPWSTR)IoStatusBlock.Information); - DPRINT("Sending IRP_MN_QUERY_ID.BusQueryDeviceID to device stack\n"); + /* + * FIXME: Check for valid characters, if there is invalid characters + * then bugcheck. + */ + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + RtlInitUnicodeString(&DeviceNode->DeviceID, NULL); + } - Stack.Parameters.QueryId.IdType = BusQueryDeviceID; + DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n"); - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_ID, - &Stack); - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString( - &DeviceNode->DeviceID, - (LPWSTR)IoStatusBlock.Information); - - /* FIXME: Check for valid characters, if there is invalid characters then bugcheck */ - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - RtlInitUnicodeString(&DeviceNode->DeviceID, NULL); - } - - - DPRINT("Sending IRP_MN_QUERY_ID.BusQueryInstanceID to device stack\n"); - - Stack.Parameters.QueryId.IdType = BusQueryInstanceID; - - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_ID, - &Stack); - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString( + Stack.Parameters.QueryId.IdType = BusQueryInstanceID; + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_ID, + &Stack); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString( &DeviceNode->InstanceID, (LPWSTR)IoStatusBlock.Information); - /* FIXME: Check for valid characters, if there is invalid characters then bugcheck */ - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - RtlInitUnicodeString(&DeviceNode->InstanceID, NULL); - } + /* + * FIXME: Check for valid characters, if there is invalid characters + * then bugcheck + */ + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + RtlInitUnicodeString(&DeviceNode->InstanceID, NULL); + } + /* FIXME: SEND IRP_QUERY_ID.BusQueryHardwareIDs */ + /* FIXME: SEND IRP_QUERY_ID.BusQueryCompatibleIDs */ - /* FIXME: SEND IRP_QUERY_ID.BusQueryHardwareIDs */ - /* FIXME: SEND IRP_QUERY_ID.BusQueryCompatibleIDs */ + Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags); + if (NT_SUCCESS(Status)) + { + } + else + { + } + DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n"); - Status = IopQueryCapabilities(DeviceNode->Pdo, &DeviceNode->CapabilityFlags); - if (NT_SUCCESS(Status)) - { - } - else - { - } + Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription; + Stack.Parameters.QueryDeviceText.LocaleId = 0; /* FIXME */ + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_DEVICE_TEXT, + &Stack); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString( + &DeviceNode->DeviceText, + (LPWSTR)IoStatusBlock.Information); + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + RtlInitUnicodeString(&DeviceNode->DeviceText, NULL); + } + DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n"); - DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextDescription to device stack\n"); + Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation; + Stack.Parameters.QueryDeviceText.LocaleId = 0; // FIXME + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_DEVICE_TEXT, + &Stack); + if (NT_SUCCESS(Status)) + { + RtlInitUnicodeString( + &DeviceNode->DeviceTextLocation, + (LPWSTR)IoStatusBlock.Information); + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + RtlInitUnicodeString(&DeviceNode->DeviceTextLocation, NULL); + } - Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextDescription; - Stack.Parameters.QueryDeviceText.LocaleId = 0; // FIXME + DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n"); - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_TEXT, - &Stack); - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString( - &DeviceNode->DeviceText, - (LPWSTR)IoStatusBlock.Information); - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - RtlInitUnicodeString(&DeviceNode->DeviceText, NULL); - } + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_BUS_INFORMATION, + NULL); + if (NT_SUCCESS(Status)) + { + DeviceNode->BusInformation = + (PPNP_BUS_INFORMATION)IoStatusBlock.Information; + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + DeviceNode->BusInformation = NULL; + } + DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n"); - DPRINT("Sending IRP_MN_QUERY_DEVICE_TEXT.DeviceTextLocation to device stack\n"); + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_RESOURCES, + NULL); + if (NT_SUCCESS(Status)) + { + DeviceNode->BootResourcesList = + (PCM_RESOURCE_LIST)IoStatusBlock.Information; + DeviceNode->Flags |= DNF_HAS_BOOT_CONFIG; + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + DeviceNode->BootResourcesList = NULL; + } - Stack.Parameters.QueryDeviceText.DeviceTextType = DeviceTextLocationInformation; - Stack.Parameters.QueryDeviceText.LocaleId = 0; // FIXME + DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n"); - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_TEXT, - &Stack); - if (NT_SUCCESS(Status)) - { - RtlInitUnicodeString( - &DeviceNode->DeviceTextLocation, - (LPWSTR)IoStatusBlock.Information); - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - RtlInitUnicodeString(&DeviceNode->DeviceTextLocation, NULL); - } + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_RESOURCE_REQUIREMENTS, + NULL); + if (NT_SUCCESS(Status)) + { + DeviceNode->ResourceRequirementsList = + (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information; + } + else + { + DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); + DeviceNode->ResourceRequirementsList = NULL; + } + /* + * Assemble the instance path for the device + */ - DPRINT("Sending IRP_MN_QUERY_BUS_INFORMATION to device stack\n"); + wcscpy(InstancePath, DeviceNode->DeviceID.Buffer); + wcscat(InstancePath, L"\\"); + wcscat(InstancePath, DeviceNode->InstanceID.Buffer); - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_BUS_INFORMATION, - NULL); - if (NT_SUCCESS(Status)) - { - DeviceNode->BusInformation = - (PPNP_BUS_INFORMATION)IoStatusBlock.Information; - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - DeviceNode->BusInformation = NULL; - } + if (!DeviceNode->CapabilityFlags->UniqueID) + { + DPRINT("Instance ID is not unique\n"); + /* FIXME: Add information from parent bus driver to InstancePath */ + } + if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool)) + { + DPRINT("No resources\n"); + /* FIXME: Cleanup and disable device */ + } - DPRINT("Sending IRP_MN_QUERY_RESOURCES to device stack\n"); + DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer); - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_RESOURCES, - NULL); - if (NT_SUCCESS(Status)) - { - DeviceNode->BootResourcesList = - (PCM_RESOURCE_LIST)IoStatusBlock.Information; - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - DeviceNode->BootResourcesList = NULL; - } + /* + * Create registry key for the instance id, if it doesn't exist yet + */ + KeyBuffer = ExAllocatePool(PagedPool, (49 + DeviceNode->InstancePath.Length) * sizeof(WCHAR)); + wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); + wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); + RtlpCreateRegistryKeyPath(KeyBuffer); + ExFreePool(KeyBuffer); + DeviceNode->Flags |= DNF_PROCESSED; - DPRINT("Sending IRP_MN_QUERY_RESOURCE_REQUIREMENTS to device stack\n"); - - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_RESOURCE_REQUIREMENTS, - NULL); - if (NT_SUCCESS(Status)) - { - DeviceNode->ResourceRequirementsList = - (PIO_RESOURCE_REQUIREMENTS_LIST)IoStatusBlock.Information; - } - else - { - DPRINT("IopInitiatePnpIrp() failed (Status %x)\n", Status); - DeviceNode->ResourceRequirementsList = NULL; - } - - - /* Assemble the instance path for the device */ - - wcscpy(InstancePath, DeviceNode->DeviceID.Buffer); - wcscat(InstancePath, L"\\"); - wcscat(InstancePath, DeviceNode->InstanceID.Buffer); - - if (!DeviceNode->CapabilityFlags->UniqueID) - { - DPRINT("Instance ID is not unique\n"); - /* FIXME: Add information from parent bus driver to InstancePath */ - } - - if (!IopCreateUnicodeString(&DeviceNode->InstancePath, InstancePath, PagedPool)) { - DPRINT("No resources\n"); - /* FIXME: Cleanup and disable device */ - } - - DPRINT("InstancePath is %S\n", DeviceNode->InstancePath.Buffer); - - /* - * Create registry key for the instance id, if it doesn't exist yet - */ - KeyBuffer = ExAllocatePool(PagedPool, (49 + DeviceNode->InstancePath.Length) * sizeof(WCHAR)); - wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); - wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); - RtlpCreateRegistryKeyPath(KeyBuffer); - ExFreePool(KeyBuffer); - DeviceNode->Flags |= DNF_PROCESSED; - - return STATUS_SUCCESS; + return STATUS_SUCCESS; } +/* + * IopActionConfigureChildServices + * + * Retrieve configuration for all (direct) child nodes of a parent node. + * + * Parameters + * DeviceNode + * Pointer to device node. + * Context + * Pointer to parent node to retrieve child node configuration for. + * + * Remarks + * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) + * when we reach a device node which is not a direct child of the device + * node for which we configure child services for. Any errors that occur is + * logged instead so that all child services have a chance of beeing + * configured. + */ NTSTATUS IopActionConfigureChildServices( PDEVICE_NODE DeviceNode, PVOID Context) -/* - * FUNCTION: Retrieve configuration for all (direct) child nodes of a parent node - * ARGUMENTS: - * DeviceNode = Pointer to device node - * Context = Pointer to parent node to retrieve child node configuration for - * NOTES: - * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) - * when we reach a device node which is not a direct child of the device - * node for which we configure child services for. Any errors that occur is - * logged instead so that all child services have a chance of beeing - * configured. - */ { -/* - * FIXME: There are two versions of this function: one that creates registry - * and one that doesn't. The second is the right, but could not be used because - * there is not automatic parent key generation. - * - * Update: It could propably be used now, but there's no need anymore. - * - * FiN - */ -#if 1 - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - PDEVICE_NODE ParentDeviceNode; - PUNICODE_STRING Service; - NTSTATUS Status; + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + PDEVICE_NODE ParentDeviceNode; + PUNICODE_STRING Service; + NTSTATUS Status; - DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context); + DPRINT("IopActionConfigureChildServices(%p, %p)\n", DeviceNode, Context); - ParentDeviceNode = (PDEVICE_NODE)Context; + ParentDeviceNode = (PDEVICE_NODE)Context; - /* We are called for the parent too, but we don't need to do special - handling for this node */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } + /* + * We are called for the parent too, but we don't need to do special + * handling for this node + */ + if (DeviceNode == ParentDeviceNode) + { + DPRINT("Success\n"); + return STATUS_SUCCESS; + } - /* Make sure this device node is a direct child of the parent device node - that is given as an argument */ - if (DeviceNode->Parent != ParentDeviceNode) - { - /* Stop the traversal immediately and indicate successful operation */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } + /* + * Make sure this device node is a direct child of the parent device node + * that is given as an argument + */ + if (DeviceNode->Parent != ParentDeviceNode) + { + /* Stop the traversal immediately and indicate successful operation */ + DPRINT("Stop\n"); + return STATUS_UNSUCCESSFUL; + } - /* Retrieve configuration from Enum key */ + if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED)) + { + /* + * Retrieve configuration from Enum key + */ - Service = &DeviceNode->ServiceName; + Service = &DeviceNode->ServiceName; - RtlZeroMemory(QueryTable, sizeof(QueryTable)); + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + RtlInitUnicodeString(Service, NULL); - RtlInitUnicodeString(Service, NULL); + QueryTable[0].Name = L"Service"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = Service; - QueryTable[0].Name = L"Service"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = Service; + Status = RtlQueryRegistryValues(RTL_REGISTRY_ENUM, + DeviceNode->InstancePath.Buffer, QueryTable, NULL, NULL); - Status = RtlQueryRegistryValues( - RTL_REGISTRY_ENUM, - DeviceNode->InstancePath.Buffer, - QueryTable, - NULL, - NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); + /* FIXME: Log the error */ + CPRINT("Could not retrieve configuration for device %S (Status %x)\n", + DeviceNode->InstancePath.Buffer, Status); + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + return STATUS_SUCCESS; + } - DPRINT("RtlQueryRegistryValues() returned status %x\n", Status); - DPRINT("Key: %S\n", DeviceNode->InstancePath.Buffer); + if (Service->Buffer == NULL) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + return STATUS_SUCCESS; + } - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - CPRINT("Could not retrieve configuration for device %S (Status %x)\n", - DeviceNode->InstancePath.Buffer, Status); - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - return STATUS_SUCCESS; - } + DPRINT("Got Service %S\n", Service->Buffer); + } - if (Service->Buffer == NULL) - { - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - return STATUS_SUCCESS; - } - - DPRINT("Got Service %S\n", Service->Buffer); - - return STATUS_SUCCESS; -#else - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - PDEVICE_NODE ParentDeviceNode; - PUNICODE_STRING Service; - HANDLE KeyHandle; - NTSTATUS Status; - - DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context); - - ParentDeviceNode = (PDEVICE_NODE)Context; - - /* We are called for the parent too, but we don't need to do special - handling for this node */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } - - /* Make sure this device node is a direct child of the parent device node - that is given as an argument */ - if (DeviceNode->Parent != ParentDeviceNode) - { - /* Stop the traversal immediately and indicate successful operation */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } - - /* Retrieve configuration from Enum key */ - - Service = &DeviceNode->ServiceName; - - Status = RtlpGetRegistryHandle( - RTL_REGISTRY_ENUM, - DeviceNode->InstancePath.Buffer, - TRUE, - &KeyHandle); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlpGetRegistryHandle() failed (Status %x)\n", Status); - return Status; - } - - RtlZeroMemory(QueryTable, sizeof(QueryTable)); - - RtlInitUnicodeString(Service, NULL); - - QueryTable[0].Name = L"Service"; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; - QueryTable[0].EntryContext = Service; - - Status = RtlQueryRegistryValues( - RTL_REGISTRY_HANDLE, - (PWSTR)KeyHandle, - QueryTable, - NULL, - NULL); - NtClose(KeyHandle); - - DPRINT("RtlQueryRegistryValues() returned status %x\n", Status); - - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - CPRINT("Could not retrieve configuration for device %S (Status %x)\n", - DeviceNode->InstancePath.Buffer, Status); - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); - return STATUS_SUCCESS; - } - - DPRINT("Got Service %S\n", Service->Buffer); - - return STATUS_SUCCESS; -#endif + return STATUS_SUCCESS; } +/* + * IopActionInitChildServices + * + * Initialize the service for all (direct) child nodes of a parent node + * + * Parameters + * DeviceNode + * Pointer to device node. + * Context + * Pointer to parent node to initialize child node services for. + * BootDrivers + * Load only driver marked as boot start. + * + * Remarks + * If the driver image for a service is not loaded and initialized + * it is done here too. We only return a status code indicating an + * error (STATUS_UNSUCCESSFUL) when we reach a device node which is + * not a direct child of the device node for which we initialize + * child services for. Any errors that occur is logged instead so + * that all child services have a chance of being initialized. + */ NTSTATUS IopActionInitChildServices( + PDEVICE_NODE DeviceNode, + PVOID Context, + BOOLEAN BootDrivers) +{ + PDEVICE_NODE ParentDeviceNode; + NTSTATUS Status; + + DPRINT("IopActionInitChildServices(%p, %p, %d)\n", DeviceNode, Context, + BootDrivers); + + ParentDeviceNode = (PDEVICE_NODE)Context; + + /* + * We are called for the parent too, but we don't need to do special + * handling for this node + */ + if (DeviceNode == ParentDeviceNode) + { + DPRINT("Success\n"); + return STATUS_SUCCESS; + } + + /* + * Make sure this device node is a direct child of the parent device node + * that is given as an argument + */ +#if 0 + if (DeviceNode->Parent != ParentDeviceNode) + { + /* + * Stop the traversal immediately and indicate unsuccessful operation + */ + DPRINT("Stop\n"); + return STATUS_UNSUCCESSFUL; + } +#endif + + if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) && + !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && + !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) + { + Status = IopInitializeDeviceNodeService(DeviceNode, BootDrivers); + if (NT_SUCCESS(Status)) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + } else + { + /* + * Don't disable when trying to load only boot drivers + */ + if (!BootDrivers) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + IopDeviceNodeSetFlag(DeviceNode, DNF_START_FAILED); + } + /* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */ + CPRINT("Initialization of service %S failed (Status %x)\n", + DeviceNode->ServiceName.Buffer, Status); + } + } else + { + DPRINT("Service %S is disabled or already initialized\n", + DeviceNode->ServiceName.Buffer); + } + + return STATUS_SUCCESS; +} + +/* + * IopActionInitAllServices + * + * Initialize the service for all (direct) child nodes of a parent node. This + * function just calls IopActionInitChildServices with BootDrivers = FALSE. + */ + +NTSTATUS +IopActionInitAllServices( PDEVICE_NODE DeviceNode, PVOID Context) -/* - * FUNCTION: Initialize the service for all (direct) child nodes of a parent node - * ARGUMENTS: - * DeviceNode = Pointer to device node - * Context = Pointer to parent node to initialize child node services for - * NOTES: - * If the driver image for a service is not loaded and initialized - * it is done here too. - * We only return a status code indicating an error (STATUS_UNSUCCESSFUL) - * when we reach a device node which is not a direct child of the device - * node for which we initialize child services for. Any errors that occur is - * logged instead so that all child services have a chance of beeing - * initialized. - */ { - PDEVICE_NODE ParentDeviceNode; - NTSTATUS Status; + return IopActionInitChildServices(DeviceNode, Context, FALSE); +} - DPRINT("DeviceNode %x Context %x\n", DeviceNode, Context); +/* + * IopActionInitBootServices + * + * Initialize the boot start services for all (direct) child nodes of a + * parent node. This function just calls IopActionInitChildServices with + * BootDrivers = TRUE. + */ - ParentDeviceNode = (PDEVICE_NODE)Context; +NTSTATUS +IopActionInitBootServices( + PDEVICE_NODE DeviceNode, + PVOID Context) +{ + return IopActionInitChildServices(DeviceNode, Context, TRUE); +} - /* We are called for the parent too, but we don't need to do special - handling for this node */ - if (DeviceNode == ParentDeviceNode) - { - DPRINT("Success\n"); - return STATUS_SUCCESS; - } +/* + * IopInitializePnpServices + * + * Initialize services for discovered children + * + * Parameters + * DeviceNode + * Top device node to start initializing services. + * BootDrivers + * When set to TRUE, only drivers marked as boot start will + * be loaded. Otherwise, all drivers will be loaded. + * + * Return Value + * Status + */ - /* Make sure this device node is a direct child of the parent device node - that is given as an argument */ - if (DeviceNode->Parent != ParentDeviceNode) - { - /* Stop the traversal immediately and indicate successful operation */ - DPRINT("Stop\n"); - return STATUS_UNSUCCESSFUL; - } +NTSTATUS +IopInitializePnpServices( + IN PDEVICE_NODE DeviceNode, + IN BOOLEAN BootDrivers) +{ + DEVICETREE_TRAVERSE_CONTEXT Context; - if (!IopDeviceNodeHasFlag(DeviceNode, DNF_DISABLED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && - !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) - { - Status = IopInitializeDeviceNodeService(DeviceNode); - if (NT_SUCCESS(Status)) - { - IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); - } - else - { - IopDeviceNodeSetFlag(DeviceNode, DNF_DISABLED); + DPRINT("IopInitializePnpServices(%p, %d)\n", DeviceNode, BootDrivers); - /* FIXME: Log the error (possibly in IopInitializeDeviceNodeService) */ - CPRINT("Initialization of service %S failed (Status %x)\n", - DeviceNode->ServiceName.Buffer, Status); - } - } - else - { - DPRINT("Service %S is disabled or already initialized\n", - DeviceNode->ServiceName.Buffer); - } + if (BootDrivers) + { + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInitBootServices, + DeviceNode); + } else + { + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionInitAllServices, + DeviceNode); + } - return STATUS_SUCCESS; + return IopTraverseDeviceTree(&Context); } NTSTATUS IopInvalidateDeviceRelations( IN PDEVICE_NODE DeviceNode, - IN DEVICE_RELATION_TYPE Type) + IN DEVICE_RELATION_TYPE Type, + IN BOOLEAN BootDriver) { - DEVICETREE_TRAVERSE_CONTEXT Context; - PDEVICE_RELATIONS DeviceRelations; - IO_STATUS_BLOCK IoStatusBlock; - PDEVICE_NODE ChildDeviceNode; - IO_STACK_LOCATION Stack; - NTSTATUS Status; - ULONG i; + DEVICETREE_TRAVERSE_CONTEXT Context; + PDEVICE_RELATIONS DeviceRelations; + IO_STATUS_BLOCK IoStatusBlock; + PDEVICE_NODE ChildDeviceNode; + IO_STACK_LOCATION Stack; + NTSTATUS Status; + ULONG i; - DPRINT("DeviceNode %x\n", DeviceNode); + DPRINT("DeviceNode %x\n", DeviceNode); - DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); + DPRINT("Sending IRP_MN_QUERY_DEVICE_RELATIONS to device stack\n"); - Stack.Parameters.QueryDeviceRelations.Type = Type/*BusRelations*/; + Stack.Parameters.QueryDeviceRelations.Type = Type/*BusRelations*/; - Status = IopInitiatePnpIrp( - DeviceNode->Pdo, - &IoStatusBlock, - IRP_MN_QUERY_DEVICE_RELATIONS, - &Stack); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitiatePnpIrp() failed\n"); - return Status; - } + Status = IopInitiatePnpIrp( + DeviceNode->Pdo, + &IoStatusBlock, + IRP_MN_QUERY_DEVICE_RELATIONS, + &Stack); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitiatePnpIrp() failed\n"); + return Status; + } - DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; + DeviceRelations = (PDEVICE_RELATIONS)IoStatusBlock.Information; - if ((!DeviceRelations) || (DeviceRelations->Count <= 0)) - { - DPRINT("No PDOs\n"); - if (DeviceRelations) - { - ExFreePool(DeviceRelations); - } - return STATUS_SUCCESS; - } + if ((!DeviceRelations) || (DeviceRelations->Count <= 0)) + { + DPRINT("No PDOs\n"); + if (DeviceRelations) + { + ExFreePool(DeviceRelations); + } + return STATUS_SUCCESS; + } - DPRINT("Got %d PDOs\n", DeviceRelations->Count); + DPRINT("Got %d PDOs\n", DeviceRelations->Count); - /* Create device nodes for all discovered devices */ - for (i = 0; i < DeviceRelations->Count; i++) - { - Status = IopCreateDeviceNode( + /* + * Create device nodes for all discovered devices + */ + + for (i = 0; i < DeviceRelations->Count; i++) + { + Status = IopCreateDeviceNode( + DeviceNode, + DeviceRelations->Objects[i], + &ChildDeviceNode); + DeviceNode->Flags |= DNF_ENUMERATED; + if (!NT_SUCCESS(Status)) + { + DPRINT("No resources\n"); + for (i = 0; i < DeviceRelations->Count; i++) + ObDereferenceObject(DeviceRelations->Objects[i]); + ExFreePool(DeviceRelations); + return STATUS_INSUFFICIENT_RESOURCES; + } + } + ExFreePool(DeviceRelations); + + /* + * Retrieve information about all discovered children from the bus driver + */ + + IopInitDeviceTreeTraverseContext( + &Context, DeviceNode, - DeviceRelations->Objects[i], - &ChildDeviceNode); - DeviceNode->Flags |= DNF_ENUMERATED; - if (!NT_SUCCESS(Status)) - { - DPRINT("No resources\n"); - for (i = 0; i < DeviceRelations->Count; i++) - ObDereferenceObject(DeviceRelations->Objects[i]); - ExFreePool(DeviceRelations); - return STATUS_INSUFFICIENT_RESOURCES; - } - } + IopActionInterrogateDeviceStack, + DeviceNode); - ExFreePool(DeviceRelations); + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); + return Status; + } + /* + * Retrieve configuration from the registry for discovered children + */ - /* Retrieve information about all discovered children from the bus driver */ + IopInitDeviceTreeTraverseContext( + &Context, + DeviceNode, + IopActionConfigureChildServices, + DeviceNode); - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInterrogateDeviceStack, - DeviceNode); + Status = IopTraverseDeviceTree(&Context); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); + return Status; + } - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); - return Status; - } + /* + * Initialize services for discovered children. Only boot drivers will + * be loaded from boot driver! + */ + Status = IopInitializePnpServices(DeviceNode, BootDriver); + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status); + return Status; + } - /* Retrieve configuration from the registry for discovered children */ - - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionConfigureChildServices, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); - return Status; - } - - - /* Initialize services for discovered children */ - - IopInitDeviceTreeTraverseContext( - &Context, - DeviceNode, - IopActionInitChildServices, - DeviceNode); - - Status = IopTraverseDeviceTree(&Context); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopTraverseDeviceTree() failed with status (%x)\n", Status); - return Status; - } - - return STATUS_SUCCESS; -} - -VOID INIT_FUNCTION -IopLoadBootStartDrivers(VOID) -{ - IopInvalidateDeviceRelations(IopRootDeviceNode, BusRelations); + return STATUS_SUCCESS; } VOID INIT_FUNCTION PnpInit(VOID) { - PDEVICE_OBJECT Pdo; - NTSTATUS Status; + PDEVICE_OBJECT Pdo; + NTSTATUS Status; - DPRINT("Called\n"); + DPRINT("PnpInit()\n"); - KeInitializeSpinLock(&IopDeviceTreeLock); + KeInitializeSpinLock(&IopDeviceTreeLock); - Status = IopCreateDriverObject(&IopRootDriverObject, NULL, FALSE, NULL, 0); - if (!NT_SUCCESS(Status)) - { - CPRINT("IoCreateDriverObject() failed\n"); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); - } + /* + * Create root device node + */ - Status = IoCreateDevice( - IopRootDriverObject, - 0, - NULL, - FILE_DEVICE_CONTROLLER, - 0, - FALSE, - &Pdo); - if (!NT_SUCCESS(Status)) - { - CPRINT("IoCreateDevice() failed\n"); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); - } + Status = IopCreateDriverObject(&IopRootDriverObject, NULL, FALSE, NULL, 0); + if (!NT_SUCCESS(Status)) + { + CPRINT("IoCreateDriverObject() failed\n"); + KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + } - Status = IopCreateDeviceNode( - NULL, - Pdo, - &IopRootDeviceNode); - if (!NT_SUCCESS(Status)) - { - CPRINT("Insufficient resources\n"); - KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); - } + Status = IoCreateDevice(IopRootDriverObject, 0, NULL, FILE_DEVICE_CONTROLLER, + 0, FALSE, &Pdo); + if (!NT_SUCCESS(Status)) + { + CPRINT("IoCreateDevice() failed\n"); + KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + } - IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; - - IopRootDeviceNode->DriverObject = IopRootDriverObject; - - PnpRootDriverEntry(IopRootDriverObject, NULL); - - IopRootDriverObject->DriverExtension->AddDevice( - IopRootDriverObject, - IopRootDeviceNode->Pdo); + Status = IopCreateDeviceNode(NULL, Pdo, &IopRootDeviceNode); + if (!NT_SUCCESS(Status)) + { + CPRINT("Insufficient resources\n"); + KEBUGCHECK(PHASE1_INITIALIZATION_FAILED); + } + IopRootDeviceNode->Pdo->Flags |= DO_BUS_ENUMERATED_DEVICE; + IopRootDeviceNode->DriverObject = IopRootDriverObject; + PnpRootDriverEntry(IopRootDriverObject, NULL); + IopRootDriverObject->DriverExtension->AddDevice( + IopRootDriverObject, + IopRootDeviceNode->Pdo); } /* EOF */ diff --git a/reactos/ntoskrnl/ke/main.c b/reactos/ntoskrnl/ke/main.c index cad9813e7c6..ee25784ee82 100644 --- a/reactos/ntoskrnl/ke/main.c +++ b/reactos/ntoskrnl/ke/main.c @@ -16,7 +16,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -/* $Id: main.c,v 1.174 2003/10/12 17:05:45 hbirr Exp $ +/* $Id: main.c,v 1.175 2003/10/15 17:04:39 navaraf Exp $ * * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/main.c @@ -86,31 +86,6 @@ extern PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS]; /* FUNCTIONS ****************************************************************/ -static BOOLEAN INIT_FUNCTION -RtlpCheckFileNameExtension(PCHAR FileName, - PCHAR Extension) -{ - PCHAR Ext; - - Ext = strrchr(FileName, '.'); - if (Ext == NULL) - { - if ((Extension == NULL) || (*Extension == 0)) - return TRUE; - else - return FALSE; - } - - if (*Extension != '.') - Ext++; - - if (_stricmp(Ext, Extension) == 0) - return TRUE; - else - return FALSE; -} - - static VOID INIT_FUNCTION InitSystemSharedUserPage (PCSZ ParameterLine) { @@ -289,25 +264,12 @@ InitSystemSharedUserPage (PCSZ ParameterLine) } } -VOID STATIC INIT_FUNCTION -MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length) -{ - ULONG i; - - for (i = 0; i < PAGE_ROUND_UP(Length)/PAGE_SIZE; i++) - { - MmDeleteVirtualMapping(NULL, StartAddress + i * PAGE_SIZE, TRUE, NULL, NULL); - - } -} - VOID INIT_FUNCTION ExpInitializeExecutive(VOID) { LARGE_INTEGER Timeout; HANDLE ProcessHandle; HANDLE ThreadHandle; - ULONG BootDriverCount; ULONG i; ULONG start; ULONG length; @@ -658,42 +620,10 @@ ExpInitializeExecutive(VOID) IoInit2(); - /* Pass 3: process boot loaded drivers */ - BootDriverCount = 0; - for (i=1; i < KeLoaderBlock.ModsCount; i++) - { - start = KeLoaderModules[i].ModStart; - length = KeLoaderModules[i].ModEnd - start; - name = (PCHAR)KeLoaderModules[i].String; - if (RtlpCheckFileNameExtension(name, ".sys") || - RtlpCheckFileNameExtension(name, ".sym")) - { - CPRINT("Initializing driver '%s' at %08lx, length 0x%08lx\n", - name, start, length); - LdrInitializeBootStartDriver((PVOID)start, name, length); - } - if (RtlpCheckFileNameExtension(name, ".sys")) - BootDriverCount++; - } - - /* Pass 4: free memory for all boot files, except ntoskrnl.exe and hal.dll */ - for (i = 2; i < KeLoaderBlock.ModsCount; i++) - { -#ifdef KDBG - /* Do not free the memory from symbol files, if the kernel debugger is active */ - if (!RtlpCheckFileNameExtension(name, ".sym")) -#endif - { - MiFreeBootDriverMemory((PVOID)KeLoaderModules[i].ModStart, - KeLoaderModules[i].ModEnd - KeLoaderModules[i].ModStart); - } - } - - if (BootDriverCount == 0) - { - DbgPrint("No boot drivers available.\n"); - KEBUGCHECK(0); - } + /* + * Load boot start drivers + */ + IopInitializeBootDrivers(); /* Display the boot screen image if not disabled */ if (!NoBootScreen) @@ -723,14 +653,14 @@ ExpInitializeExecutive(VOID) PiInitDefaultLocale(); /* - * Load boot start drivers + * Load services for devices found by PnP manager */ - IopLoadBootStartDrivers(); + IopInitializePnpServices(IopRootDeviceNode, FALSE); /* - * Load Auto configured drivers + * Load system start drivers */ - LdrLoadAutoConfigDrivers(); + IopInitializeSystemDrivers(); IoDestroyDriverList(); @@ -863,7 +793,6 @@ KiSystemStartup(BOOLEAN BootProcessor) for(;;); } - VOID INIT_FUNCTION _main (ULONG MultiBootMagic, PLOADER_PARAMETER_BLOCK _LoaderBlock) /* diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index c20a857a5a0..d3331d31173 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.136 2003/10/12 17:05:45 hbirr Exp $ +/* $Id: loader.c,v 1.137 2003/10/15 17:04:39 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -940,7 +940,12 @@ LdrPEProcessModule(PVOID ModuleLoadBase, CPRINT("Failed to allocate a virtual section for driver\n"); return STATUS_UNSUCCESSFUL; } +#if 0 DbgPrint("DriverBase for %wZ: %x\n", FileName, DriverBase); +#else + DbgPrint("DriverBase for %wZ", FileName); + DbgPrint(": %x\n", DriverBase); +#endif CHECKPOINT; /* Copy headers over */ memcpy(DriverBase, ModuleLoadBase, PEOptionalHeader->SizeOfHeaders);