mirror of
https://github.com/reactos/reactos.git
synced 2024-07-30 16:18:43 +00:00
- Get rid of the stupid LIST_FOR_EACH macros in FS Notifcation APIs.
- Each new change request should be queued at the end of the list, not at the head. - Also, reference the device object for each registration, since one more object is holding a pointer to it, likewise, dereference the object on deregistration. - IopLoadFileSystem should use the base FSD in case the device object is an attachee. Also, use IoBuildDEviceIoControlRequest to minimize the IRP setup to only a couple of lines. svn path=/trunk/; revision=22757
This commit is contained in:
parent
fe8b3cfda1
commit
23e06403c7
|
@ -145,12 +145,28 @@ IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN BOOLEAN DriverActive)
|
IN BOOLEAN DriverActive)
|
||||||
{
|
{
|
||||||
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* Acquire the notification lock */
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
||||||
LIST_FOR_EACH(ChangeEntry, &FsChangeNotifyListHead,FS_CHANGE_NOTIFY_ENTRY, FsChangeNotifyList)
|
|
||||||
|
/* Loop the list */
|
||||||
|
ListEntry = FsChangeNotifyListHead.Flink;
|
||||||
|
while (ListEntry != &FsChangeNotifyListHead)
|
||||||
{
|
{
|
||||||
(ChangeEntry->FSDNotificationProc)(DeviceObject, DriverActive);
|
/* Get the entry */
|
||||||
|
ChangeEntry = CONTAINING_RECORD(ListEntry,
|
||||||
|
FS_CHANGE_NOTIFY_ENTRY,
|
||||||
|
FsChangeNotifyList);
|
||||||
|
|
||||||
|
/* Call the notification procedure */
|
||||||
|
ChangeEntry->FSDNotificationProc(DeviceObject, DriverActive);
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -240,7 +256,7 @@ IopMountFileSystem(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return(Status);
|
return(Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
|
@ -249,36 +265,42 @@ IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Loop as long as we're attached */
|
||||||
|
while (AttachedDeviceObject->AttachedDevice)
|
||||||
|
{
|
||||||
|
/* Get the attached device object */
|
||||||
|
AttachedDeviceObject = AttachedDeviceObject->AttachedDevice;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the event and build the IRP */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
|
Irp = IoBuildDeviceIoControlRequest(IRP_MJ_DEVICE_CONTROL,
|
||||||
if (Irp==NULL)
|
AttachedDeviceObject,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
0,
|
||||||
|
FALSE,
|
||||||
|
&Event,
|
||||||
|
&IoStatusBlock);
|
||||||
|
if (Irp)
|
||||||
{
|
{
|
||||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
/* Set the major and minor functions */
|
||||||
|
StackPtr = IoGetNextIrpStackLocation(Irp);
|
||||||
|
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
|
||||||
|
StackPtr->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
|
||||||
|
|
||||||
|
/* Call the driver */
|
||||||
|
Status = IoCallDriver(AttachedDeviceObject, Irp);
|
||||||
|
if (Status == STATUS_PENDING)
|
||||||
|
{
|
||||||
|
/* Wait on it */
|
||||||
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->UserIosb = &IoStatusBlock;
|
|
||||||
Irp->UserEvent = &Event;
|
|
||||||
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
|
|
||||||
|
|
||||||
StackPtr = IoGetNextIrpStackLocation(Irp);
|
|
||||||
StackPtr->MajorFunction = IRP_MJ_FILE_SYSTEM_CONTROL;
|
|
||||||
StackPtr->MinorFunction = IRP_MN_LOAD_FILE_SYSTEM;
|
|
||||||
StackPtr->Flags = 0;
|
|
||||||
StackPtr->Control = 0;
|
|
||||||
StackPtr->DeviceObject = DeviceObject;
|
|
||||||
StackPtr->FileObject = NULL;
|
|
||||||
StackPtr->CompletionRoutine = NULL;
|
|
||||||
|
|
||||||
Status = IoCallDriver(DeviceObject,Irp);
|
|
||||||
if (Status==STATUS_PENDING)
|
|
||||||
{
|
|
||||||
KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
|
|
||||||
Status = IoStatusBlock.Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(Status);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -347,12 +369,7 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
case STATUS_FS_DRIVER_REQUIRED:
|
case STATUS_FS_DRIVER_REQUIRED:
|
||||||
DevObject = current->DeviceObject;
|
DevObject = current->DeviceObject;
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&FileSystemListLock);
|
||||||
Status = IopLoadFileSystem(DevObject);
|
IopLoadFileSystem(DevObject);
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
return(Status);
|
|
||||||
}
|
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
||||||
goto restart;
|
goto restart;
|
||||||
|
|
||||||
|
@ -584,20 +601,26 @@ IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
|
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
|
||||||
{
|
{
|
||||||
PFS_CHANGE_NOTIFY_ENTRY Entry;
|
PFS_CHANGE_NOTIFY_ENTRY Entry;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
Entry = ExAllocatePoolWithTag(NonPagedPool,
|
/* Allocate a notification entry */
|
||||||
|
Entry = ExAllocatePoolWithTag(PagedPool,
|
||||||
sizeof(FS_CHANGE_NOTIFY_ENTRY),
|
sizeof(FS_CHANGE_NOTIFY_ENTRY),
|
||||||
TAG_FS_CHANGE_NOTIFY);
|
TAG_FS_CHANGE_NOTIFY);
|
||||||
if (Entry == NULL) return(STATUS_INSUFFICIENT_RESOURCES);
|
if (!Entry) return(STATUS_INSUFFICIENT_RESOURCES);
|
||||||
|
|
||||||
|
/* Save the driver object and notification routine */
|
||||||
Entry->DriverObject = DriverObject;
|
Entry->DriverObject = DriverObject;
|
||||||
Entry->FSDNotificationProc = FSDNotificationProc;
|
Entry->FSDNotificationProc = FSDNotificationProc;
|
||||||
|
|
||||||
|
/* Insert it into the notification list */
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
||||||
InsertHeadList(&FsChangeNotifyListHead, &Entry->FsChangeNotifyList);
|
InsertTailList(&FsChangeNotifyListHead, &Entry->FsChangeNotifyList);
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
/* Reference the driver */
|
||||||
|
ObReferenceObject(DriverObject);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -609,20 +632,38 @@ IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
|
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
|
||||||
{
|
{
|
||||||
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
||||||
|
PLIST_ENTRY NextEntry;
|
||||||
|
PAGED_CODE();
|
||||||
|
|
||||||
LIST_FOR_EACH(ChangeEntry, &FsChangeNotifyListHead, FS_CHANGE_NOTIFY_ENTRY, FsChangeNotifyList)
|
/* Acquire the list lock */
|
||||||
|
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
||||||
|
|
||||||
|
/* Loop the list */
|
||||||
|
NextEntry = FsChangeNotifyListHead.Flink;
|
||||||
|
while (NextEntry != &FsChangeNotifyListHead)
|
||||||
{
|
{
|
||||||
if (ChangeEntry->DriverObject == DriverObject &&
|
/* Get the entry */
|
||||||
ChangeEntry->FSDNotificationProc == FSDNotificationProc)
|
ChangeEntry = CONTAINING_RECORD(NextEntry,
|
||||||
{
|
FS_CHANGE_NOTIFY_ENTRY,
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
FsChangeNotifyList);
|
||||||
RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
|
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
|
||||||
|
|
||||||
|
/* Check if it matches this de-registration */
|
||||||
|
if ((ChangeEntry->DriverObject == DriverObject) &&
|
||||||
|
(ChangeEntry->FSDNotificationProc == FSDNotificationProc))
|
||||||
|
{
|
||||||
|
/* It does, remove it from the list */
|
||||||
|
RemoveEntryList(&ChangeEntry->FsChangeNotifyList);
|
||||||
ExFreePoolWithTag(ChangeEntry, TAG_FS_CHANGE_NOTIFY);
|
ExFreePoolWithTag(ChangeEntry, TAG_FS_CHANGE_NOTIFY);
|
||||||
return;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
NextEntry = NextEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Release the lock and dereference the driver */
|
||||||
|
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
||||||
|
ObDereferenceObject(DriverObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -632,6 +673,7 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IoAcquireVpbSpinLock(OUT PKIRQL Irql)
|
IoAcquireVpbSpinLock(OUT PKIRQL Irql)
|
||||||
{
|
{
|
||||||
|
/* Simply acquire the lock */
|
||||||
KeAcquireSpinLock(&IoVpbLock, Irql);
|
KeAcquireSpinLock(&IoVpbLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +684,7 @@ VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IoReleaseVpbSpinLock(IN KIRQL Irql)
|
IoReleaseVpbSpinLock(IN KIRQL Irql)
|
||||||
{
|
{
|
||||||
|
/* Just release the lock */
|
||||||
KeReleaseSpinLock(&IoVpbLock, Irql);
|
KeReleaseSpinLock(&IoVpbLock, Irql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue