mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 09:23:06 +00:00
[NTOSKRNL]
- renamed Io volumes global to match Windows names (in case of debug) - renamed IopDereferenceVpb() to IopDereferenceVpbAndFree(), IopReferenceVpbForVerify() to IopReferenceVerifyVpb(), IopInitializeVpbForMount() to IopMountInitializeVpb(), IopLoadFileSystem() to IopLoadFileSystemDriver() - implemented IopDecrementDeviceObjectHandleCount(), IopInterlockedIncrementUlong(), IopInterlockedDecrementUlong(), IopNotifyAlreadyRegisteredFileSystems() and IoEnumerateRegisteredFiltersList() - halfplemented IopDecrementDeviceObjectRef() - implemented check for already registrered notification in IoRegisterFsRegistrationChange() - implemented sending notifications for already registered drivers to registrant in IoRegisterFsRegistrationChange() - implemented VPB freeing in IopDereferenceVpbAndFree() - acquire Io volumes lists once and forever for system shutdown, instead of keeping acquiring and releasing - reference device object in IopShutdownBaseFileSystems() before sending it the shutdown IRP. To ensure to keep it valid till the end - added a FS driver registration operations counter - use this counter to handle failed mounts - fixed: release locks before calling driver for mounting and reacquire them after - fixed check for boot partition failure (and associated bugcheck): check we are in boot phase 0 or 1 - simplified lock process by using only one lock (ie removed mutex). Also use only critical region where needed - fixed: ensure that locks are properly released when quitting a function - fixed wrong return in IopCreateVpb() - minor fixes around svn path=/trunk/; revision=52065
This commit is contained in:
parent
33a2b85a57
commit
69764dd21a
5 changed files with 401 additions and 119 deletions
|
@ -838,7 +838,7 @@ IopCreateVpb(
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopDereferenceVpb(
|
IopDereferenceVpbAndFree(
|
||||||
IN PVPB Vpb
|
IN PVPB Vpb
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -869,8 +869,15 @@ IopDereferenceDeviceObject(
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IoGetRelatedTargetDevice(IN PFILE_OBJECT FileObject,
|
IoGetRelatedTargetDevice(
|
||||||
OUT PDEVICE_OBJECT *DeviceObject
|
IN PFILE_OBJECT FileObject,
|
||||||
|
OUT PDEVICE_OBJECT *DeviceObject
|
||||||
|
);
|
||||||
|
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopUnloadDevice(
|
||||||
|
IN PDEVICE_OBJECT DeviceObject
|
||||||
);
|
);
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -19,9 +19,10 @@
|
||||||
ULONG IopDeviceObjectNumber = 0;
|
ULONG IopDeviceObjectNumber = 0;
|
||||||
LIST_ENTRY ShutdownListHead, LastChanceShutdownListHead;
|
LIST_ENTRY ShutdownListHead, LastChanceShutdownListHead;
|
||||||
KSPIN_LOCK ShutdownListLock;
|
KSPIN_LOCK ShutdownListLock;
|
||||||
extern LIST_ENTRY IopDiskFsListHead;
|
extern LIST_ENTRY IopDiskFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopCdRomFsListHead;
|
extern LIST_ENTRY IopCdRomFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopTapeFsListHead;
|
extern LIST_ENTRY IopTapeFileSystemQueueHead;
|
||||||
|
extern ERESOURCE IopDatabaseResource;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS **********************************************************/
|
/* PRIVATE FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
|
@ -187,14 +188,17 @@ IoShutdownSystem(IN ULONG Phase)
|
||||||
}
|
}
|
||||||
else if (Phase == 1)
|
else if (Phase == 1)
|
||||||
{
|
{
|
||||||
|
/* Acquire resource forever */
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
/* Shutdown disk file systems */
|
/* Shutdown disk file systems */
|
||||||
IopShutdownBaseFileSystems(&IopDiskFsListHead);
|
IopShutdownBaseFileSystems(&IopDiskFileSystemQueueHead);
|
||||||
|
|
||||||
/* Shutdown cdrom file systems */
|
/* Shutdown cdrom file systems */
|
||||||
IopShutdownBaseFileSystems(&IopCdRomFsListHead);
|
IopShutdownBaseFileSystems(&IopCdRomFileSystemQueueHead);
|
||||||
|
|
||||||
/* Shutdown tape filesystems */
|
/* Shutdown tape filesystems */
|
||||||
IopShutdownBaseFileSystems(&IopTapeFsListHead);
|
IopShutdownBaseFileSystems(&IopTapeFileSystemQueueHead);
|
||||||
|
|
||||||
/* Loop last-chance shutdown notifications */
|
/* Loop last-chance shutdown notifications */
|
||||||
ListEntry = ExInterlockedRemoveHeadList(&LastChanceShutdownListHead,
|
ListEntry = ExInterlockedRemoveHeadList(&LastChanceShutdownListHead,
|
||||||
|
|
|
@ -479,7 +479,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
{
|
{
|
||||||
/* Dereference the device and VPB, then fail */
|
/* Dereference the device and VPB, then fail */
|
||||||
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
if (Vpb) IopDereferenceVpbAndFree(Vpb);
|
||||||
return STATUS_INSUFFICIENT_RESOURCES;
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,7 +577,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
|
|
||||||
/* Dereference the device and VPB */
|
/* Dereference the device and VPB */
|
||||||
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
if (Vpb) IopDereferenceVpbAndFree(Vpb);
|
||||||
|
|
||||||
/* We failed, return status */
|
/* We failed, return status */
|
||||||
OpenPacket->FinalStatus = Status;
|
OpenPacket->FinalStatus = Status;
|
||||||
|
@ -687,7 +687,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
|
|
||||||
/* Dereference the device object and VPB */
|
/* Dereference the device object and VPB */
|
||||||
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
if (Vpb) IopDereferenceVpbAndFree(Vpb);
|
||||||
|
|
||||||
/* Clear the FO and dereference it */
|
/* Clear the FO and dereference it */
|
||||||
FileObject->DeviceObject = NULL;
|
FileObject->DeviceObject = NULL;
|
||||||
|
@ -783,7 +783,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
IopDereferenceDeviceObject(OriginalDeviceObject, FALSE);
|
||||||
|
|
||||||
/* Unless the driver cancelled the open, dereference the VPB */
|
/* Unless the driver cancelled the open, dereference the VPB */
|
||||||
if (!(OpenCancelled) && (Vpb)) IopDereferenceVpb(Vpb);
|
if (!(OpenCancelled) && (Vpb)) IopDereferenceVpbAndFree(Vpb);
|
||||||
|
|
||||||
/* Set the status and return */
|
/* Set the status and return */
|
||||||
OpenPacket->FinalStatus = Status;
|
OpenPacket->FinalStatus = Status;
|
||||||
|
@ -806,7 +806,7 @@ IopParseDevice(IN PVOID ParseObject,
|
||||||
if (OwnerDevice != DeviceObject)
|
if (OwnerDevice != DeviceObject)
|
||||||
{
|
{
|
||||||
/* We have to de-reference the VPB we had associated */
|
/* We have to de-reference the VPB we had associated */
|
||||||
if (Vpb) IopDereferenceVpb(Vpb);
|
if (Vpb) IopDereferenceVpbAndFree(Vpb);
|
||||||
|
|
||||||
/* And re-associate with the actual one */
|
/* And re-associate with the actual one */
|
||||||
Vpb = FileObject->Vpb;
|
Vpb = FileObject->Vpb;
|
||||||
|
|
|
@ -52,19 +52,17 @@ extern LIST_ENTRY ShutdownListHead;
|
||||||
extern LIST_ENTRY LastChanceShutdownListHead;
|
extern LIST_ENTRY LastChanceShutdownListHead;
|
||||||
extern KSPIN_LOCK ShutdownListLock;
|
extern KSPIN_LOCK ShutdownListLock;
|
||||||
extern POBJECT_TYPE IoAdapterObjectType;
|
extern POBJECT_TYPE IoAdapterObjectType;
|
||||||
ERESOURCE IopDatabaseResource;
|
extern ERESOURCE IopDatabaseResource;
|
||||||
extern ERESOURCE FileSystemListLock;
|
|
||||||
ERESOURCE IopSecurityResource;
|
ERESOURCE IopSecurityResource;
|
||||||
extern KGUARDED_MUTEX FsChangeNotifyListLock;
|
|
||||||
extern KGUARDED_MUTEX PnpNotifyListLock;
|
extern KGUARDED_MUTEX PnpNotifyListLock;
|
||||||
extern LIST_ENTRY IopDiskFsListHead;
|
extern LIST_ENTRY IopDiskFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopCdRomFsListHead;
|
extern LIST_ENTRY IopCdRomFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopTapeFsListHead;
|
extern LIST_ENTRY IopTapeFileSystemQueueHead;
|
||||||
extern LIST_ENTRY IopNetworkFsListHead;
|
extern LIST_ENTRY IopNetworkFileSystemQueueHead;
|
||||||
extern LIST_ENTRY DriverBootReinitListHead;
|
extern LIST_ENTRY DriverBootReinitListHead;
|
||||||
extern LIST_ENTRY DriverReinitListHead;
|
extern LIST_ENTRY DriverReinitListHead;
|
||||||
extern LIST_ENTRY PnpNotifyListHead;
|
extern LIST_ENTRY PnpNotifyListHead;
|
||||||
extern LIST_ENTRY FsChangeNotifyListHead;
|
extern LIST_ENTRY IopFsNotifyChangeQueueHead;
|
||||||
extern LIST_ENTRY IopErrorLogListHead;
|
extern LIST_ENTRY IopErrorLogListHead;
|
||||||
extern LIST_ENTRY IopTimerQueueHead;
|
extern LIST_ENTRY IopTimerQueueHead;
|
||||||
extern KDPC IopTimerDpc;
|
extern KDPC IopTimerDpc;
|
||||||
|
@ -450,20 +448,18 @@ IoInitSystem(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||||
|
|
||||||
/* Initialize all locks and lists */
|
/* Initialize all locks and lists */
|
||||||
ExInitializeResource(&IopDatabaseResource);
|
ExInitializeResource(&IopDatabaseResource);
|
||||||
ExInitializeResource(&FileSystemListLock);
|
|
||||||
ExInitializeResource(&IopSecurityResource);
|
ExInitializeResource(&IopSecurityResource);
|
||||||
KeInitializeGuardedMutex(&FsChangeNotifyListLock);
|
|
||||||
KeInitializeGuardedMutex(&PnpNotifyListLock);
|
KeInitializeGuardedMutex(&PnpNotifyListLock);
|
||||||
InitializeListHead(&IopDiskFsListHead);
|
InitializeListHead(&IopDiskFileSystemQueueHead);
|
||||||
InitializeListHead(&IopCdRomFsListHead);
|
InitializeListHead(&IopCdRomFileSystemQueueHead);
|
||||||
InitializeListHead(&IopTapeFsListHead);
|
InitializeListHead(&IopTapeFileSystemQueueHead);
|
||||||
InitializeListHead(&IopNetworkFsListHead);
|
InitializeListHead(&IopNetworkFileSystemQueueHead);
|
||||||
InitializeListHead(&DriverBootReinitListHead);
|
InitializeListHead(&DriverBootReinitListHead);
|
||||||
InitializeListHead(&DriverReinitListHead);
|
InitializeListHead(&DriverReinitListHead);
|
||||||
InitializeListHead(&PnpNotifyListHead);
|
InitializeListHead(&PnpNotifyListHead);
|
||||||
InitializeListHead(&ShutdownListHead);
|
InitializeListHead(&ShutdownListHead);
|
||||||
InitializeListHead(&LastChanceShutdownListHead);
|
InitializeListHead(&LastChanceShutdownListHead);
|
||||||
InitializeListHead(&FsChangeNotifyListHead);
|
InitializeListHead(&IopFsNotifyChangeQueueHead);
|
||||||
InitializeListHead(&IopErrorLogListHead);
|
InitializeListHead(&IopErrorLogListHead);
|
||||||
KeInitializeSpinLock(&IoStatisticsLock);
|
KeInitializeSpinLock(&IoStatisticsLock);
|
||||||
KeInitializeSpinLock(&DriverReinitListLock);
|
KeInitializeSpinLock(&DriverReinitListLock);
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||||
* Hervé Poussineau (hpoussin@reactos.org)
|
* Hervé Poussineau (hpoussin@reactos.org)
|
||||||
* Eric Kohl
|
* Eric Kohl
|
||||||
|
* Pierre Schweitzer (pierre.schweitzer@reactos.org)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
@ -21,14 +22,60 @@
|
||||||
|
|
||||||
/* GLOBALS ******************************************************************/
|
/* GLOBALS ******************************************************************/
|
||||||
|
|
||||||
ERESOURCE FileSystemListLock;
|
ERESOURCE IopDatabaseResource;
|
||||||
LIST_ENTRY IopDiskFsListHead, IopNetworkFsListHead;
|
LIST_ENTRY IopDiskFileSystemQueueHead, IopNetworkFileSystemQueueHead;
|
||||||
LIST_ENTRY IopCdRomFsListHead, IopTapeFsListHead;
|
LIST_ENTRY IopCdRomFileSystemQueueHead, IopTapeFileSystemQueueHead;
|
||||||
KGUARDED_MUTEX FsChangeNotifyListLock;
|
LIST_ENTRY IopFsNotifyChangeQueueHead;
|
||||||
LIST_ENTRY FsChangeNotifyListHead;
|
ULONG IopFsRegistrationOps;
|
||||||
|
|
||||||
/* PRIVATE FUNCTIONS *********************************************************/
|
/* PRIVATE FUNCTIONS *********************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @halfplemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopDecrementDeviceObjectRef(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
IN BOOLEAN UnloadIfUnused)
|
||||||
|
{
|
||||||
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
/* Acquire lock */
|
||||||
|
OldIrql = KeAcquireQueuedSpinLock(LockQueueIoDatabaseLock);
|
||||||
|
ASSERT(DeviceObject->ReferenceCount > 0);
|
||||||
|
|
||||||
|
if (--DeviceObject->ReferenceCount > 0)
|
||||||
|
{
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Here, DO is not referenced any longer, check if we have to unload it */
|
||||||
|
if (UnloadIfUnused || IoGetDevObjExtension(DeviceObject)->ExtensionFlags &
|
||||||
|
(DOE_UNLOAD_PENDING | DOE_DELETE_PENDING | DOE_REMOVE_PENDING))
|
||||||
|
{
|
||||||
|
/* Unload the driver */
|
||||||
|
IopUnloadDevice(DeviceObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release lock */
|
||||||
|
KeReleaseQueuedSpinLock(LockQueueIoDatabaseLock, OldIrql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopDecrementDeviceObjectHandleCount(IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
{
|
||||||
|
/* Just decrease reference count */
|
||||||
|
IopDecrementDeviceObjectRef(DeviceObject, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
PVPB
|
PVPB
|
||||||
NTAPI
|
NTAPI
|
||||||
IopCheckVpbMounted(IN POPEN_PACKET OpenPacket,
|
IopCheckVpbMounted(IN POPEN_PACKET OpenPacket,
|
||||||
|
@ -100,6 +147,9 @@ IopCheckVpbMounted(IN POPEN_PACKET OpenPacket,
|
||||||
return Vpb;
|
return Vpb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||||
|
@ -110,7 +160,7 @@ IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||||
Vpb = ExAllocatePoolWithTag(NonPagedPool,
|
Vpb = ExAllocatePoolWithTag(NonPagedPool,
|
||||||
sizeof(VPB),
|
sizeof(VPB),
|
||||||
TAG_VPB);
|
TAG_VPB);
|
||||||
if (!Vpb) return STATUS_UNSUCCESSFUL;
|
if (!Vpb) return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
|
||||||
/* Clear it so we don't waste time manually */
|
/* Clear it so we don't waste time manually */
|
||||||
RtlZeroMemory(Vpb, sizeof(VPB));
|
RtlZeroMemory(Vpb, sizeof(VPB));
|
||||||
|
@ -125,9 +175,12 @@ IopCreateVpb(IN PDEVICE_OBJECT DeviceObject)
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopDereferenceVpb(IN PVPB Vpb)
|
IopDereferenceVpbAndFree(IN PVPB Vpb)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
|
||||||
|
@ -136,21 +189,30 @@ IopDereferenceVpb(IN PVPB Vpb)
|
||||||
Vpb->ReferenceCount--;
|
Vpb->ReferenceCount--;
|
||||||
|
|
||||||
/* Check if we're out of references */
|
/* Check if we're out of references */
|
||||||
if (!Vpb->ReferenceCount)
|
if (!Vpb->ReferenceCount && Vpb->RealDevice->Vpb == Vpb &&
|
||||||
|
!(Vpb->Flags & VPB_PERSISTENT))
|
||||||
{
|
{
|
||||||
/* FIXME: IMPLEMENT CLEANUP! */
|
/* Release VPB lock */
|
||||||
ASSERT(FALSE);
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
}
|
|
||||||
|
|
||||||
/* Release VPB lock */
|
/* And free VPB */
|
||||||
IoReleaseVpbSpinLock(OldIrql);
|
ExFreePoolWithTag(Vpb, TAG_VPB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Release VPB lock */
|
||||||
|
IoReleaseVpbSpinLock(OldIrql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NTAPI
|
NTAPI
|
||||||
IopReferenceVpbForVerify(IN PDEVICE_OBJECT DeviceObject,
|
IopReferenceVerifyVpb(IN PDEVICE_OBJECT DeviceObject,
|
||||||
OUT PDEVICE_OBJECT *FileSystemObject,
|
OUT PDEVICE_OBJECT *FileSystemObject,
|
||||||
OUT PVPB *Vpb)
|
OUT PVPB *Vpb)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PVPB LocalVpb;
|
PVPB LocalVpb;
|
||||||
|
@ -181,9 +243,9 @@ IopReferenceVpbForVerify(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
PVPB
|
PVPB
|
||||||
NTAPI
|
NTAPI
|
||||||
IopInitializeVpbForMount(IN PDEVICE_OBJECT DeviceObject,
|
IopMountInitializeVpb(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN PDEVICE_OBJECT AttachedDeviceObject,
|
IN PDEVICE_OBJECT AttachedDeviceObject,
|
||||||
IN BOOLEAN Raw)
|
IN BOOLEAN Raw)
|
||||||
{
|
{
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
PVPB Vpb;
|
PVPB Vpb;
|
||||||
|
@ -212,20 +274,20 @@ IopInitializeVpbForMount(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return Vpb;
|
return Vpb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
FORCEINLINE
|
||||||
IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
||||||
IN BOOLEAN DriverActive)
|
IN BOOLEAN DriverActive)
|
||||||
{
|
{
|
||||||
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
/* Acquire the notification lock */
|
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
|
||||||
|
|
||||||
/* Loop the list */
|
/* Loop the list */
|
||||||
ListEntry = FsChangeNotifyListHead.Flink;
|
ListEntry = IopFsNotifyChangeQueueHead.Flink;
|
||||||
while (ListEntry != &FsChangeNotifyListHead)
|
while (ListEntry != &IopFsNotifyChangeQueueHead)
|
||||||
{
|
{
|
||||||
/* Get the entry */
|
/* Get the entry */
|
||||||
ChangeEntry = CONTAINING_RECORD(ListEntry,
|
ChangeEntry = CONTAINING_RECORD(ListEntry,
|
||||||
|
@ -238,11 +300,47 @@ IopNotifyFileSystemChange(IN PDEVICE_OBJECT DeviceObject,
|
||||||
/* Go to the next entry */
|
/* Go to the next entry */
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock */
|
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
FASTCALL
|
||||||
|
IopInterlockedIncrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue,
|
||||||
|
IN PULONG Ulong)
|
||||||
|
{
|
||||||
|
KIRQL Irql;
|
||||||
|
ULONG OldValue;
|
||||||
|
|
||||||
|
Irql = KeAcquireQueuedSpinLock(Queue);
|
||||||
|
OldValue = (*Ulong)++;
|
||||||
|
KeReleaseQueuedSpinLock(Queue, Irql);
|
||||||
|
|
||||||
|
return OldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
ULONG
|
||||||
|
FASTCALL
|
||||||
|
IopInterlockedDecrementUlong(IN KSPIN_LOCK_QUEUE_NUMBER Queue,
|
||||||
|
IN PULONG Ulong)
|
||||||
|
{
|
||||||
|
KIRQL Irql;
|
||||||
|
ULONG OldValue;
|
||||||
|
|
||||||
|
Irql = KeAcquireQueuedSpinLock(Queue);
|
||||||
|
OldValue = (*Ulong)--;
|
||||||
|
KeReleaseQueuedSpinLock(Queue, Irql);
|
||||||
|
|
||||||
|
return OldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
|
IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
|
||||||
|
@ -254,9 +352,6 @@ IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
/* Lock the FS List and initialize an event to wait on */
|
|
||||||
KeEnterCriticalRegion();
|
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock,TRUE);
|
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
/* Get the first entry and start looping */
|
/* Get the first entry and start looping */
|
||||||
|
@ -268,6 +363,9 @@ IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
|
||||||
DEVICE_OBJECT,
|
DEVICE_OBJECT,
|
||||||
Queue.ListEntry);
|
Queue.ListEntry);
|
||||||
|
|
||||||
|
ObReferenceObject(DeviceObject);
|
||||||
|
IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
|
|
||||||
/* Check if we're attached */
|
/* Check if we're attached */
|
||||||
if (DeviceObject->AttachedDevice)
|
if (DeviceObject->AttachedDevice)
|
||||||
{
|
{
|
||||||
|
@ -293,18 +391,20 @@ IopShutdownBaseFileSystems(IN PLIST_ENTRY ListHead)
|
||||||
/* Reset the event */
|
/* Reset the event */
|
||||||
KeClearEvent(&Event);
|
KeClearEvent(&Event);
|
||||||
|
|
||||||
|
IopDecrementDeviceObjectRef(DeviceObject, FALSE);
|
||||||
|
ObDereferenceObject(DeviceObject);
|
||||||
|
|
||||||
/* Go to the next entry */
|
/* Go to the next entry */
|
||||||
ListEntry = ListEntry->Flink;
|
ListEntry = ListEntry->Flink;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock */
|
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
VOID
|
VOID
|
||||||
NTAPI
|
NTAPI
|
||||||
IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
IopLoadFileSystemDriver(IN PDEVICE_OBJECT DeviceObject)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
|
@ -347,8 +447,14 @@ IopLoadFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Dereference DO - FsRec? */
|
||||||
|
IopDecrementDeviceObjectRef(AttachedDeviceObject, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
@ -366,7 +472,7 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
LIST_ENTRY LocalList;
|
LIST_ENTRY LocalList;
|
||||||
PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
|
PDEVICE_OBJECT AttachedDeviceObject = DeviceObject;
|
||||||
PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
|
PDEVICE_OBJECT FileSystemDeviceObject, ParentFsDeviceObject;
|
||||||
ULONG FsStackOverhead;
|
ULONG FsStackOverhead, RegistrationOps;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Check if the device isn't already locked */
|
/* Check if the device isn't already locked */
|
||||||
|
@ -387,7 +493,7 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
/* Acquire the FS Lock*/
|
/* Acquire the FS Lock*/
|
||||||
KeEnterCriticalRegion();
|
KeEnterCriticalRegion();
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
|
ExAcquireResourceSharedLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
/* Make sure we weren't already mounted */
|
/* Make sure we weren't already mounted */
|
||||||
if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
|
if (!(DeviceObject->Vpb->Flags & (VPB_MOUNTED | VPB_REMOVE_PENDING)))
|
||||||
|
@ -411,17 +517,17 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
(DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
|
(DeviceObject->DeviceType == FILE_DEVICE_VIRTUAL_DISK))
|
||||||
{
|
{
|
||||||
/* Use the disk list */
|
/* Use the disk list */
|
||||||
FsList = &IopDiskFsListHead;
|
FsList = &IopDiskFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
|
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM)
|
||||||
{
|
{
|
||||||
/* Use the CD-ROM list */
|
/* Use the CD-ROM list */
|
||||||
FsList = &IopCdRomFsListHead;
|
FsList = &IopCdRomFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* It's gotta be a tape... */
|
/* It's gotta be a tape... */
|
||||||
FsList = &IopTapeFsListHead;
|
FsList = &IopTapeFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now loop the fs list until one of the file systems accepts us */
|
/* Now loop the fs list until one of the file systems accepts us */
|
||||||
|
@ -502,6 +608,13 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
StackPtr->Parameters.MountVolume.DeviceObject =
|
StackPtr->Parameters.MountVolume.DeviceObject =
|
||||||
AttachedDeviceObject;
|
AttachedDeviceObject;
|
||||||
|
|
||||||
|
/* Save registration operations */
|
||||||
|
RegistrationOps = IopFsRegistrationOps;
|
||||||
|
|
||||||
|
/* Release locks */
|
||||||
|
IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
/* Call the driver */
|
/* Call the driver */
|
||||||
Status = IoCallDriver(FileSystemDeviceObject, Irp);
|
Status = IoCallDriver(FileSystemDeviceObject, Irp);
|
||||||
if (Status == STATUS_PENDING)
|
if (Status == STATUS_PENDING)
|
||||||
|
@ -515,14 +628,17 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
Status = IoStatusBlock.Status;
|
Status = IoStatusBlock.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExAcquireResourceSharedLite(&IopDatabaseResource, TRUE);
|
||||||
|
IopInterlockedDecrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
|
|
||||||
/* Check if mounting was successful */
|
/* Check if mounting was successful */
|
||||||
if (NT_SUCCESS(Status))
|
if (NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Mount the VPB */
|
/* Mount the VPB */
|
||||||
*Vpb = IopInitializeVpbForMount(DeviceObject,
|
*Vpb = IopMountInitializeVpb(DeviceObject,
|
||||||
AttachedDeviceObject,
|
AttachedDeviceObject,
|
||||||
(DeviceObject->Vpb->Flags &
|
(DeviceObject->Vpb->Flags &
|
||||||
VPB_RAW_MOUNT));
|
VPB_RAW_MOUNT));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -534,11 +650,22 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If there were registration operations in the meanwhile */
|
||||||
|
if (RegistrationOps != IopFsRegistrationOps)
|
||||||
|
{
|
||||||
|
/* We need to setup a local list to pickup where we left */
|
||||||
|
LocalList.Flink = FsList->Flink;
|
||||||
|
ListEntry = &LocalList;
|
||||||
|
|
||||||
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
|
}
|
||||||
|
|
||||||
/* Otherwise, check if we need to load the FS driver */
|
/* Otherwise, check if we need to load the FS driver */
|
||||||
if (Status == STATUS_FS_DRIVER_REQUIRED)
|
if (Status == STATUS_FS_DRIVER_REQUIRED)
|
||||||
{
|
{
|
||||||
/* We need to release the lock */
|
/* We need to release the lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
/* Release the device lock if we're holding it */
|
/* Release the device lock if we're holding it */
|
||||||
if (!DeviceIsLocked)
|
if (!DeviceIsLocked)
|
||||||
|
@ -546,8 +673,11 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
|
KeSetEvent(&DeviceObject->DeviceLock, 0, FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Leave critical section */
|
||||||
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Load the FS */
|
/* Load the FS */
|
||||||
IopLoadFileSystem(ParentFsDeviceObject);
|
IopLoadFileSystemDriver(ParentFsDeviceObject);
|
||||||
|
|
||||||
/* Check if the device isn't already locked */
|
/* Check if the device isn't already locked */
|
||||||
if (!DeviceIsLocked)
|
if (!DeviceIsLocked)
|
||||||
|
@ -569,7 +699,8 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reacquire the lock */
|
/* Reacquire the lock */
|
||||||
ExAcquireResourceSharedLite(&FileSystemListLock, TRUE);
|
KeEnterCriticalRegion();
|
||||||
|
ExAcquireResourceSharedLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
/* When we released the lock, make sure nobody beat us */
|
/* When we released the lock, make sure nobody beat us */
|
||||||
if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
|
if (DeviceObject->Vpb->Flags & VPB_MOUNTED)
|
||||||
|
@ -620,7 +751,7 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the FS lock */
|
/* Release the FS lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
KeLeaveCriticalRegion();
|
KeLeaveCriticalRegion();
|
||||||
|
|
||||||
/* Release the device lock if we're holding it */
|
/* Release the device lock if we're holding it */
|
||||||
|
@ -628,7 +759,8 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
/* Check if we failed to mount the boot partition */
|
/* Check if we failed to mount the boot partition */
|
||||||
if ((!NT_SUCCESS(Status)) &&
|
if ((!NT_SUCCESS(Status)) &&
|
||||||
(DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION))
|
(DeviceObject->Flags & DO_SYSTEM_BOOT_PARTITION) &&
|
||||||
|
ExpInitializationPhase < 2)
|
||||||
{
|
{
|
||||||
/* Bugcheck the system */
|
/* Bugcheck the system */
|
||||||
KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
|
KeBugCheckEx(INACCESSIBLE_BOOT_DEVICE,
|
||||||
|
@ -642,19 +774,102 @@ IopMountVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @implemented
|
||||||
|
*/
|
||||||
|
VOID
|
||||||
|
NTAPI
|
||||||
|
IopNotifyAlreadyRegisteredFileSystems(IN PLIST_ENTRY ListHead,
|
||||||
|
IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine,
|
||||||
|
BOOLEAN SkipLast)
|
||||||
|
{
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
PDEVICE_OBJECT DeviceObject;
|
||||||
|
|
||||||
|
/* Browse the whole list */
|
||||||
|
ListEntry = ListHead->Flink;
|
||||||
|
while (ListEntry != ListHead)
|
||||||
|
{
|
||||||
|
/* Check if we reached end and if we have to skip it */
|
||||||
|
if (ListEntry->Flink == ListHead && SkipLast)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, get DO and notify */
|
||||||
|
DeviceObject = CONTAINING_RECORD(ListEntry,
|
||||||
|
DEVICE_OBJECT,
|
||||||
|
Queue.ListEntry);
|
||||||
|
|
||||||
|
DriverNotificationRoutine(DeviceObject, TRUE);
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* PUBLIC FUNCTIONS **********************************************************/
|
/* PUBLIC FUNCTIONS **********************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IoEnumerateRegisteredFiltersList(IN PDRIVER_OBJECT *DriverObjectList,
|
IoEnumerateRegisteredFiltersList(OUT PDRIVER_OBJECT *DriverObjectList,
|
||||||
IN ULONG DriverObjectListSize,
|
IN ULONG DriverObjectListSize,
|
||||||
OUT PULONG ActualNumberDriverObjects)
|
OUT PULONG ActualNumberDriverObjects)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
USHORT Index = 0;
|
||||||
return STATUS_UNSUCCESSFUL;
|
ULONG ListSize = 0;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
PFS_CHANGE_NOTIFY_ENTRY ChangeEntry;
|
||||||
|
|
||||||
|
/* Acquire the FS lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
|
/* First of all, count number of driver objects */
|
||||||
|
ListEntry = IopFsNotifyChangeQueueHead.Flink;
|
||||||
|
while (ListEntry != &IopFsNotifyChangeQueueHead)
|
||||||
|
{
|
||||||
|
ListSize++;
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return this size */
|
||||||
|
*ActualNumberDriverObjects = ListSize;
|
||||||
|
|
||||||
|
/* Then, check if given buffer is big enough to contain list */
|
||||||
|
if (ListSize > DriverObjectListSize / sizeof(PDRIVER_OBJECT))
|
||||||
|
{
|
||||||
|
Status = STATUS_BUFFER_TOO_SMALL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Rebrowse the whole list */
|
||||||
|
ListEntry = IopFsNotifyChangeQueueHead.Flink;
|
||||||
|
while (ListEntry != &IopFsNotifyChangeQueueHead)
|
||||||
|
{
|
||||||
|
ChangeEntry = CONTAINING_RECORD(ListEntry,
|
||||||
|
FS_CHANGE_NOTIFY_ENTRY,
|
||||||
|
FsChangeNotifyList);
|
||||||
|
|
||||||
|
/* Reference the driver object */
|
||||||
|
ObReferenceObject(ChangeEntry->DriverObject);
|
||||||
|
/* And pass it to the caller */
|
||||||
|
DriverObjectList[Index++] = ChangeEntry->DriverObject;
|
||||||
|
|
||||||
|
/* Go to the next entry */
|
||||||
|
ListEntry = ListEntry->Flink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the FS lock */
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -669,20 +884,21 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
PIO_STACK_LOCATION StackPtr;
|
PIO_STACK_LOCATION StackPtr;
|
||||||
KEVENT Event;
|
KEVENT Event;
|
||||||
PIRP Irp;
|
PIRP Irp;
|
||||||
NTSTATUS Status = STATUS_SUCCESS, VpbStatus;
|
NTSTATUS Status, VpbStatus;
|
||||||
PDEVICE_OBJECT FileSystemDeviceObject;
|
PDEVICE_OBJECT FileSystemDeviceObject;
|
||||||
PVPB Vpb, NewVpb;
|
PVPB Vpb, NewVpb;
|
||||||
BOOLEAN WasNotMounted = TRUE;
|
BOOLEAN WasNotMounted = TRUE;
|
||||||
|
|
||||||
/* Wait on the device lock */
|
/* Wait on the device lock */
|
||||||
KeWaitForSingleObject(&DeviceObject->DeviceLock,
|
Status = KeWaitForSingleObject(&DeviceObject->DeviceLock,
|
||||||
Executive,
|
Executive,
|
||||||
KernelMode,
|
KernelMode,
|
||||||
FALSE,
|
FALSE,
|
||||||
NULL);
|
NULL);
|
||||||
|
ASSERT(Status == STATUS_SUCCESS);
|
||||||
|
|
||||||
/* Reference the VPB */
|
/* Reference the VPB */
|
||||||
if (IopReferenceVpbForVerify(DeviceObject, &FileSystemDeviceObject, &Vpb))
|
if (IopReferenceVerifyVpb(DeviceObject, &FileSystemDeviceObject, &Vpb))
|
||||||
{
|
{
|
||||||
/* Initialize the event */
|
/* Initialize the event */
|
||||||
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
KeInitializeEvent(&Event, NotificationEvent, FALSE);
|
||||||
|
@ -698,7 +914,11 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
/* Allocate the IRP */
|
/* Allocate the IRP */
|
||||||
Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
|
Irp = IoAllocateIrp(FileSystemDeviceObject->StackSize, FALSE);
|
||||||
if (!Irp) return STATUS_INSUFFICIENT_RESOURCES;
|
if (!Irp)
|
||||||
|
{
|
||||||
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
goto Release;
|
||||||
|
}
|
||||||
|
|
||||||
/* Set it up */
|
/* Set it up */
|
||||||
Irp->UserIosb = &IoStatusBlock;
|
Irp->UserIosb = &IoStatusBlock;
|
||||||
|
@ -726,28 +946,37 @@ IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dereference the VPB */
|
/* Dereference the VPB */
|
||||||
IopDereferenceVpb(Vpb);
|
IopDereferenceVpbAndFree(Vpb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check if we had the wrong volume or didn't mount at all */
|
/* Check if we had the wrong volume or didn't mount at all */
|
||||||
if ((Status == STATUS_WRONG_VOLUME) || (WasNotMounted))
|
if (Status == STATUS_WRONG_VOLUME)
|
||||||
{
|
{
|
||||||
/* Create a VPB */
|
/* Create a VPB */
|
||||||
VpbStatus = IopCreateVpb(DeviceObject);
|
VpbStatus = IopCreateVpb(DeviceObject);
|
||||||
if (NT_SUCCESS(VpbStatus))
|
if (NT_SUCCESS(VpbStatus))
|
||||||
{
|
{
|
||||||
|
PoVolumeDevice(DeviceObject);
|
||||||
|
|
||||||
/* Mount it */
|
/* Mount it */
|
||||||
VpbStatus = IopMountVolume(DeviceObject,
|
VpbStatus = IopMountVolume(DeviceObject,
|
||||||
AllowRawMount,
|
AllowRawMount,
|
||||||
TRUE,
|
TRUE,
|
||||||
FALSE,
|
FALSE,
|
||||||
&NewVpb);
|
&NewVpb);
|
||||||
|
|
||||||
|
/* If we got a new VPB, dereference it */
|
||||||
|
if (NewVpb)
|
||||||
|
{
|
||||||
|
IopInterlockedDecrementUlong(LockQueueIoVpbLock, &NewVpb->ReferenceCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we failed, remove the verify flag */
|
/* If we failed, remove the verify flag */
|
||||||
if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
|
if (!NT_SUCCESS(VpbStatus)) DeviceObject->Flags &= ~DO_VERIFY_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Release:
|
||||||
/* Signal the device lock and return */
|
/* Signal the device lock and return */
|
||||||
KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
|
KeSetEvent(&DeviceObject->DeviceLock, IO_NO_INCREMENT, FALSE);
|
||||||
return Status;
|
return Status;
|
||||||
|
@ -764,29 +993,28 @@ IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Acquire the FS lock */
|
/* Acquire the FS lock */
|
||||||
KeEnterCriticalRegion();
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
|
||||||
|
|
||||||
/* Check what kind of FS this is */
|
/* Check what kind of FS this is */
|
||||||
if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
|
if (DeviceObject->DeviceType == FILE_DEVICE_DISK_FILE_SYSTEM)
|
||||||
{
|
{
|
||||||
/* Use the disk list */
|
/* Use the disk list */
|
||||||
FsList = &IopDiskFsListHead;
|
FsList = &IopDiskFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
else if (DeviceObject->DeviceType == FILE_DEVICE_NETWORK_FILE_SYSTEM)
|
||||||
{
|
{
|
||||||
/* Use the network device list */
|
/* Use the network device list */
|
||||||
FsList = &IopNetworkFsListHead;
|
FsList = &IopNetworkFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
|
else if (DeviceObject->DeviceType == FILE_DEVICE_CD_ROM_FILE_SYSTEM)
|
||||||
{
|
{
|
||||||
/* Use the CD-ROM list */
|
/* Use the CD-ROM list */
|
||||||
FsList = &IopCdRomFsListHead;
|
FsList = &IopCdRomFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
|
else if (DeviceObject->DeviceType == FILE_DEVICE_TAPE_FILE_SYSTEM)
|
||||||
{
|
{
|
||||||
/* Use the tape list */
|
/* Use the tape list */
|
||||||
FsList = &IopTapeFsListHead;
|
FsList = &IopTapeFileSystemQueueHead;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Make sure that we have a valid list */
|
/* Make sure that we have a valid list */
|
||||||
|
@ -805,15 +1033,20 @@ IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update operations counter */
|
||||||
|
IopFsRegistrationOps++;
|
||||||
|
|
||||||
/* Clear the initializing flag */
|
/* Clear the initializing flag */
|
||||||
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
|
||||||
|
|
||||||
/* Release the FS Lock */
|
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
|
||||||
/* Notify file systems of the addition */
|
/* Notify file systems of the addition */
|
||||||
IopNotifyFileSystemChange(DeviceObject, TRUE);
|
IopNotifyFileSystemChange(DeviceObject, TRUE);
|
||||||
|
|
||||||
|
/* Release the FS Lock */
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
|
/* Ensure driver won't be unloaded */
|
||||||
|
IopInterlockedIncrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -826,18 +1059,25 @@ IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Acquire the FS lock */
|
/* Acquire the FS lock */
|
||||||
KeEnterCriticalRegion();
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
ExAcquireResourceExclusiveLite(&FileSystemListLock, TRUE);
|
|
||||||
|
|
||||||
/* Simply remove the entry */
|
/* Simply remove the entry - if queued */
|
||||||
RemoveEntryList(&DeviceObject->Queue.ListEntry);
|
if (DeviceObject->Queue.ListEntry.Flink)
|
||||||
|
{
|
||||||
|
RemoveEntryList(&DeviceObject->Queue.ListEntry);
|
||||||
|
}
|
||||||
|
|
||||||
/* And notify all registered file systems */
|
/* And notify all registered file systems */
|
||||||
IopNotifyFileSystemChange(DeviceObject, FALSE);
|
IopNotifyFileSystemChange(DeviceObject, FALSE);
|
||||||
|
|
||||||
|
/* Update operations counter */
|
||||||
|
IopFsRegistrationOps++;
|
||||||
|
|
||||||
/* Then release the lock */
|
/* Then release the lock */
|
||||||
ExReleaseResourceLite(&FileSystemListLock);
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
KeLeaveCriticalRegion();
|
|
||||||
|
/* Decrease reference count to allow unload */
|
||||||
|
IopInterlockedDecrementUlong(LockQueueIoDatabaseLock, (PULONG)&DeviceObject->ReferenceCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -846,25 +1086,60 @@ IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
IoRegisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
||||||
IN PDRIVER_FS_NOTIFICATION FSDNotificationProc)
|
IN PDRIVER_FS_NOTIFICATION DriverNotificationRoutine)
|
||||||
{
|
{
|
||||||
PFS_CHANGE_NOTIFY_ENTRY Entry;
|
PFS_CHANGE_NOTIFY_ENTRY Entry;
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
|
/* Acquire the list lock */
|
||||||
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
|
/* Check if that driver is already registered (successive calls)
|
||||||
|
* See MSDN note: http://msdn.microsoft.com/en-us/library/ff548499%28v=vs.85%29.aspx
|
||||||
|
*/
|
||||||
|
if (!IsListEmpty(&IopFsNotifyChangeQueueHead))
|
||||||
|
{
|
||||||
|
Entry = CONTAINING_RECORD(IopFsNotifyChangeQueueHead.Blink,
|
||||||
|
FS_CHANGE_NOTIFY_ENTRY,
|
||||||
|
FsChangeNotifyList);
|
||||||
|
|
||||||
|
if (Entry->DriverObject == DriverObject &&
|
||||||
|
Entry->FSDNotificationProc == DriverNotificationRoutine)
|
||||||
|
{
|
||||||
|
/* Release the lock */
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
|
return STATUS_DEVICE_ALREADY_ATTACHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Allocate a notification entry */
|
/* Allocate a notification entry */
|
||||||
Entry = ExAllocatePoolWithTag(PagedPool,
|
Entry = ExAllocatePoolWithTag(PagedPool,
|
||||||
sizeof(FS_CHANGE_NOTIFY_ENTRY),
|
sizeof(FS_CHANGE_NOTIFY_ENTRY),
|
||||||
TAG_FS_CHANGE_NOTIFY);
|
TAG_FS_CHANGE_NOTIFY);
|
||||||
if (!Entry) return(STATUS_INSUFFICIENT_RESOURCES);
|
if (!Entry)
|
||||||
|
{
|
||||||
|
/* Release the lock */
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
|
return STATUS_INSUFFICIENT_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
/* Save the driver object and notification routine */
|
/* Save the driver object and notification routine */
|
||||||
Entry->DriverObject = DriverObject;
|
Entry->DriverObject = DriverObject;
|
||||||
Entry->FSDNotificationProc = FSDNotificationProc;
|
Entry->FSDNotificationProc = DriverNotificationRoutine;
|
||||||
|
|
||||||
/* Insert it into the notification list */
|
/* Insert it into the notification list */
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
InsertTailList(&IopFsNotifyChangeQueueHead, &Entry->FsChangeNotifyList);
|
||||||
InsertTailList(&FsChangeNotifyListHead, &Entry->FsChangeNotifyList);
|
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
/* Start notifying all already present FS */
|
||||||
|
IopNotifyAlreadyRegisteredFileSystems(&IopNetworkFileSystemQueueHead, DriverNotificationRoutine, FALSE);
|
||||||
|
IopNotifyAlreadyRegisteredFileSystems(&IopCdRomFileSystemQueueHead, DriverNotificationRoutine, TRUE);
|
||||||
|
IopNotifyAlreadyRegisteredFileSystems(&IopDiskFileSystemQueueHead, DriverNotificationRoutine, TRUE);
|
||||||
|
IopNotifyAlreadyRegisteredFileSystems(&IopTapeFileSystemQueueHead, DriverNotificationRoutine, TRUE);
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
|
|
||||||
/* Reference the driver */
|
/* Reference the driver */
|
||||||
ObReferenceObject(DriverObject);
|
ObReferenceObject(DriverObject);
|
||||||
|
@ -884,11 +1159,11 @@ IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
/* Acquire the list lock */
|
/* Acquire the list lock */
|
||||||
KeAcquireGuardedMutex(&FsChangeNotifyListLock);
|
ExAcquireResourceExclusiveLite(&IopDatabaseResource, TRUE);
|
||||||
|
|
||||||
/* Loop the list */
|
/* Loop the list */
|
||||||
NextEntry = FsChangeNotifyListHead.Flink;
|
NextEntry = IopFsNotifyChangeQueueHead.Flink;
|
||||||
while (NextEntry != &FsChangeNotifyListHead)
|
while (NextEntry != &IopFsNotifyChangeQueueHead)
|
||||||
{
|
{
|
||||||
/* Get the entry */
|
/* Get the entry */
|
||||||
ChangeEntry = CONTAINING_RECORD(NextEntry,
|
ChangeEntry = CONTAINING_RECORD(NextEntry,
|
||||||
|
@ -910,7 +1185,7 @@ IoUnregisterFsRegistrationChange(IN PDRIVER_OBJECT DriverObject,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the lock and dereference the driver */
|
/* Release the lock and dereference the driver */
|
||||||
KeReleaseGuardedMutex(&FsChangeNotifyListLock);
|
ExReleaseResourceLite(&IopDatabaseResource);
|
||||||
ObDereferenceObject(DriverObject);
|
ObDereferenceObject(DriverObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue