diff --git a/reactos/ntoskrnl/io/iomgr/driver.c b/reactos/ntoskrnl/io/iomgr/driver.c index 29541021c4a..9f54c174776 100644 --- a/reactos/ntoskrnl/io/iomgr/driver.c +++ b/reactos/ntoskrnl/io/iomgr/driver.c @@ -16,6 +16,8 @@ /* GLOBALS ********************************************************************/ +ERESOURCE IopDriverLoadResource; + LIST_ENTRY DriverReinitListHead; KSPIN_LOCK DriverReinitListLock; PLIST_ENTRY DriverReinitTailEntry; @@ -113,6 +115,7 @@ IopGetDriverObject( DPRINT("IopGetDriverObject(%p '%wZ' %x)\n", DriverObject, ServiceName, FileSystem); + ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); *DriverObject = NULL; /* Create ModuleName string */ @@ -313,6 +316,7 @@ IopLoadServiceModule( HANDLE CCSKey, ServiceKey; PVOID BaseAddress; + ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource)); ASSERT(ServiceName->Length); DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject); @@ -567,6 +571,8 @@ IopAttachFilterDriversCallback( ServiceName.MaximumLength = ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR); + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); Status = IopGetDriverObject(&DriverObject, &ServiceName, FALSE); @@ -575,7 +581,11 @@ IopAttachFilterDriversCallback( /* Load and initialize the filter driver */ Status = IopLoadServiceModule(&ServiceName, &ModuleObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; + } Status = IopInitializeDriverModule(DeviceNode, ModuleObject, @@ -583,9 +593,16 @@ IopAttachFilterDriversCallback( FALSE, &DriverObject); if (!NT_SUCCESS(Status)) + { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; + } } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + Status = IopInitializeDevice(DeviceNode, DriverObject); /* Remove extra reference */ @@ -1971,6 +1988,8 @@ IopLoadUnloadDriver( DPRINT("FullImagePath: '%wZ'\n", &ImagePath); DPRINT("Type: %lx\n", Type); + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* * Get existing DriverObject pointer (in case the driver * has already been loaded and initialized). @@ -1990,6 +2009,8 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); return Status; } @@ -2000,6 +2021,8 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); return Status; } @@ -2015,16 +2038,24 @@ IopLoadUnloadDriver( if (!NT_SUCCESS(Status)) { DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status); + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); MmUnloadSystemImage(ModuleObject); return Status; } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + /* Initialize and start device */ IopInitializeDevice(DeviceNode, *DriverObject); Status = IopStartDevice(DeviceNode); } else { + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); + DPRINT("DriverObject already exist in ObjectManager\n"); Status = STATUS_IMAGE_ALREADY_LOADED; diff --git a/reactos/ntoskrnl/io/iomgr/iomgr.c b/reactos/ntoskrnl/io/iomgr/iomgr.c index b1d4a136731..b61e8e4fce1 100644 --- a/reactos/ntoskrnl/io/iomgr/iomgr.c +++ b/reactos/ntoskrnl/io/iomgr/iomgr.c @@ -54,6 +54,7 @@ extern KSPIN_LOCK ShutdownListLock; extern POBJECT_TYPE IoAdapterObjectType; extern ERESOURCE IopDatabaseResource; ERESOURCE IopSecurityResource; +extern ERESOURCE IopDriverLoadResource; extern KGUARDED_MUTEX PnpNotifyListLock; extern LIST_ENTRY IopDiskFileSystemQueueHead; extern LIST_ENTRY IopCdRomFileSystemQueueHead; @@ -476,8 +477,9 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock) IopInitLookasideLists(); /* Initialize all locks and lists */ - ExInitializeResource(&IopDatabaseResource); - ExInitializeResource(&IopSecurityResource); + ExInitializeResourceLite(&IopDatabaseResource); + ExInitializeResourceLite(&IopSecurityResource); + ExInitializeResourceLite(&IopDriverLoadResource); KeInitializeGuardedMutex(&PnpNotifyListLock); InitializeListHead(&IopDiskFileSystemQueueHead); InitializeListHead(&IopCdRomFileSystemQueueHead); diff --git a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c index 63d82da9ad6..1cdfc5d46d3 100644 --- a/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c +++ b/reactos/ntoskrnl/io/pnpmgr/pnpmgr.c @@ -21,6 +21,7 @@ ERESOURCE PpRegistryDeviceResource; KGUARDED_MUTEX PpDeviceReferenceTableLock; RTL_AVL_TABLE PpDeviceReferenceTable; +extern ERESOURCE IopDriverLoadResource; extern ULONG ExpInitializationPhase; extern BOOLEAN ExpInTextModeSetup; extern BOOLEAN PnpSystemInit; @@ -2611,6 +2612,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, PLDR_DATA_TABLE_ENTRY ModuleObject; PDRIVER_OBJECT DriverObject; + KeEnterCriticalRegion(); + ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE); /* Get existing DriverObject pointer (in case the driver has already been loaded and initialized) */ Status = IopGetDriverObject( @@ -2642,6 +2645,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode, if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD; } } + ExReleaseResourceLite(&IopDriverLoadResource); + KeLeaveCriticalRegion(); /* Driver is loaded and initialized at this point */ if (NT_SUCCESS(Status))