mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 21:16:09 +00:00
[NTOS:IO]
- Introduce IopDriverLoadResource to protect against concurrent driver loading CORE-8696 #resolve svn path=/trunk/; revision=64951
This commit is contained in:
parent
2c91c440f1
commit
fcae57435c
3 changed files with 40 additions and 2 deletions
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
/* GLOBALS ********************************************************************/
|
/* GLOBALS ********************************************************************/
|
||||||
|
|
||||||
|
ERESOURCE IopDriverLoadResource;
|
||||||
|
|
||||||
LIST_ENTRY DriverReinitListHead;
|
LIST_ENTRY DriverReinitListHead;
|
||||||
KSPIN_LOCK DriverReinitListLock;
|
KSPIN_LOCK DriverReinitListLock;
|
||||||
PLIST_ENTRY DriverReinitTailEntry;
|
PLIST_ENTRY DriverReinitTailEntry;
|
||||||
|
@ -113,6 +115,7 @@ IopGetDriverObject(
|
||||||
DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
|
DPRINT("IopGetDriverObject(%p '%wZ' %x)\n",
|
||||||
DriverObject, ServiceName, FileSystem);
|
DriverObject, ServiceName, FileSystem);
|
||||||
|
|
||||||
|
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
|
||||||
*DriverObject = NULL;
|
*DriverObject = NULL;
|
||||||
|
|
||||||
/* Create ModuleName string */
|
/* Create ModuleName string */
|
||||||
|
@ -313,6 +316,7 @@ IopLoadServiceModule(
|
||||||
HANDLE CCSKey, ServiceKey;
|
HANDLE CCSKey, ServiceKey;
|
||||||
PVOID BaseAddress;
|
PVOID BaseAddress;
|
||||||
|
|
||||||
|
ASSERT(ExIsResourceAcquiredExclusiveLite(&IopDriverLoadResource));
|
||||||
ASSERT(ServiceName->Length);
|
ASSERT(ServiceName->Length);
|
||||||
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
|
DPRINT("IopLoadServiceModule(%wZ, 0x%p)\n", ServiceName, ModuleObject);
|
||||||
|
|
||||||
|
@ -567,6 +571,8 @@ IopAttachFilterDriversCallback(
|
||||||
ServiceName.MaximumLength =
|
ServiceName.MaximumLength =
|
||||||
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
|
ServiceName.Length = (USHORT)wcslen(Filters) * sizeof(WCHAR);
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
|
||||||
Status = IopGetDriverObject(&DriverObject,
|
Status = IopGetDriverObject(&DriverObject,
|
||||||
&ServiceName,
|
&ServiceName,
|
||||||
FALSE);
|
FALSE);
|
||||||
|
@ -575,7 +581,11 @@ IopAttachFilterDriversCallback(
|
||||||
/* Load and initialize the filter driver */
|
/* Load and initialize the filter driver */
|
||||||
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
|
Status = IopLoadServiceModule(&ServiceName, &ModuleObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
Status = IopInitializeDriverModule(DeviceNode,
|
Status = IopInitializeDriverModule(DeviceNode,
|
||||||
ModuleObject,
|
ModuleObject,
|
||||||
|
@ -583,9 +593,16 @@ IopAttachFilterDriversCallback(
|
||||||
FALSE,
|
FALSE,
|
||||||
&DriverObject);
|
&DriverObject);
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
return Status;
|
return Status;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
Status = IopInitializeDevice(DeviceNode, DriverObject);
|
||||||
|
|
||||||
/* Remove extra reference */
|
/* Remove extra reference */
|
||||||
|
@ -1971,6 +1988,8 @@ IopLoadUnloadDriver(
|
||||||
DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
|
DPRINT("FullImagePath: '%wZ'\n", &ImagePath);
|
||||||
DPRINT("Type: %lx\n", Type);
|
DPRINT("Type: %lx\n", Type);
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
|
||||||
/*
|
/*
|
||||||
* Get existing DriverObject pointer (in case the driver
|
* Get existing DriverObject pointer (in case the driver
|
||||||
* has already been loaded and initialized).
|
* has already been loaded and initialized).
|
||||||
|
@ -1990,6 +2009,8 @@ IopLoadUnloadDriver(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
|
DPRINT("MmLoadSystemImage() failed (Status %lx)\n", Status);
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2000,6 +2021,8 @@ IopLoadUnloadDriver(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
DPRINT1("IopCreateDeviceNode() failed (Status %lx)\n", Status);
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
MmUnloadSystemImage(ModuleObject);
|
MmUnloadSystemImage(ModuleObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
@ -2015,16 +2038,24 @@ IopLoadUnloadDriver(
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
|
DPRINT1("IopInitializeDriverModule() failed (Status %lx)\n", Status);
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
MmUnloadSystemImage(ModuleObject);
|
MmUnloadSystemImage(ModuleObject);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Initialize and start device */
|
/* Initialize and start device */
|
||||||
IopInitializeDevice(DeviceNode, *DriverObject);
|
IopInitializeDevice(DeviceNode, *DriverObject);
|
||||||
Status = IopStartDevice(DeviceNode);
|
Status = IopStartDevice(DeviceNode);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
DPRINT("DriverObject already exist in ObjectManager\n");
|
DPRINT("DriverObject already exist in ObjectManager\n");
|
||||||
Status = STATUS_IMAGE_ALREADY_LOADED;
|
Status = STATUS_IMAGE_ALREADY_LOADED;
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@ extern KSPIN_LOCK ShutdownListLock;
|
||||||
extern POBJECT_TYPE IoAdapterObjectType;
|
extern POBJECT_TYPE IoAdapterObjectType;
|
||||||
extern ERESOURCE IopDatabaseResource;
|
extern ERESOURCE IopDatabaseResource;
|
||||||
ERESOURCE IopSecurityResource;
|
ERESOURCE IopSecurityResource;
|
||||||
|
extern ERESOURCE IopDriverLoadResource;
|
||||||
extern KGUARDED_MUTEX PnpNotifyListLock;
|
extern KGUARDED_MUTEX PnpNotifyListLock;
|
||||||
extern LIST_ENTRY IopDiskFileSystemQueueHead;
|
extern LIST_ENTRY IopDiskFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopCdRomFileSystemQueueHead;
|
extern LIST_ENTRY IopCdRomFileSystemQueueHead;
|
||||||
|
@ -476,8 +477,9 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
IopInitLookasideLists();
|
IopInitLookasideLists();
|
||||||
|
|
||||||
/* Initialize all locks and lists */
|
/* Initialize all locks and lists */
|
||||||
ExInitializeResource(&IopDatabaseResource);
|
ExInitializeResourceLite(&IopDatabaseResource);
|
||||||
ExInitializeResource(&IopSecurityResource);
|
ExInitializeResourceLite(&IopSecurityResource);
|
||||||
|
ExInitializeResourceLite(&IopDriverLoadResource);
|
||||||
KeInitializeGuardedMutex(&PnpNotifyListLock);
|
KeInitializeGuardedMutex(&PnpNotifyListLock);
|
||||||
InitializeListHead(&IopDiskFileSystemQueueHead);
|
InitializeListHead(&IopDiskFileSystemQueueHead);
|
||||||
InitializeListHead(&IopCdRomFileSystemQueueHead);
|
InitializeListHead(&IopCdRomFileSystemQueueHead);
|
||||||
|
|
|
@ -21,6 +21,7 @@ ERESOURCE PpRegistryDeviceResource;
|
||||||
KGUARDED_MUTEX PpDeviceReferenceTableLock;
|
KGUARDED_MUTEX PpDeviceReferenceTableLock;
|
||||||
RTL_AVL_TABLE PpDeviceReferenceTable;
|
RTL_AVL_TABLE PpDeviceReferenceTable;
|
||||||
|
|
||||||
|
extern ERESOURCE IopDriverLoadResource;
|
||||||
extern ULONG ExpInitializationPhase;
|
extern ULONG ExpInitializationPhase;
|
||||||
extern BOOLEAN ExpInTextModeSetup;
|
extern BOOLEAN ExpInTextModeSetup;
|
||||||
extern BOOLEAN PnpSystemInit;
|
extern BOOLEAN PnpSystemInit;
|
||||||
|
@ -2611,6 +2612,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
|
||||||
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
PLDR_DATA_TABLE_ENTRY ModuleObject;
|
||||||
PDRIVER_OBJECT DriverObject;
|
PDRIVER_OBJECT DriverObject;
|
||||||
|
|
||||||
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDriverLoadResource, TRUE);
|
||||||
/* Get existing DriverObject pointer (in case the driver has
|
/* Get existing DriverObject pointer (in case the driver has
|
||||||
already been loaded and initialized) */
|
already been loaded and initialized) */
|
||||||
Status = IopGetDriverObject(
|
Status = IopGetDriverObject(
|
||||||
|
@ -2642,6 +2645,8 @@ IopActionInitChildServices(PDEVICE_NODE DeviceNode,
|
||||||
if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
|
if (!BootDrivers) DeviceNode->Problem = CM_PROB_DRIVER_FAILED_LOAD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ExReleaseResourceLite(&IopDriverLoadResource);
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Driver is loaded and initialized at this point */
|
/* Driver is loaded and initialized at this point */
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue