diff --git a/reactos/ntoskrnl/include/internal/io.h b/reactos/ntoskrnl/include/internal/io.h index 082f9202512..45afb24d356 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.40 2004/03/21 18:58:52 navaraf Exp $ +/* $Id: io.h,v 1.41 2004/03/27 19:41:31 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -32,6 +32,7 @@ #include #include +#include #ifndef __USE_W32API @@ -62,7 +63,6 @@ typedef struct _DEVICE_NODE struct _DEVICE_NODE *PrevSibling; struct _DEVICE_NODE *NextSibling; struct _DEVICE_NODE *Child; - PDRIVER_OBJECT DriverObject; PDEVICE_OBJECT Pdo; UNICODE_STRING InstancePath; UNICODE_STRING ServiceName; @@ -266,19 +266,6 @@ IopCreateDeviceNode(PDEVICE_NODE ParentNode, NTSTATUS IopFreeDeviceNode(PDEVICE_NODE DeviceNode); -NTSTATUS -IopCreateDriverObject(PDRIVER_OBJECT *DriverObject, - PUNICODE_STRING ServiceName, - BOOLEAN FileSystemDriver, - PVOID DriverImageStart, - ULONG DriverImageSize); -NTSTATUS -IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry, - PDEVICE_NODE DeviceNode, - BOOLEAN FileSystemDriver, - PVOID DriverImageStart, - ULONG DriverImageSize, - BOOLEAN BootDriver); VOID IoInitCancelHandling(VOID); VOID @@ -388,37 +375,48 @@ PnpRootCreateDevice( /* device.c */ -NTSTATUS -IopAttachFilterDrivers( - PDEVICE_NODE DeviceNode, - BOOLEAN Lower); - -NTSTATUS -IopInitializeService( - PDEVICE_NODE DeviceNode, - PUNICODE_STRING ServiceName, - PUNICODE_STRING ImagePath); +NTSTATUS FASTCALL +IopInitializeDevice( + PDEVICE_NODE DeviceNode, + PDRIVER_OBJECT DriverObject); /* driver.c */ -VOID -IopInitializeBootDrivers( - VOID); +VOID FASTCALL +IopInitializeBootDrivers(VOID); -VOID -IopInitializeSystemDrivers( - VOID); +VOID FASTCALL +IopInitializeSystemDrivers(VOID); -NTSTATUS -IopInitializeDeviceNodeService( - PDEVICE_NODE DeviceNode, - PUNICODE_STRING ServiceName, - BOOLEAN BootDriverOnly); +NTSTATUS FASTCALL +IopCreateDriverObject( + PDRIVER_OBJECT *DriverObject, + PUNICODE_STRING ServiceName, + BOOLEAN FileSystemDriver, + PVOID DriverImageStart, + ULONG DriverImageSize); -VOID +NTSTATUS FASTCALL +IopLoadServiceModule( + IN PUNICODE_STRING ServiceName, + OUT PMODULE_OBJECT *ModuleObject); + +NTSTATUS FASTCALL +IopInitializeDriverModule( + IN PDEVICE_NODE DeviceNode, + IN PMODULE_OBJECT ModuleObject, + IN BOOLEAN FileSystemDriver, + OUT PDRIVER_OBJECT *DriverObject); + +NTSTATUS FASTCALL +IopAttachFilterDrivers( + PDEVICE_NODE DeviceNode, + BOOLEAN Lower); + +VOID FASTCALL IopMarkLastReinitializeDriver(VOID); -VOID +VOID FASTCALL IopReinitializeDrivers(VOID); /* pnpmgr.c */ @@ -431,7 +429,6 @@ IopInitializePnpServices( NTSTATUS IopInvalidateDeviceRelations( IN PDEVICE_NODE DeviceNode, - IN DEVICE_RELATION_TYPE Type, - IN BOOLEAN BootDriver); + IN DEVICE_RELATION_TYPE Type); #endif diff --git a/reactos/ntoskrnl/include/internal/ldr.h b/reactos/ntoskrnl/include/internal/ldr.h index 95feea6a3d2..ef93e8f0c19 100644 --- a/reactos/ntoskrnl/include/internal/ldr.h +++ b/reactos/ntoskrnl/include/internal/ldr.h @@ -34,11 +34,6 @@ LdrInitModuleManagement ( VOID ); -NTSTATUS -LdrInitializeBootStartDriver(IN PVOID ModuleLoadBase, - IN PCHAR FileName, - IN ULONG ModuleLength); - NTSTATUS LdrpMapSystemDll ( HANDLE ProcessHandle, diff --git a/reactos/ntoskrnl/io/device.c b/reactos/ntoskrnl/io/device.c index 5b9cfeb120f..ecf64fa8553 100644 --- a/reactos/ntoskrnl/io/device.c +++ b/reactos/ntoskrnl/io/device.c @@ -1,4 +1,4 @@ -/* $Id: device.c,v 1.68 2004/03/21 18:58:53 navaraf Exp $ +/* $Id: device.c,v 1.69 2004/03/27 19:41:32 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -9,7 +9,7 @@ * 15/05/98: Created */ -/* INCLUDES ****************************************************************/ +/* INCLUDES *******************************************************************/ #define NTOS_MODE_KERNEL #include @@ -22,99 +22,219 @@ #include #define NDEBUG -//#define DBG #include -/* GLOBALS *******************************************************************/ +#define ASSERT assert + +/* GLOBALS ********************************************************************/ -#define TAG_DRIVER TAG('D', 'R', 'V', 'R') -#define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E') #define TAG_DEVICE_EXTENSION TAG('D', 'E', 'X', 'T') -#define DRIVER_REGISTRY_KEY_BASENAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" +/* PRIVATE FUNCTIONS **********************************************************/ -/* FUNCTIONS ***************************************************************/ - -/* - * @implemented - */ -NTSTATUS STDCALL -IoAttachDeviceByPointer(IN PDEVICE_OBJECT SourceDevice, - IN PDEVICE_OBJECT TargetDevice) +NTSTATUS FASTCALL +IopInitializeDevice( + PDEVICE_NODE DeviceNode, + PDRIVER_OBJECT DriverObject) { - PDEVICE_OBJECT AttachedDevice; + IO_STATUS_BLOCK IoStatusBlock; + IO_STACK_LOCATION Stack; + PDEVICE_OBJECT Fdo; + NTSTATUS Status; - DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n", - SourceDevice, - TargetDevice); + if (DriverObject->DriverExtension->AddDevice) + { + /* This is a Plug and Play driver */ + DPRINT("Plug and Play driver found\n"); - AttachedDevice = IoAttachDeviceToDeviceStack (SourceDevice, - TargetDevice); - if (AttachedDevice == NULL) - return STATUS_NO_SUCH_DEVICE; + ASSERT(DeviceNode->Pdo); - return STATUS_SUCCESS; + DPRINT("Calling driver AddDevice entrypoint at %08lx\n", + DriverObject->DriverExtension->AddDevice); + + Status = DriverObject->DriverExtension->AddDevice( + DriverObject, DeviceNode->Pdo); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo); + + if (Fdo == DeviceNode->Pdo) + { + /* FIXME: What do we do? Unload the driver or just disable the device? */ + DbgPrint("An FDO was not attached\n"); + KEBUGCHECK(0); + } + + IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED); + + DPRINT("Sending IRP_MN_START_DEVICE to driver\n"); + + /* FIXME: Put some resources in the IRP for the device */ + Stack.Parameters.StartDevice.AllocatedResources = NULL; + Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL; + + Status = IopInitiatePnpIrp( + Fdo, + &IoStatusBlock, + IRP_MN_START_DEVICE, + &Stack); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IopInitiatePnpIrp() failed\n"); + ObDereferenceObject(Fdo); + return Status; + } + + if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER) + { + DPRINT("Bus extender found\n"); + + Status = IopInvalidateDeviceRelations(DeviceNode, BusRelations); + + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Fdo); + return Status; + } + } + else if (Fdo->DeviceType == FILE_DEVICE_ACPI) + { +#ifdef ACPI + static BOOLEAN SystemPowerDeviceNodeCreated = FALSE; + + /* There can be only one system power device */ + if (!SystemPowerDeviceNodeCreated) + { + PopSystemPowerDeviceNode = DeviceNode; + SystemPowerDeviceNodeCreated = TRUE; + } +#endif /* ACPI */ + } + ObDereferenceObject(Fdo); + } + + return STATUS_SUCCESS; } +NTSTATUS STDCALL +IopCreateDevice( + PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) +{ + DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n", + ObjectBody, Parent, RemainingPath); + + if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL) + return STATUS_UNSUCCESSFUL; + + return STATUS_SUCCESS; +} + +/* PUBLIC FUNCTIONS ***********************************************************/ /* - * @implemented + * IoAttachDeviceByPointer + * + * Status + * @implemented */ + +NTSTATUS STDCALL +IoAttachDeviceByPointer( + IN PDEVICE_OBJECT SourceDevice, + IN PDEVICE_OBJECT TargetDevice) +{ + PDEVICE_OBJECT AttachedDevice; + + DPRINT("IoAttachDeviceByPointer(SourceDevice %x, TargetDevice %x)\n", + SourceDevice, TargetDevice); + + AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice, TargetDevice); + if (AttachedDevice == NULL) + return STATUS_NO_SUCH_DEVICE; + + return STATUS_SUCCESS; +} + +/* + * IoDeleteDevice + * + * Status + * @implemented + */ + VOID STDCALL IoDeleteDevice(PDEVICE_OBJECT DeviceObject) { - PDEVICE_OBJECT Previous; + PDEVICE_OBJECT Previous; - if (DeviceObject->Flags & DO_SHUTDOWN_REGISTERED) - IoUnregisterShutdownNotification(DeviceObject); + if (DeviceObject->Flags & DO_SHUTDOWN_REGISTERED) + IoUnregisterShutdownNotification(DeviceObject); - /* remove the timer if it exists */ - if (DeviceObject->Timer) - { - IoStopTimer(DeviceObject); - ExFreePool(DeviceObject->Timer); - } + /* Remove the timer if it exists */ + if (DeviceObject->Timer) + { + IoStopTimer(DeviceObject); + ExFreePool(DeviceObject->Timer); + } - /* free device extension */ - if (DeviceObject->DeviceObjectExtension) - ExFreePool (DeviceObject->DeviceObjectExtension); + /* Free device extension */ + if (DeviceObject->DeviceObjectExtension) + ExFreePool(DeviceObject->DeviceObjectExtension); - /* remove device from driver device list */ - Previous = DeviceObject->DriverObject->DeviceObject; - if (Previous == DeviceObject) - { - DeviceObject->DriverObject->DeviceObject = DeviceObject->NextDevice; - } - else - { - while (Previous->NextDevice != DeviceObject) - Previous = Previous->NextDevice; - Previous->NextDevice = DeviceObject->NextDevice; - } + /* Remove device from driver device list */ + Previous = DeviceObject->DriverObject->DeviceObject; + if (Previous == DeviceObject) + { + DeviceObject->DriverObject->DeviceObject = DeviceObject->NextDevice; + } + else + { + while (Previous->NextDevice != DeviceObject) + Previous = Previous->NextDevice; + Previous->NextDevice = DeviceObject->NextDevice; + } - ObDereferenceObject (DeviceObject); + ObDereferenceObject(DeviceObject); } - /* - * @implemented + * IoGetRelatedDeviceObject + * + * Remarks + * See "Windows NT File System Internals", page 633 - 634. + * + * Status + * @implemented */ -PDEVICE_OBJECT -STDCALL -IoGetRelatedDeviceObject ( - IN PFILE_OBJECT FileObject - ) -{ - /*Win NT File System Internals, page 633-634*/ - /*get logical volume mounted on a physical/virtual/logical device*/ +PDEVICE_OBJECT STDCALL +IoGetRelatedDeviceObject( + IN PFILE_OBJECT FileObject) +{ + /* + * Get logical volume mounted on a physical/virtual/logical device + */ + if (FileObject->Vpb && FileObject->Vpb->DeviceObject) { return IoGetAttachedDevice(FileObject->Vpb->DeviceObject); } - /*check if fileobject has an associated device object mounted by some other file system*/ - if (FileObject->DeviceObject->Vpb && FileObject->DeviceObject->Vpb->DeviceObject) + /* + * Check if file object has an associated device object mounted by some + * other file system. + */ + + if (FileObject->DeviceObject->Vpb && + FileObject->DeviceObject->Vpb->DeviceObject) { return IoGetAttachedDevice(FileObject->DeviceObject->Vpb->DeviceObject); } @@ -122,636 +242,228 @@ IoGetRelatedDeviceObject ( return IoGetAttachedDevice(FileObject->DeviceObject); } - /* - * @implemented + * IoGetDeviceObjectPointer + * + * Status + * @implemented */ -NTSTATUS -STDCALL -IoGetDeviceObjectPointer ( - IN PUNICODE_STRING ObjectName, - IN ACCESS_MASK DesiredAccess, - OUT PFILE_OBJECT * FileObject, - OUT PDEVICE_OBJECT * DeviceObject) + +NTSTATUS STDCALL +IoGetDeviceObjectPointer( + IN PUNICODE_STRING ObjectName, + IN ACCESS_MASK DesiredAccess, + OUT PFILE_OBJECT *FileObject, + OUT PDEVICE_OBJECT *DeviceObject) { - OBJECT_ATTRIBUTES ObjectAttributes; - IO_STATUS_BLOCK StatusBlock; - PFILE_OBJECT LocalFileObject; - HANDLE FileHandle; - NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + IO_STATUS_BLOCK StatusBlock; + PFILE_OBJECT LocalFileObject; + HANDLE FileHandle; + NTSTATUS Status; - DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n", - ObjectName, - DesiredAccess, - FileObject, - DeviceObject); + DPRINT("IoGetDeviceObjectPointer(ObjectName %wZ, DesiredAccess %x, FileObject %p DeviceObject %p)\n", + ObjectName, DesiredAccess, FileObject, DeviceObject); - InitializeObjectAttributes (&ObjectAttributes, - ObjectName, - 0, - NULL, - NULL); + InitializeObjectAttributes( + &ObjectAttributes, + ObjectName, + 0, + NULL, + NULL); - Status = NtOpenFile (&FileHandle, - DesiredAccess, - &ObjectAttributes, - &StatusBlock, - 0, - FILE_NON_DIRECTORY_FILE); - if (!NT_SUCCESS(Status)) - return Status; + Status = NtOpenFile( + &FileHandle, + DesiredAccess, + &ObjectAttributes, + &StatusBlock, + 0, + FILE_NON_DIRECTORY_FILE); - Status = ObReferenceObjectByHandle (FileHandle, - 0, - IoFileObjectType, - KernelMode, - (PVOID*)&LocalFileObject, - NULL); - if (NT_SUCCESS(Status)) - { - *DeviceObject = IoGetRelatedDeviceObject (LocalFileObject); - *FileObject = LocalFileObject; - } - NtClose (FileHandle); + if (!NT_SUCCESS(Status)) + return Status; - return Status; + Status = ObReferenceObjectByHandle( + FileHandle, + 0, + IoFileObjectType, + KernelMode, + (PVOID*)&LocalFileObject, + NULL); + + if (NT_SUCCESS(Status)) + { + *DeviceObject = IoGetRelatedDeviceObject(LocalFileObject); + *FileObject = LocalFileObject; + } + + NtClose(FileHandle); + + return Status; } - /* - * @unimplemented + * IoDetachDevice + * + * Status + * @unimplemented */ -VOID -STDCALL + +VOID STDCALL IoDetachDevice(PDEVICE_OBJECT TargetDevice) { -// UNIMPLEMENTED; DPRINT("IoDetachDevice(TargetDevice %x) - UNIMPLEMENTED\n", TargetDevice); } - /* - * @implemented + * IoGetAttachedDevice + * + * Status + * @implemented */ -PDEVICE_OBJECT -STDCALL + +PDEVICE_OBJECT STDCALL IoGetAttachedDevice(PDEVICE_OBJECT DeviceObject) { PDEVICE_OBJECT Current = DeviceObject; -// DPRINT("IoGetAttachedDevice(DeviceObject %x)\n",DeviceObject); - - while (Current->AttachedDevice!=NULL) - { - Current = Current->AttachedDevice; -// DPRINT("Current %x\n",Current); - } + while (Current->AttachedDevice != NULL) + Current = Current->AttachedDevice; -// DPRINT("IoGetAttachedDevice() = %x\n",DeviceObject); - return(Current); + return Current; } /* - * @implemented + * IoGetAttachedDeviceReference + * + * Status + * @implemented */ -PDEVICE_OBJECT -STDCALL + +PDEVICE_OBJECT STDCALL IoGetAttachedDeviceReference(PDEVICE_OBJECT DeviceObject) { - PDEVICE_OBJECT Current = DeviceObject; - - while (Current->AttachedDevice!=NULL) - { - Current = Current->AttachedDevice; - } - + PDEVICE_OBJECT Current = IoGetAttachedDevice(DeviceObject); ObReferenceObject(Current); - return(Current); + return Current; } /* - * @implemented + * IoAttachDeviceToDeviceStack + * + * Status + * @implemented */ + PDEVICE_OBJECT STDCALL -IoAttachDeviceToDeviceStack(PDEVICE_OBJECT SourceDevice, - PDEVICE_OBJECT TargetDevice) +IoAttachDeviceToDeviceStack( + PDEVICE_OBJECT SourceDevice, + PDEVICE_OBJECT TargetDevice) { PDEVICE_OBJECT AttachedDevice; DPRINT("IoAttachDeviceToDeviceStack(SourceDevice %x, TargetDevice %x)\n", - SourceDevice,TargetDevice); + SourceDevice, TargetDevice); AttachedDevice = IoGetAttachedDevice(TargetDevice); AttachedDevice->AttachedDevice = SourceDevice; SourceDevice->AttachedDevice = NULL; SourceDevice->StackSize = AttachedDevice->StackSize + 1; SourceDevice->Vpb = AttachedDevice->Vpb; - return(AttachedDevice); + return AttachedDevice; } - -NTSTATUS STDCALL -IopDefaultDispatchFunction(PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; - Irp->IoStatus.Information = 0; - - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return(STATUS_NOT_IMPLEMENTED); -} - - -NTSTATUS -IopCreateDriverObject(PDRIVER_OBJECT *DriverObject, - PUNICODE_STRING ServiceName, - BOOLEAN FileSystem, - PVOID DriverImageStart, - ULONG DriverImageSize) -{ - PDRIVER_OBJECT Object; - ULONG i; - WCHAR NameBuffer[MAX_PATH]; - UNICODE_STRING DriverName; - OBJECT_ATTRIBUTES ObjectAttributes; - NTSTATUS Status; - - DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n", DriverObject, ServiceName, FileSystem, - DriverImageStart, DriverImageSize); - - *DriverObject = NULL; - - /* Create ModuleName string */ - if ((ServiceName != NULL) && (ServiceName->Buffer != NULL)) - { - if (FileSystem == TRUE) - wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME); - else - wcscpy(NameBuffer, DRIVER_ROOT_NAME); - wcscat(NameBuffer, ServiceName->Buffer); - - RtlInitUnicodeString(&DriverName, - NameBuffer); - DPRINT("Driver name: '%wZ'\n", &DriverName); - } - - /* Initialize ObjectAttributes for driver object */ - InitializeObjectAttributes(&ObjectAttributes, - ((ServiceName != NULL) && (ServiceName->Buffer != NULL))? &DriverName : NULL, - OBJ_PERMANENT, - NULL, - NULL); - - /* Create driver object */ - Status = ObCreateObject(KernelMode, - IoDriverObjectType, - &ObjectAttributes, - KernelMode, - NULL, - sizeof(DRIVER_OBJECT), - 0, - 0, - (PVOID*)&Object); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* Create driver extension */ - Object->DriverExtension = (PDRIVER_EXTENSION) - ExAllocatePoolWithTag(NonPagedPool, - sizeof(DRIVER_EXTENSION), - TAG_DRIVER_EXTENSION); - if (Object->DriverExtension == NULL) - { - ExFreePool(Object); - return(STATUS_INSUFFICIENT_RESOURCES); - } - - RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION)); - - Object->Type = InternalDriverType; - - Object->DriverStart = DriverImageStart; - Object->DriverSize = DriverImageSize; - - for (i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++) - { - Object->MajorFunction[i] = (PDRIVER_DISPATCH) IopDefaultDispatchFunction; - } - - *DriverObject = Object; - - return STATUS_SUCCESS; -} - - -NTSTATUS STDCALL -IopAttachFilterDriversCallback( - PWSTR ValueName, - ULONG ValueType, - PVOID ValueData, - ULONG ValueLength, - PVOID Context, - PVOID EntryContext) -{ - PDEVICE_NODE DeviceNode = Context; - UNICODE_STRING ServiceName; - PWCHAR Filters; - - Filters = ValueData; - while (((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength && - *Filters != 0) - { - DPRINT1("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath); - ServiceName.Buffer = Filters; - ServiceName.MaximumLength = - ServiceName.Length = wcslen(Filters) * sizeof(WCHAR); - IopInitializeDeviceNodeService( - DeviceNode, - &ServiceName, - FALSE); - Filters += (ServiceName.Length / sizeof(WCHAR)) + 1; - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -IopAttachFilterDrivers( - PDEVICE_NODE DeviceNode, - BOOLEAN Lower) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - PWCHAR KeyBuffer; - UNICODE_STRING Class; - WCHAR ClassBuffer[40]; - NTSTATUS Status; - - /* - * First load the device filters - */ - - QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; - if (Lower) - QueryTable[0].Name = L"LowerFilters"; - else - QueryTable[0].Name = L"UpperFilters"; - QueryTable[0].EntryContext = NULL; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; - QueryTable[1].QueryRoutine = NULL; - QueryTable[1].Name = NULL; - - KeyBuffer = ExAllocatePool( - PagedPool, - (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length); - wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); - wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); - - RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - KeyBuffer, - QueryTable, - DeviceNode, - NULL); - - /* - * Now get the class GUID - */ - - Class.Length = 0; - Class.MaximumLength = 40 * sizeof(WCHAR); - Class.Buffer = ClassBuffer; - QueryTable[0].QueryRoutine = NULL; - QueryTable[0].Name = L"ClassGUID"; - QueryTable[0].EntryContext = &Class; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; - - Status = RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - KeyBuffer, - QueryTable, - DeviceNode, - NULL); - - ExFreePool(KeyBuffer); - - /* - * Load the class filter driver - */ - - if (NT_SUCCESS(Status)) - { - QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; - if (Lower) - QueryTable[0].Name = L"LowerFilters"; - else - QueryTable[0].Name = L"UpperFilters"; - QueryTable[0].EntryContext = NULL; - QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; - - KeyBuffer = ExAllocatePool(PagedPool, (58 * sizeof(WCHAR)) + Class.Length); - wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"); - wcscat(KeyBuffer, ClassBuffer); - - RtlQueryRegistryValues( - RTL_REGISTRY_ABSOLUTE, - KeyBuffer, - QueryTable, - DeviceNode, - NULL); - - ExFreePool(KeyBuffer); - } - - return STATUS_SUCCESS; -} - - -NTSTATUS -IopInitializeDevice(PDEVICE_NODE DeviceNode, - BOOLEAN BootDriver) -{ - IO_STATUS_BLOCK IoStatusBlock; - PDRIVER_OBJECT DriverObject; - IO_STACK_LOCATION Stack; - PDEVICE_OBJECT Fdo; - NTSTATUS Status; - - DriverObject = DeviceNode->DriverObject; - - if (DriverObject->DriverExtension->AddDevice) - { - /* This is a Plug and Play driver */ - DPRINT("Plug and Play driver found\n"); - - assert(DeviceNode->Pdo); - - DPRINT("Calling driver AddDevice entrypoint at %08lx\n", - DriverObject->DriverExtension->AddDevice); - Status = DriverObject->DriverExtension->AddDevice( - DriverObject, DeviceNode->Pdo); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - IopDeviceNodeSetFlag(DeviceNode, DNF_ADDED); - - DPRINT("Sending IRP_MN_START_DEVICE to driver\n"); - - Fdo = IoGetAttachedDeviceReference(DeviceNode->Pdo); - - if (Fdo == DeviceNode->Pdo) - { - /* FIXME: What do we do? Unload the driver or just disable the device? */ - DbgPrint("An FDO was not attached\n"); - KEBUGCHECK(0); - } - - /* FIXME: Put some resources in the IRP for the device */ - Stack.Parameters.StartDevice.AllocatedResources = NULL; - Stack.Parameters.StartDevice.AllocatedResourcesTranslated = NULL; - - Status = IopInitiatePnpIrp( - Fdo, - &IoStatusBlock, - IRP_MN_START_DEVICE, - &Stack); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopInitiatePnpIrp() failed\n"); - ObDereferenceObject(Fdo); - return(Status); - } - - if (Fdo->DeviceType == FILE_DEVICE_BUS_EXTENDER) - { - DPRINT("Bus extender found\n"); - - Status = IopInvalidateDeviceRelations( - DeviceNode, BusRelations, BootDriver); - if (!NT_SUCCESS(Status)) - { - ObDereferenceObject(Fdo); - return(Status); - } - } - else if (Fdo->DeviceType == FILE_DEVICE_ACPI) - { -#ifdef ACPI - static BOOLEAN SystemPowerDeviceNodeCreated = FALSE; - - /* There can be only one system power device */ - if (!SystemPowerDeviceNodeCreated) - { - PopSystemPowerDeviceNode = DeviceNode; - SystemPowerDeviceNodeCreated = TRUE; - } -#endif /* ACPI */ - } - ObDereferenceObject(Fdo); - } - - return STATUS_SUCCESS; -} - -NTSTATUS -IopInitializeService( - PDEVICE_NODE DeviceNode, - PUNICODE_STRING ServiceName, - PUNICODE_STRING ImagePath) -{ - PMODULE_OBJECT ModuleObject; - NTSTATUS Status; - - ModuleObject = LdrGetModuleObject(ServiceName); - if (ModuleObject == NULL) - { - /* The module is currently not loaded, so load it now */ - - Status = LdrLoadModule(ImagePath, &ModuleObject); - if (!NT_SUCCESS(Status)) - { - /* FIXME: Log the error */ - CPRINT("Driver load failed\n"); - return(Status); - } - - Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, FALSE, - ModuleObject->Base, ModuleObject->Length, - FALSE); - if (!NT_SUCCESS(Status)) - { - LdrUnloadModule(ModuleObject); - - /* FIXME: Log the error */ - CPRINT("A driver failed to initialize\n"); - return(Status); - } - } else - { - /* FIXME: This doesn't work for two devices with the same driver */ - Status = IopInitializeDevice(DeviceNode, FALSE); - } - - return(Status); -} - -NTSTATUS -IopInitializeDriver(PDRIVER_INITIALIZE DriverEntry, - PDEVICE_NODE DeviceNode, - BOOLEAN FileSystemDriver, - PVOID DriverImageStart, - ULONG DriverImageSize, - BOOLEAN BootDriver) -/* - * FUNCTION: Called to initalize a loaded driver - * ARGUMENTS: - * DriverEntry = Pointer to driver entry routine - * DeviceNode = Pointer to device node - */ -{ - WCHAR RegistryKeyBuffer[MAX_PATH]; - PDRIVER_OBJECT DriverObject; - UNICODE_STRING RegistryKey; - NTSTATUS Status; - - DPRINT("IopInitializeDriver(DriverEntry %08lx, DeviceNode %08lx)\n", - DriverEntry, DeviceNode); - - Status = IopCreateDriverObject(&DriverObject, - &DeviceNode->ServiceName, - FileSystemDriver, - DriverImageStart, - DriverImageSize); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - DeviceNode->DriverObject = DriverObject; - - if (DeviceNode->ServiceName.Buffer) - { - wcscpy(RegistryKeyBuffer, DRIVER_REGISTRY_KEY_BASENAME); - wcscat(RegistryKeyBuffer, DeviceNode->ServiceName.Buffer); - RtlInitUnicodeString(&RegistryKey, RegistryKeyBuffer); - } - else - { - RtlInitUnicodeString(&RegistryKey, NULL); - } - - DPRINT("RegistryKey: %wZ\n", &RegistryKey); - DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry); - - IopMarkLastReinitializeDriver(); - - Status = DriverEntry(DriverObject, &RegistryKey); - if (!NT_SUCCESS(Status)) - { - DeviceNode->DriverObject = NULL; - ExFreePool(DriverObject->DriverExtension); - ObMakeTemporaryObject(DriverObject); - ObDereferenceObject(DriverObject); - return(Status); - } - - IopReinitializeDrivers(); - - Status = IopInitializeDevice(DeviceNode, BootDriver); - - return(Status); -} - - /* - * @implemented + * IoAttachDevice + * + * Layers a device over the highest device in a device stack. + * + * Parameters + * SourceDevice + * Device to be attached. + * + * TargetDevice + * Name of the target device. + * + * AttachedDevice + * Caller storage for the device attached to. + * + * Status + * @implemented */ + NTSTATUS STDCALL -IoAttachDevice(PDEVICE_OBJECT SourceDevice, - PUNICODE_STRING TargetDeviceName, - PDEVICE_OBJECT* AttachedDevice) -/* - * FUNCTION: Layers a device over the highest device in a device stack - * ARGUMENTS: - * SourceDevice = Device to attached - * TargetDevice = Name of the target device - * AttachedDevice (OUT) = Caller storage for the device attached to - */ +IoAttachDevice( + PDEVICE_OBJECT SourceDevice, + PUNICODE_STRING TargetDeviceName, + PDEVICE_OBJECT *AttachedDevice) { - NTSTATUS Status; - PFILE_OBJECT FileObject; + NTSTATUS Status; + PFILE_OBJECT FileObject; PDEVICE_OBJECT TargetDevice; - Status = IoGetDeviceObjectPointer(TargetDeviceName, - FILE_READ_ATTRIBUTES, - &FileObject, - &TargetDevice); + Status = IoGetDeviceObjectPointer( + TargetDeviceName, + FILE_READ_ATTRIBUTES, + &FileObject, + &TargetDevice); if (!NT_SUCCESS(Status)) { return Status; } - *AttachedDevice = IoAttachDeviceToDeviceStack(SourceDevice, - TargetDevice); + *AttachedDevice = IoAttachDeviceToDeviceStack( + SourceDevice, + TargetDevice); ObDereferenceObject(FileObject); + return STATUS_SUCCESS; } +/* + * IoCreateDevice + * + * Allocates memory for and intializes a device object for use for + * a driver. + * + * Parameters + * DriverObject + * Driver object passed by IO Manager when the driver was loaded. + * + * DeviceExtensionSize + * Number of bytes for the device extension. + * + * DeviceName + * Unicode name of device. + * + * DeviceType + * Device type of the new device. + * + * DeviceCharacteristics + * Bit mask of device characteristics. + * + * Exclusive + * TRUE if only one thread can access the device at a time. + * + * DeviceObject + * On successful return this parameter is filled by pointer to + * allocated device object. + * + * Status + * @implemented + */ NTSTATUS STDCALL -IopCreateDevice(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - POBJECT_ATTRIBUTES ObjectAttributes) -{ - - DPRINT("IopCreateDevice(ObjectBody %x, Parent %x, RemainingPath %S)\n", - ObjectBody, Parent, RemainingPath); - - if (RemainingPath != NULL && wcschr(RemainingPath+1, '\\') != NULL) - { - return(STATUS_UNSUCCESSFUL); - } - - return(STATUS_SUCCESS); -} - - -/* - * @implemented - */ -NTSTATUS STDCALL -IoCreateDevice(PDRIVER_OBJECT DriverObject, - ULONG DeviceExtensionSize, - PUNICODE_STRING DeviceName, - DEVICE_TYPE DeviceType, - ULONG DeviceCharacteristics, - BOOLEAN Exclusive, - PDEVICE_OBJECT* DeviceObject) -/* - * FUNCTION: Allocates memory for and intializes a device object for use for - * a driver - * ARGUMENTS: - * DriverObject : Driver object passed by iomgr when the driver was - * loaded - * DeviceExtensionSize : Number of bytes for the device extension - * DeviceName : Unicode name of device - * DeviceType : Device type - * DeviceCharacteristics : Bit mask of device characteristics - * Exclusive : True if only one thread can access the device at a - * time - * RETURNS: - * Success or failure - * DeviceObject : Contains a pointer to allocated device object - * if the call succeeded - * NOTES: See the DDK documentation for more information - */ +IoCreateDevice( + PDRIVER_OBJECT DriverObject, + ULONG DeviceExtensionSize, + PUNICODE_STRING DeviceName, + DEVICE_TYPE DeviceType, + ULONG DeviceCharacteristics, + BOOLEAN Exclusive, + PDEVICE_OBJECT *DeviceObject) { PDEVICE_OBJECT CreatedDeviceObject; PDEVOBJ_EXTENSION DeviceObjectExtension; @@ -761,146 +473,160 @@ IoCreateDevice(PDRIVER_OBJECT DriverObject, assert_irql(PASSIVE_LEVEL); if (DeviceName != NULL) - { - DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n",DriverObject, - DeviceName->Buffer); - } + { + DPRINT("IoCreateDevice(DriverObject %x, DeviceName %S)\n", + DriverObject, DeviceName->Buffer); + } else - { - DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject); - } + { + DPRINT("IoCreateDevice(DriverObject %x)\n",DriverObject); + } if (DeviceName != NULL) - { - InitializeObjectAttributes(&ObjectAttributes,DeviceName,0,NULL,NULL); - Status = ObCreateObject(KernelMode, - IoDeviceObjectType, - &ObjectAttributes, - KernelMode, - NULL, - sizeof(DEVICE_OBJECT), - 0, - 0, - (PVOID*)&CreatedDeviceObject); - } + { + InitializeObjectAttributes(&ObjectAttributes, DeviceName, 0, NULL, NULL); + Status = ObCreateObject( + KernelMode, + IoDeviceObjectType, + &ObjectAttributes, + KernelMode, + NULL, + sizeof(DEVICE_OBJECT), + 0, + 0, + (PVOID*)&CreatedDeviceObject); + } else - { - Status = ObCreateObject(KernelMode, - IoDeviceObjectType, - NULL, - KernelMode, - NULL, - sizeof(DEVICE_OBJECT), - 0, - 0, - (PVOID*)&CreatedDeviceObject); - } + { + Status = ObCreateObject( + KernelMode, + IoDeviceObjectType, + NULL, + KernelMode, + NULL, + sizeof(DEVICE_OBJECT), + 0, + 0, + (PVOID*)&CreatedDeviceObject); + } *DeviceObject = NULL; if (!NT_SUCCESS(Status)) - { - DPRINT("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status); - return(Status); - } + { + DPRINT("IoCreateDevice() ObCreateObject failed, status: 0x%08X\n", Status); + return Status; + } if (DriverObject->DeviceObject == NULL) - { - DriverObject->DeviceObject = CreatedDeviceObject; - CreatedDeviceObject->NextDevice = NULL; - } + { + DriverObject->DeviceObject = CreatedDeviceObject; + CreatedDeviceObject->NextDevice = NULL; + } else - { - CreatedDeviceObject->NextDevice = DriverObject->DeviceObject; - DriverObject->DeviceObject = CreatedDeviceObject; - } + { + CreatedDeviceObject->NextDevice = DriverObject->DeviceObject; + DriverObject->DeviceObject = CreatedDeviceObject; + } - CreatedDeviceObject->Type = DeviceType; - CreatedDeviceObject->DriverObject = DriverObject; - CreatedDeviceObject->CurrentIrp = NULL; - CreatedDeviceObject->Flags = 0; + CreatedDeviceObject->Type = DeviceType; + CreatedDeviceObject->DriverObject = DriverObject; + CreatedDeviceObject->CurrentIrp = NULL; + CreatedDeviceObject->Flags = 0; - CreatedDeviceObject->DeviceExtension = - ExAllocatePoolWithTag(NonPagedPool, DeviceExtensionSize, - TAG_DEVICE_EXTENSION); - if (DeviceExtensionSize > 0 && CreatedDeviceObject->DeviceExtension == NULL) - { + CreatedDeviceObject->DeviceExtension = + ExAllocatePoolWithTag( + NonPagedPool, + DeviceExtensionSize, + TAG_DEVICE_EXTENSION); + + if (DeviceExtensionSize > 0 && CreatedDeviceObject->DeviceExtension == NULL) + { ExFreePool(CreatedDeviceObject); DPRINT("IoCreateDevice() ExAllocatePoolWithTag failed, returning: 0x%08X\n", STATUS_INSUFFICIENT_RESOURCES); - return(STATUS_INSUFFICIENT_RESOURCES); - } + return STATUS_INSUFFICIENT_RESOURCES; + } - if (DeviceExtensionSize > 0) - { - RtlZeroMemory(CreatedDeviceObject->DeviceExtension, - DeviceExtensionSize); - } + if (DeviceExtensionSize > 0) + { + RtlZeroMemory(CreatedDeviceObject->DeviceExtension, DeviceExtensionSize); + } - CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize; - CreatedDeviceObject->ReferenceCount = 1; - CreatedDeviceObject->AttachedDevice = NULL; - CreatedDeviceObject->DeviceType = DeviceType; - CreatedDeviceObject->StackSize = 1; - CreatedDeviceObject->AlignmentRequirement = 1; - CreatedDeviceObject->Characteristics = DeviceCharacteristics; - CreatedDeviceObject->Timer = NULL; - CreatedDeviceObject->Vpb = NULL; - KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue); + CreatedDeviceObject->Size = sizeof(DEVICE_OBJECT) + DeviceExtensionSize; + CreatedDeviceObject->ReferenceCount = 1; + CreatedDeviceObject->AttachedDevice = NULL; + CreatedDeviceObject->DeviceType = DeviceType; + CreatedDeviceObject->StackSize = 1; + CreatedDeviceObject->AlignmentRequirement = 1; + CreatedDeviceObject->Characteristics = DeviceCharacteristics; + CreatedDeviceObject->Timer = NULL; + CreatedDeviceObject->Vpb = NULL; + KeInitializeDeviceQueue(&CreatedDeviceObject->DeviceQueue); - KeInitializeEvent(&CreatedDeviceObject->DeviceLock, - SynchronizationEvent, - TRUE); + KeInitializeEvent( + &CreatedDeviceObject->DeviceLock, + SynchronizationEvent, + TRUE); - /* FIXME: Do we need to add network drives too?! */ - if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK || - CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM || - CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE) - { + /* FIXME: Do we need to add network drives too?! */ + if (CreatedDeviceObject->DeviceType == FILE_DEVICE_DISK || + CreatedDeviceObject->DeviceType == FILE_DEVICE_CD_ROM || + CreatedDeviceObject->DeviceType == FILE_DEVICE_TAPE) + { IoAttachVpb(CreatedDeviceObject); - } + } - DeviceObjectExtension = - ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVOBJ_EXTENSION), - TAG_DEVICE_EXTENSION); + DeviceObjectExtension = + ExAllocatePoolWithTag( + NonPagedPool, + sizeof(DEVOBJ_EXTENSION), + TAG_DEVICE_EXTENSION); - DeviceObjectExtension->Type = 0 /* ?? */; - DeviceObjectExtension->Size = sizeof(DEVOBJ_EXTENSION); - DeviceObjectExtension->DeviceObject = CreatedDeviceObject; - DeviceObjectExtension->DeviceNode = NULL; + DeviceObjectExtension->Type = 0 /* ?? */; + DeviceObjectExtension->Size = sizeof(DEVOBJ_EXTENSION); + DeviceObjectExtension->DeviceObject = CreatedDeviceObject; + DeviceObjectExtension->DeviceNode = NULL; - CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension; + CreatedDeviceObject->DeviceObjectExtension = DeviceObjectExtension; - *DeviceObject = CreatedDeviceObject; + *DeviceObject = CreatedDeviceObject; - return(STATUS_SUCCESS); + return STATUS_SUCCESS; } +/* + * IoOpenDeviceInstanceKey + * + * Status + * @unimplemented + */ -NTSTATUS -STDCALL -IoOpenDeviceInstanceKey ( - DWORD Unknown0, - DWORD Unknown1, - DWORD Unknown2, - DWORD Unknown3, - DWORD Unknown4 - ) +NTSTATUS STDCALL +IoOpenDeviceInstanceKey( + DWORD Unknown0, + DWORD Unknown1, + DWORD Unknown2, + DWORD Unknown3, + DWORD Unknown4) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } +/* + * IoQueryDeviceEnumInfo + * + * Status + * @unimplemented + */ -DWORD -STDCALL -IoQueryDeviceEnumInfo ( - DWORD Unknown0, - DWORD Unknown1 - ) +DWORD STDCALL +IoQueryDeviceEnumInfo( + DWORD Unknown0, + DWORD Unknown1) { - UNIMPLEMENTED; - return 0; + UNIMPLEMENTED; + return 0; } - /* EOF */ diff --git a/reactos/ntoskrnl/io/driver.c b/reactos/ntoskrnl/io/driver.c index b5f7973b1c3..3259c70eb41 100644 --- a/reactos/ntoskrnl/io/driver.c +++ b/reactos/ntoskrnl/io/driver.c @@ -1,4 +1,4 @@ -/* $Id: driver.c,v 1.38 2004/03/21 18:58:53 navaraf Exp $ +/* $Id: driver.c,v 1.39 2004/03/27 19:41:32 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -83,58 +83,611 @@ POBJECT_TYPE EXPORTED IoDriverObjectType = NULL; #define TAG_DRIVER TAG('D', 'R', 'V', 'R') #define TAG_DRIVER_EXTENSION TAG('D', 'R', 'V', 'E') +#define DRIVER_REGISTRY_KEY_BASENAME L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\" + /* PRIVATE FUNCTIONS **********************************************************/ NTSTATUS STDCALL -IopCreateDriver(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - POBJECT_ATTRIBUTES ObjectAttributes) +IopCreateDriver( + PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + POBJECT_ATTRIBUTES ObjectAttributes) { - DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n", - ObjectBody, - Parent, - RemainingPath); - if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL) - { - return(STATUS_UNSUCCESSFUL); - } + DPRINT("LdrCreateModule(ObjectBody %x, Parent %x, RemainingPath %S)\n", + ObjectBody, Parent, RemainingPath); - return(STATUS_SUCCESS); + if (RemainingPath != NULL && wcschr(RemainingPath + 1, '\\') != NULL) + return STATUS_UNSUCCESSFUL; + + return STATUS_SUCCESS; } VOID INIT_FUNCTION IopInitDriverImplementation(VOID) { - /* Register the process object type */ - IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R'); - IoDriverObjectType->TotalObjects = 0; - IoDriverObjectType->TotalHandles = 0; - IoDriverObjectType->MaxObjects = ULONG_MAX; - IoDriverObjectType->MaxHandles = ULONG_MAX; - IoDriverObjectType->PagedPoolCharge = 0; - IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT); - IoDriverObjectType->Dump = NULL; - IoDriverObjectType->Open = NULL; - IoDriverObjectType->Close = NULL; - IoDriverObjectType->Delete = NULL; - IoDriverObjectType->Parse = NULL; - IoDriverObjectType->Security = NULL; - IoDriverObjectType->QueryName = NULL; - IoDriverObjectType->OkayToClose = NULL; - IoDriverObjectType->Create = IopCreateDriver; - IoDriverObjectType->DuplicationNotify = NULL; - RtlRosInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver"); + /* Register the process object type */ + IoDriverObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + IoDriverObjectType->Tag = TAG('D', 'R', 'V', 'R'); + IoDriverObjectType->TotalObjects = 0; + IoDriverObjectType->TotalHandles = 0; + IoDriverObjectType->MaxObjects = ULONG_MAX; + IoDriverObjectType->MaxHandles = ULONG_MAX; + IoDriverObjectType->PagedPoolCharge = 0; + IoDriverObjectType->NonpagedPoolCharge = sizeof(DRIVER_OBJECT); + IoDriverObjectType->Dump = NULL; + IoDriverObjectType->Open = NULL; + IoDriverObjectType->Close = NULL; + IoDriverObjectType->Delete = NULL; + IoDriverObjectType->Parse = NULL; + IoDriverObjectType->Security = NULL; + IoDriverObjectType->QueryName = NULL; + IoDriverObjectType->OkayToClose = NULL; + IoDriverObjectType->Create = IopCreateDriver; + IoDriverObjectType->DuplicationNotify = NULL; + RtlRosInitUnicodeStringFromLiteral(&IoDriverObjectType->TypeName, L"Driver"); - ObpCreateTypeObject(IoDriverObjectType); + ObpCreateTypeObject(IoDriverObjectType); - InitializeListHead(&DriverReinitListHead); - KeInitializeSpinLock(&DriverReinitListLock); - DriverReinitTailEntry = NULL; + InitializeListHead(&DriverReinitListHead); + KeInitializeSpinLock(&DriverReinitListLock); + DriverReinitTailEntry = NULL; } +NTSTATUS STDCALL +IopDefaultDispatchFunction( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; + Irp->IoStatus.Information = 0; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_NOT_IMPLEMENTED; +} + +NTSTATUS FASTCALL +IopCreateDriverObject( + PDRIVER_OBJECT *DriverObject, + PUNICODE_STRING ServiceName, + BOOLEAN FileSystem, + PVOID DriverImageStart, + ULONG DriverImageSize) +{ + PDRIVER_OBJECT Object; + ULONG i; + WCHAR NameBuffer[MAX_PATH]; + UNICODE_STRING DriverName; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + + DPRINT("IopCreateDriverObject(%p '%wZ' %x %p %x)\n", + DriverObject, ServiceName, FileSystem, DriverImageStart, DriverImageSize); + + *DriverObject = NULL; + + /* Create ModuleName string */ + if (ServiceName != NULL && ServiceName->Buffer != NULL) + { + if (FileSystem == TRUE) + wcscpy(NameBuffer, FILESYSTEM_ROOT_NAME); + else + wcscpy(NameBuffer, DRIVER_ROOT_NAME); + wcscat(NameBuffer, ServiceName->Buffer); + + RtlInitUnicodeString(&DriverName, NameBuffer); + DPRINT("Driver name: '%wZ'\n", &DriverName); + } + else + { + RtlInitUnicodeString(&DriverName, NULL); + } + + /* Initialize ObjectAttributes for driver object */ + InitializeObjectAttributes( + &ObjectAttributes, + &DriverName, + OBJ_PERMANENT, + NULL, + NULL); + + /* Create driver object */ + Status = ObCreateObject( + KernelMode, + IoDriverObjectType, + &ObjectAttributes, + KernelMode, + NULL, + sizeof(DRIVER_OBJECT), + 0, + 0, + (PVOID*)&Object); + + if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* Create driver extension */ + Object->DriverExtension = (PDRIVER_EXTENSION) + ExAllocatePoolWithTag( + NonPagedPool, + sizeof(DRIVER_EXTENSION), + TAG_DRIVER_EXTENSION); + + if (Object->DriverExtension == NULL) + { + ExFreePool(Object); + return STATUS_NO_MEMORY; + } + + RtlZeroMemory(Object->DriverExtension, sizeof(DRIVER_EXTENSION)); + + Object->Type = InternalDriverType; + Object->DriverStart = DriverImageStart; + Object->DriverSize = DriverImageSize; + + for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) + Object->MajorFunction[i] = IopDefaultDispatchFunction; + + *DriverObject = Object; + + return STATUS_SUCCESS; +} + +/* + * IopDisplayLoadingMessage + * + * Display 'Loading XXX...' message. + */ + +VOID FASTCALL +IopDisplayLoadingMessage(PWCHAR ServiceName) +{ + CHAR TextBuffer[256]; + sprintf(TextBuffer, "Loading %S...\n", ServiceName); + HalDisplayString(TextBuffer); +} + +/* + * IopNormalizeImagePath + * + * Normalize an image path to contain complete path. + * + * Parameters + * ImagePath + * The input path and on exit the result path. ImagePath.Buffer + * must be allocated by ExAllocatePool on input. Caller is responsible + * for freeing the buffer when it's no longer needed. + * + * ServiceName + * Name of the service that ImagePath belongs to. + * + * Return Value + * Status + * + * Remarks + * The input image path isn't freed on error. + */ + +NTSTATUS FASTCALL +IopNormalizeImagePath( + IN OUT PUNICODE_STRING ImagePath, + IN PUNICODE_STRING ServiceName) +{ + UNICODE_STRING InputImagePath; + + RtlCopyMemory( + &InputImagePath, + ImagePath, + sizeof(UNICODE_STRING)); + + if (InputImagePath.Length == 0) + { + ImagePath->Length = (33 * sizeof(WCHAR)) + ServiceName->Length; + ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); + if (ImagePath->Buffer == NULL) + return STATUS_NO_MEMORY; + + wcscpy(ImagePath->Buffer, L"\\SystemRoot\\system32\\drivers\\"); + wcscat(ImagePath->Buffer, ServiceName->Buffer); + wcscat(ImagePath->Buffer, L".sys"); + } else + if (InputImagePath.Buffer[0] != L'\\') + { + ImagePath->Length = (12 * sizeof(WCHAR)) + InputImagePath.Length; + ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL); + ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); + if (ImagePath->Buffer == NULL) + return STATUS_NO_MEMORY; + + wcscpy(ImagePath->Buffer, L"\\SystemRoot\\"); + wcscat(ImagePath->Buffer, InputImagePath.Buffer); + RtlFreeUnicodeString(&InputImagePath); + } + + return STATUS_SUCCESS; +} + +/* + * IopLoadServiceModule + * + * Load a module specified by registry settings for service. + * + * Parameters + * ServiceName + * Name of the service to load. + * + * Return Value + * Status + */ + +NTSTATUS FASTCALL +IopLoadServiceModule( + IN PUNICODE_STRING ServiceName, + OUT PMODULE_OBJECT *ModuleObject) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; + ULONG ServiceStart; + UNICODE_STRING ServiceImagePath; + NTSTATUS Status; + + /* + * Get information about the service. + */ + + RtlZeroMemory(QueryTable, sizeof(QueryTable)); + + RtlInitUnicodeString(&ServiceImagePath, NULL); + + QueryTable[0].Name = L"Start"; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[0].EntryContext = &ServiceStart; + + QueryTable[1].Name = L"ImagePath"; + QueryTable[1].Flags = RTL_QUERY_REGISTRY_DIRECT; + QueryTable[1].EntryContext = &ServiceImagePath; + + Status = RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, + ServiceName->Buffer, QueryTable, NULL, NULL); + + if (!NT_SUCCESS(Status)) + { + DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); + return Status; + } + + IopDisplayLoadingMessage(ServiceName->Buffer); + + /* + * Normalize the image path for all later processing. + */ + + Status = IopNormalizeImagePath(&ServiceImagePath, ServiceName); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); + return Status; + } + + /* + * Load the module. + */ + + *ModuleObject = LdrGetModuleObject(&ServiceImagePath); + + if (*ModuleObject == NULL) + { + /* + * Special case for boot modules that were loaded by boot loader. + */ + + if (ServiceStart == 0) + { + ULONG i; + CHAR SearchName[256]; + PCHAR ModuleName; + PLOADER_MODULE KeLoaderModules = + (PLOADER_MODULE)KeLoaderBlock.ModsAddr; + + Status = STATUS_UNSUCCESSFUL; + + /* + * FIXME: + * Improve this searching algorithm by using the image name + * stored in registry entry ImageName and use the whole path + * (requires change in FreeLoader). + */ + + _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName); + for (i = 1; i < KeLoaderBlock.ModsCount; i++) + { + ModuleName = (PCHAR)KeLoaderModules[i].String; + if (!strcmp(ModuleName, SearchName)) + { + /* Tell, that the module is already loaded */ + KeLoaderModules[i].Reserved = 1; + + Status = LdrProcessModule( + (PVOID)KeLoaderModules[i].ModStart, + &ServiceImagePath, + ModuleObject); + + break; + } + } + } + + /* + * Case for rest of the drivers (except disabled) + */ + + else if (ServiceStart < 4) + { + DPRINT("Loading module\n"); + Status = LdrLoadModule(&ServiceImagePath, ModuleObject); + } + } + else + { + DPRINT("Module already loaded\n"); + Status = STATUS_SUCCESS; + } + + RtlFreeUnicodeString(&ServiceImagePath); + + /* + * Now check if the module was loaded successfully. + */ + + if (!NT_SUCCESS(Status)) + { + DPRINT("Module loading failed (Status %x)\n", Status); + } + + DPRINT("Module loading (Status %x)\n", Status); + + return Status; +} + +/* + * IopInitializeDriverModule + * + * Initalize a loaded driver. + * + * Parameters + * DeviceNode + * Pointer to device node. + * + * ModuleObject + * Module object representing the driver. It can be retrieve by + * IopLoadServiceModule. + * + * FileSystemDriver + * Set to TRUE for file system drivers. + * + * DriverObject + * On successful return this contains the driver object representing + * the loaded driver. + */ + +NTSTATUS FASTCALL +IopInitializeDriverModule( + IN PDEVICE_NODE DeviceNode, + IN PMODULE_OBJECT ModuleObject, + IN BOOLEAN FileSystemDriver, + OUT PDRIVER_OBJECT *DriverObject) +{ + UNICODE_STRING RegistryKey; + PDRIVER_INITIALIZE DriverEntry = ModuleObject->EntryPoint; + NTSTATUS Status; + + Status = IopCreateDriverObject( + DriverObject, + &DeviceNode->ServiceName, + FileSystemDriver, + ModuleObject->Base, + ModuleObject->Length); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IopCreateDriverObject failed (Status %x)\n", Status); + return Status; + } + + if (DeviceNode->ServiceName.Buffer) + { + RegistryKey.Length = DeviceNode->ServiceName.Length + + sizeof(DRIVER_REGISTRY_KEY_BASENAME); + RegistryKey.MaximumLength = RegistryKey.Length + sizeof(UNICODE_NULL); + RegistryKey.Buffer = ExAllocatePool(PagedPool, RegistryKey.MaximumLength); + wcscpy(RegistryKey.Buffer, DRIVER_REGISTRY_KEY_BASENAME); + wcscat(RegistryKey.Buffer, DeviceNode->ServiceName.Buffer); + } + else + { + RtlInitUnicodeString(&RegistryKey, NULL); + } + + DPRINT("RegistryKey: %wZ\n", &RegistryKey); + DPRINT("Calling driver entrypoint at %08lx\n", DriverEntry); + + IopMarkLastReinitializeDriver(); + + Status = DriverEntry(*DriverObject, &RegistryKey); + if (!NT_SUCCESS(Status)) + { + ExFreePool((*DriverObject)->DriverExtension); + ObMakeTemporaryObject(DriverObject); + ObDereferenceObject(DriverObject); + return Status; + } + + IopReinitializeDrivers(); + + return STATUS_SUCCESS; +} + +/* + * IopAttachFilterDriversCallback + * + * Internal routine used by IopAttachFilterDrivers. + */ + +NTSTATUS STDCALL +IopAttachFilterDriversCallback( + PWSTR ValueName, + ULONG ValueType, + PVOID ValueData, + ULONG ValueLength, + PVOID Context, + PVOID EntryContext) +{ + PDEVICE_NODE DeviceNode = Context; + UNICODE_STRING ServiceName; + PWCHAR Filters; + PMODULE_OBJECT ModuleObject; + PDRIVER_OBJECT DriverObject; + NTSTATUS Status; + + + for (Filters = ValueData; + ((ULONG_PTR)Filters - (ULONG_PTR)ValueData) < ValueLength && + *Filters != 0; + Filters += (ServiceName.Length / sizeof(WCHAR)) + 1) + { + DPRINT("Filter Driver: %S (%wZ)\n", Filters, &DeviceNode->InstancePath); + ServiceName.Buffer = Filters; + ServiceName.MaximumLength = + ServiceName.Length = wcslen(Filters) * sizeof(WCHAR); + + /* Load and initialize the filter driver */ + Status = IopLoadServiceModule(&ServiceName, &ModuleObject); + if (!NT_SUCCESS(Status)) + continue; + + Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject); + if (!NT_SUCCESS(Status)) + continue; + + Status = IopInitializeDevice(DeviceNode, DriverObject); + if (!NT_SUCCESS(Status)) + continue; + } + + return STATUS_SUCCESS; +} + +/* + * IopAttachFilterDrivers + * + * Load filter drivers for specified device node. + * + * Parameters + * Lower + * Set to TRUE for loading lower level filters or FALSE for upper + * level filters. + */ + +NTSTATUS FASTCALL +IopAttachFilterDrivers( + PDEVICE_NODE DeviceNode, + BOOLEAN Lower) +{ + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + PWCHAR KeyBuffer; + UNICODE_STRING Class; + WCHAR ClassBuffer[40]; + NTSTATUS Status; + + /* + * First load the device filters + */ + + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].EntryContext = NULL; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + QueryTable[1].QueryRoutine = NULL; + QueryTable[1].Name = NULL; + + KeyBuffer = ExAllocatePool( + PagedPool, + (49 * sizeof(WCHAR)) + DeviceNode->InstancePath.Length); + wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Enum\\"); + wcscat(KeyBuffer, DeviceNode->InstancePath.Buffer); + + RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + /* + * Now get the class GUID + */ + + Class.Length = 0; + Class.MaximumLength = 40 * sizeof(WCHAR); + Class.Buffer = ClassBuffer; + QueryTable[0].QueryRoutine = NULL; + QueryTable[0].Name = L"ClassGUID"; + QueryTable[0].EntryContext = &Class; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED | RTL_QUERY_REGISTRY_DIRECT; + + Status = RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + ExFreePool(KeyBuffer); + + /* + * Load the class filter driver + */ + + if (NT_SUCCESS(Status)) + { + QueryTable[0].QueryRoutine = IopAttachFilterDriversCallback; + if (Lower) + QueryTable[0].Name = L"LowerFilters"; + else + QueryTable[0].Name = L"UpperFilters"; + QueryTable[0].EntryContext = NULL; + QueryTable[0].Flags = RTL_QUERY_REGISTRY_REQUIRED; + + KeyBuffer = ExAllocatePool(PagedPool, (58 * sizeof(WCHAR)) + Class.Length); + wcscpy(KeyBuffer, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"); + wcscat(KeyBuffer, ClassBuffer); + + RtlQueryRegistryValues( + RTL_REGISTRY_ABSOLUTE, + KeyBuffer, + QueryTable, + DeviceNode, + NULL); + + ExFreePool(KeyBuffer); + } + + return STATUS_SUCCESS; +} + + + + + + + + static NTSTATUS STDCALL IopCreateGroupListEntry(PWSTR ValueName, ULONG ValueType, @@ -419,27 +972,13 @@ MiFreeBootDriverMemory(PVOID StartAddress, ULONG Length) } } -/* - * 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 +NTSTATUS FASTCALL IopInitializeBuiltinDriver( PDEVICE_NODE ModuleDeviceNode, PVOID ModuleLoadBase, @@ -448,6 +987,7 @@ IopInitializeBuiltinDriver( { PMODULE_OBJECT ModuleObject; PDEVICE_NODE DeviceNode; + PDRIVER_OBJECT DriverObject; NTSTATUS Status; CHAR TextBuffer[256]; PCHAR FileNameWithoutPath; @@ -516,15 +1056,19 @@ IopInitializeBuiltinDriver( /* * Initialize the driver */ - Status = IopInitializeDriver(ModuleObject->EntryPoint, DeviceNode, - FALSE, ModuleObject->Base, ModuleObject->Length, TRUE); + Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, + &DriverObject); + if (!NT_SUCCESS(Status)) { if (ModuleDeviceNode == NULL) IopFreeDeviceNode(DeviceNode); CPRINT("Driver load failed, status (%x)\n", Status); + return Status; } + Status = IopInitializeDevice(DeviceNode, DriverObject); + return Status; } @@ -540,7 +1084,7 @@ IopInitializeBuiltinDriver( * None */ -VOID INIT_FUNCTION +VOID FASTCALL IopInitializeBootDrivers(VOID) { ULONG BootDriverCount; @@ -621,7 +1165,7 @@ IopInitializeBootDrivers(VOID) * None */ -VOID INIT_FUNCTION +VOID FASTCALL IopInitializeSystemDrivers(VOID) { PLIST_ENTRY GroupEntry; @@ -688,212 +1232,6 @@ IopInitializeSystemDrivers(VOID) DPRINT("IopInitializeSystemDrivers() done\n"); } -/* - * IopGetDriverNameFromServiceKey - * - * Returns a module path from service registry key. - * - * Parameters - * RelativeTo - * Relative path identifier. - * PathName - * Relative key path name. - * ImagePath - * The result path. - * - * Return Value - * Status - */ - -NTSTATUS STDCALL -IopGetDriverNameFromServiceKey( - ULONG RelativeTo, - PWSTR PathName, - PUNICODE_STRING ImagePath) -{ - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - UNICODE_STRING RegistryImagePath; - NTSTATUS Status; - PWSTR ServiceName; - - 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(RelativeTo, - PathName, QueryTable, NULL, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); - RtlFreeUnicodeString(&RegistryImagePath); - return STATUS_UNSUCCESSFUL; - } - - if (RegistryImagePath.Length == 0) - { - ServiceName = wcsrchr(PathName, L'\\'); - if (ServiceName == NULL) - { - ServiceName = PathName; - } - else - { - ServiceName++; - } - - ImagePath->Length = (33 + wcslen(ServiceName)) * sizeof(WCHAR); - ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); - if (ImagePath->Buffer == NULL) - { - return STATUS_UNSUCCESSFUL; - } - wcscpy(ImagePath->Buffer, L"\\SystemRoot\\system32\\drivers\\"); - wcscat(ImagePath->Buffer, ServiceName); - wcscat(ImagePath->Buffer, L".sys"); - } else - if (RegistryImagePath.Buffer[0] != L'\\') - { - ImagePath->Length = (12 + wcslen(RegistryImagePath.Buffer)) * sizeof(WCHAR); - ImagePath->MaximumLength = ImagePath->Length + sizeof(UNICODE_NULL); - ImagePath->Buffer = ExAllocatePool(NonPagedPool, ImagePath->MaximumLength); - 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->MaximumLength = RegistryImagePath.MaximumLength; - 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, - PUNICODE_STRING ServiceName, - BOOLEAN BootDriverOnly) -{ - NTSTATUS Status; - ULONG ServiceStart; - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; - - if (ServiceName == NULL || ServiceName->Buffer == NULL) - { - return STATUS_UNSUCCESSFUL; - } - - /* - * 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_SERVICES, - ServiceName->Buffer, QueryTable, NULL, NULL); - if (!NT_SUCCESS(Status)) - { - DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); - return Status; - } - - if (BootDriverOnly) - { - PLOADER_MODULE KeLoaderModules = (PLOADER_MODULE)KeLoaderBlock.ModsAddr; - - /* - * Find and initialize boot driver - */ - if (ServiceStart == 0 /*SERVICE_BOOT_START*/) - { - ULONG i; - CHAR SearchName[256]; - ULONG ModuleStart, ModuleSize; - PCHAR ModuleName; - - _snprintf(SearchName, sizeof(SearchName), "%wZ.sys", ServiceName); - 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 - if (ServiceStart < 4) - { - UNICODE_STRING ImagePath; - - /* - * Get service path - */ - Status = IopGetDriverNameFromServiceKey(RTL_REGISTRY_SERVICES, - ServiceName->Buffer, &ImagePath); - if (!NT_SUCCESS(Status)) - { - DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); - return Status; - } - - /* - * Display loading message - */ - IopDisplayLoadingMessage(ServiceName->Buffer); - - /* - * Load the service - */ - Status = IopInitializeService(DeviceNode, ServiceName, &ImagePath); - - /* - * Free the service path - */ - RtlFreeUnicodeString(&ImagePath); - } - else - Status = STATUS_UNSUCCESSFUL; - - return Status; -} - /* * IopUnloadDriver * @@ -902,6 +1240,7 @@ IopInitializeDeviceNodeService( * 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 @@ -917,7 +1256,9 @@ IopInitializeDeviceNodeService( NTSTATUS STDCALL IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) { + RTL_QUERY_REGISTRY_TABLE QueryTable[2]; UNICODE_STRING ImagePath; + UNICODE_STRING ServiceName; UNICODE_STRING ObjectName; PDRIVER_OBJECT DriverObject; PMODULE_OBJECT ModuleObject; @@ -927,17 +1268,21 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) DPRINT("IopUnloadDriver('%wZ', %d)\n", DriverServiceName, UnloadPnpDrivers); /* - * Get the service name from the module name + * Get the service name from the registry key name */ + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); if (Start == NULL) Start = DriverServiceName->Buffer; else Start++; + RtlInitUnicodeString(&ServiceName, Start); + /* * Construct the driver object name */ + ObjectName.Length = (wcslen(Start) + 8) * sizeof(WCHAR); ObjectName.MaximumLength = ObjectName.Length + sizeof(WCHAR); ObjectName.Buffer = ExAllocatePool(NonPagedPool, ObjectName.MaximumLength); @@ -948,8 +1293,10 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) /* * 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); @@ -959,22 +1306,46 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) /* * Free the buffer for driver object name */ + ExFreePool(ObjectName.Buffer); /* * Get path of service... */ - Status = IopGetDriverNameFromServiceKey(RTL_REGISTRY_ABSOLUTE, - DriverServiceName->Buffer, &ImagePath); + + 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_ABSOLUTE, + DriverServiceName->Buffer, QueryTable, NULL, NULL); + if (!NT_SUCCESS(Status)) { - DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); + DPRINT("RtlQueryRegistryValues() failed (Status %x)\n", Status); + return Status; + } + + /* + * Normalize the image path for all later processing. + */ + + Status = IopNormalizeImagePath(&ImagePath, &ServiceName); + + if (!NT_SUCCESS(Status)) + { + DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); return Status; } /* * ... and check if it's loaded */ + ModuleObject = LdrGetModuleObject(&ImagePath); if (ModuleObject == NULL) { @@ -984,11 +1355,13 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) /* * 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); @@ -1016,12 +1389,14 @@ IopUnloadDriver(PUNICODE_STRING DriverServiceName, BOOLEAN UnloadPnpDrivers) NTSTATUS STDCALL NtLoadDriver(IN PUNICODE_STRING DriverServiceName) { - RTL_QUERY_REGISTRY_TABLE QueryTable[2]; + RTL_QUERY_REGISTRY_TABLE QueryTable[3]; UNICODE_STRING ImagePath; + UNICODE_STRING ServiceName; NTSTATUS Status; ULONG Type; PDEVICE_NODE DeviceNode; PMODULE_OBJECT ModuleObject; + PDRIVER_OBJECT DriverObject; LPWSTR Start; DPRINT("NtLoadDriver('%wZ')\n", DriverServiceName); @@ -1029,6 +1404,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) /* * Check security privileges */ + #if 0 if (!SeSinglePrivilegeCheck(SeLoadDriverPrivilege, KeGetPreviousMode())) return STATUS_PRIVILEGE_NOT_HELD; @@ -1037,14 +1413,36 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) RtlInitUnicodeString(&ImagePath, NULL); /* - * Get service type + * Get the service name from the registry key name. */ + + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); + if (Start == NULL) + Start = DriverServiceName->Buffer; + else + Start++; + + RtlInitUnicodeString(&ServiceName, Start); + + /* + * Get service type. + */ + RtlZeroMemory(&QueryTable, sizeof(QueryTable)); + + RtlInitUnicodeString(&ImagePath, NULL); + 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)) { DPRINT("RtlQueryRegistryValues() failed (Status %lx)\n", Status); @@ -1053,13 +1451,14 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) } /* - * Get module path + * Normalize the image path for all later processing. */ - Status = IopGetDriverNameFromServiceKey(RTL_REGISTRY_ABSOLUTE, - DriverServiceName->Buffer, &ImagePath); + + Status = IopNormalizeImagePath(&ImagePath, &ServiceName); + if (!NT_SUCCESS(Status)) { - DPRINT("IopGetDriverNameFromKeyNode() failed (Status %x)\n", Status); + DPRINT("IopNormalizeImagePath() failed (Status %x)\n", Status); return Status; } @@ -1078,8 +1477,10 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) /* * Create device node */ + /* Use IopRootDeviceNode for now */ Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); + if (!NT_SUCCESS(Status)) { DPRINT("IopCreateDeviceNode() failed (Status %lx)\n", Status); @@ -1089,7 +1490,9 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) /* * Load the driver module */ + Status = LdrLoadModule(&ImagePath, &ModuleObject); + if (!NT_SUCCESS(Status)) { DPRINT("LdrLoadModule() failed (Status %lx)\n", Status); @@ -1100,6 +1503,7 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) /* * Set a service name for the device node */ + Start = wcsrchr(DriverServiceName->Buffer, L'\\'); if (Start == NULL) Start = DriverServiceName->Buffer; @@ -1110,21 +1514,24 @@ NtLoadDriver(IN PUNICODE_STRING DriverServiceName) /* * Initialize the driver module */ - Status = IopInitializeDriver( - ModuleObject->EntryPoint, + + Status = IopInitializeDriverModule( DeviceNode, + ModuleObject, (Type == 2 /*SERVICE_FILE_SYSTEM_DRIVER*/ || Type == 8 /*SERVICE_RECOGNIZER_DRIVER*/), - ModuleObject->Base, - ModuleObject->Length, - FALSE); + &DriverObject); + if (!NT_SUCCESS(Status)) { DPRINT1("IopInitializeDriver() failed (Status %lx)\n", Status); LdrUnloadModule(ModuleObject); IopFreeDeviceNode(DeviceNode); + return Status; } + IopInitializeDevice(DeviceNode, DriverObject); + return Status; } @@ -1173,7 +1580,7 @@ IoRegisterDriverReinitialization(PDRIVER_OBJECT DriverObject, } -VOID +VOID FASTCALL IopMarkLastReinitializeDriver(VOID) { KIRQL Irql; @@ -1195,7 +1602,7 @@ IopMarkLastReinitializeDriver(VOID) } -VOID +VOID FASTCALL IopReinitializeDrivers(VOID) { PDRIVER_REINIT_ITEM ReinitItem; diff --git a/reactos/ntoskrnl/io/iomgr.c b/reactos/ntoskrnl/io/iomgr.c index 02ab0269f52..061ba346157 100644 --- a/reactos/ntoskrnl/io/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr.c @@ -1,4 +1,4 @@ -/* $Id: iomgr.c,v 1.45 2003/12/31 14:20:26 hbirr Exp $ +/* $Id: iomgr.c,v 1.46 2004/03/27 19:41:32 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -16,6 +16,7 @@ #include #include #include +#include #include #define NDEBUG @@ -367,6 +368,8 @@ VOID INIT_FUNCTION IoInit2(VOID) { PDEVICE_NODE DeviceNode; + PDRIVER_OBJECT DriverObject; + MODULE_OBJECT ModuleObject; NTSTATUS Status; KeInitializeSpinLock (&IoStatisticsLock); @@ -383,12 +386,15 @@ IoInit2(VOID) return; } - Status = IopInitializeDriver(RawFsDriverEntry, + ModuleObject.Base = NULL; + ModuleObject.Length = 0; + ModuleObject.EntryPoint = RawFsDriverEntry; + + Status = IopInitializeDriverModule( DeviceNode, + &ModuleObject, TRUE, - NULL, - 0, - FALSE); + &DriverObject); if (!NT_SUCCESS(Status)) { IopFreeDeviceNode(DeviceNode); @@ -396,13 +402,20 @@ IoInit2(VOID) return; } + Status = IopInitializeDevice(DeviceNode, DriverObject); + if (!NT_SUCCESS(Status)) + { + IopFreeDeviceNode(DeviceNode); + CPRINT("IopInitializeDevice() failed with status (%x)\n", Status); + return; + } + /* * Initialize PnP root releations */ IopInvalidateDeviceRelations( IopRootDeviceNode, - BusRelations, - TRUE); + BusRelations); } /* diff --git a/reactos/ntoskrnl/io/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr.c index 5f5da1a80a2..8b694857c45 100644 --- a/reactos/ntoskrnl/io/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr.c @@ -1,4 +1,4 @@ -/* $Id: pnpmgr.c,v 1.27 2004/03/21 18:58:53 navaraf Exp $ +/* $Id: pnpmgr.c,v 1.28 2004/03/27 19:41:32 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -1068,15 +1068,28 @@ IopActionInitChildServices( !IopDeviceNodeHasFlag(DeviceNode, DNF_ADDED) && !IopDeviceNodeHasFlag(DeviceNode, DNF_STARTED)) { - Status = IopInitializeDeviceNodeService( - DeviceNode, - &DeviceNode->ServiceName, - BootDrivers); + PMODULE_OBJECT ModuleObject; + PDRIVER_OBJECT DriverObject; + + Status = IopLoadServiceModule(&DeviceNode->ServiceName, &ModuleObject); if (NT_SUCCESS(Status)) { - IopAttachFilterDrivers(DeviceNode, FALSE); - IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); - } else + Status = IopInitializeDriverModule(DeviceNode, ModuleObject, FALSE, &DriverObject); + if (NT_SUCCESS(Status)) + { + /* Attach lower level filter drivers. */ + IopAttachFilterDrivers(DeviceNode, TRUE); + /* Initialize the function driver for the device node */ + Status = IopInitializeDevice(DeviceNode, DriverObject); + if (NT_SUCCESS(Status)) + { + IopDeviceNodeSetFlag(DeviceNode, DNF_STARTED); + /* Attach upper level filter drivers. */ + IopAttachFilterDrivers(DeviceNode, FALSE); + } + } + } + else { /* * Don't disable when trying to load only boot drivers @@ -1138,6 +1151,7 @@ IopActionInitBootServices( * 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. @@ -1177,15 +1191,18 @@ IopInitializePnpServices( NTSTATUS IopInvalidateDeviceRelations( - IN PDEVICE_NODE DeviceNode, - IN DEVICE_RELATION_TYPE Type, - IN BOOLEAN BootDriver) + IN PDEVICE_NODE DeviceNode, + IN DEVICE_RELATION_TYPE Type) { DEVICETREE_TRAVERSE_CONTEXT Context; PDEVICE_RELATIONS DeviceRelations; IO_STATUS_BLOCK IoStatusBlock; PDEVICE_NODE ChildDeviceNode; IO_STACK_LOCATION Stack; + BOOL BootDrivers; + OBJECT_ATTRIBUTES ObjectAttributes; + UNICODE_STRING LinkName; + HANDLE Handle; NTSTATUS Status; ULONG i; @@ -1276,12 +1293,39 @@ IopInvalidateDeviceRelations( return Status; } + /* + * Get the state of the system boot. If the \\SystemRoot link isn't + * created yet, we will assume that it's possible to load only boot + * drivers. + */ + + RtlInitUnicodeString(&LinkName, L"\\SystemRoot"); + + InitializeObjectAttributes( + &ObjectAttributes, + &LinkName, + 0, + NULL, + NULL); + + Status = NtOpenFile( + &Handle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatusBlock, + 0, + 0); + + BootDrivers = NT_SUCCESS(Status) ? FALSE : TRUE; + + NtClose(Handle); + /* * Initialize services for discovered children. Only boot drivers will * be loaded from boot driver! */ - Status = IopInitializePnpServices(DeviceNode, BootDriver); + Status = IopInitializePnpServices(DeviceNode, BootDrivers); if (!NT_SUCCESS(Status)) { DPRINT("IopInitializePnpServices() failed with status (%x)\n", Status); @@ -1326,8 +1370,8 @@ PnpInit(VOID) 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, diff --git a/reactos/ntoskrnl/ldr/loader.c b/reactos/ntoskrnl/ldr/loader.c index b6b38ca5eb5..32455165706 100644 --- a/reactos/ntoskrnl/ldr/loader.c +++ b/reactos/ntoskrnl/ldr/loader.c @@ -1,4 +1,4 @@ -/* $Id: loader.c,v 1.140 2004/03/07 11:59:10 navaraf Exp $ +/* $Id: loader.c,v 1.141 2004/03/27 19:41:32 navaraf Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -449,107 +449,6 @@ LdrUnloadModule(PMODULE_OBJECT ModuleObject) } -NTSTATUS INIT_FUNCTION -LdrInitializeBootStartDriver(PVOID ModuleLoadBase, - PCHAR FileName, - ULONG ModuleLength) -{ - PMODULE_OBJECT ModuleObject; - UNICODE_STRING ModuleName; - PDEVICE_NODE DeviceNode; - NTSTATUS Status; - - WCHAR Buffer[MAX_PATH]; - ULONG Length; - LPWSTR Start; - LPWSTR Ext; - PCHAR FileExt; - CHAR TextBuffer [256]; - ULONG x, y, cx, cy; - - HalQueryDisplayParameters(&x, &y, &cx, &cy); - RtlFillMemory(TextBuffer, x, ' '); - TextBuffer[x] = '\0'; - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - - sprintf(TextBuffer, "Initializing %s...\n", FileName); - HalSetDisplayParameters(0, y-1); - HalDisplayString(TextBuffer); - HalSetDisplayParameters(cx, cy); - - /* Split the filename into base name and extension */ - FileExt = strrchr(FileName, '.'); - if (FileExt != NULL) - Length = FileExt - FileName; - else - Length = strlen(FileName); - - if ((FileExt != NULL) && (strcmp(FileExt, ".sym") == 0)) - { - KDB_SYMBOLFILE_HOOK(ModuleLoadBase, FileName, Length); - return(STATUS_SUCCESS); - } - else if ((FileExt != NULL) && !(strcmp(FileExt, ".sys") == 0)) - { - CPRINT("Ignoring non-driver file %s\n", FileName); - return STATUS_SUCCESS; - } - - /* Use IopRootDeviceNode for now */ - Status = IopCreateDeviceNode(IopRootDeviceNode, NULL, &DeviceNode); - if (!NT_SUCCESS(Status)) - { - CPRINT("Driver load failed, status (%x)\n", Status); - return(Status); - } - - RtlCreateUnicodeStringFromAsciiz(&ModuleName, - FileName); - Status = LdrProcessModule(ModuleLoadBase, - &ModuleName, - &ModuleObject); - RtlFreeUnicodeString(&ModuleName); - if (ModuleObject == NULL) - { - IopFreeDeviceNode(DeviceNode); - CPRINT("Driver load failed, status (%x)\n", Status); - return(STATUS_UNSUCCESSFUL); - } - - - /* Get the service name from the module name */ - Start = wcsrchr(ModuleObject->BaseName.Buffer, L'\\'); - if (Start == NULL) - Start = ModuleObject->BaseName.Buffer; - else - Start++; - - Ext = wcsrchr(ModuleObject->BaseName.Buffer, L'.'); - if (Ext != NULL) - Length = Ext - Start; - else - Length = wcslen(Start); - - wcsncpy(Buffer, Start, Length); - Buffer[Length] = 0; - RtlCreateUnicodeString(&DeviceNode->ServiceName, Buffer); - - Status = IopInitializeDriver(ModuleObject->EntryPoint, - DeviceNode, FALSE, - ModuleObject->Base, - ModuleObject->Length, - TRUE); - if (!NT_SUCCESS(Status)) - { - IopFreeDeviceNode(DeviceNode); - CPRINT("Driver load failed, status (%x)\n", Status); - } - - return(Status); -} - - NTSTATUS LdrProcessModule(PVOID ModuleLoadBase, PUNICODE_STRING ModuleName,