IoShutdownRegisteredFileSystems(): Cope with uncalled IoUnregisterFileSystem().
[reactos.git] / ntoskrnl / io / fs.c
index 26947a8..a241167 100644 (file)
@@ -174,14 +174,13 @@ IoInitFileSystemImplementation(VOID)
 #endif /* LIBCAPTIVE */
 }
 
-#ifndef LIBCAPTIVE
 
 VOID
 IoShutdownRegisteredFileSystems(VOID)
 {
    KIRQL oldlvl;
    PLIST_ENTRY current_entry;
-   FILE_SYSTEM_OBJECT* current;
+   FILE_SYSTEM_OBJECT* current,*current_last=NULL;
    PIRP Irp;
    KEVENT Event;
    IO_STATUS_BLOCK IoStatusBlock;
@@ -189,13 +188,27 @@ IoShutdownRegisteredFileSystems(VOID)
 
    DPRINT("IoShutdownRegisteredFileSystems()\n");
 
+#ifndef LIBCAPTIVE
+   /* filesystems cannot be called at DISPATCH_LEVEL */
    KeAcquireSpinLock(&FileSystemListLock,&oldlvl);
+#endif /* LIBCAPTIVE */
    KeInitializeEvent(&Event,NotificationEvent,FALSE);
 
-   current_entry = FileSystemListHead.Flink;
-   while (current_entry!=(&FileSystemListHead))
+   /* 'current' will get IoDeleteDevice()ed by IRP_MJ_SHUTDOWN! */
+   while ((current_entry = FileSystemListHead.Flink)!=(&FileSystemListHead))
      {
        current = CONTAINING_RECORD(current_entry,FILE_SYSTEM_OBJECT,Entry);
+       if (current==current_last)
+         {
+           /* At least ntfs.sys-NT5.1sp1 appears to not to unregister itself.
+            * It does not import symbol IoUnregisterFileSystem() at all!
+            * BTW also ext2fsd.sys<=v0.10A also forgets to call IoUnregisterFileSystem().
+            */
+           DPRINT("IoShutdownRegisteredFileSystems(): WARNING: filesystem forgot to call IoUnregisterFileSystem() !!!\n");
+           IoUnregisterFileSystem(current->DeviceObject);
+           continue;
+         }
+       current_last=current;
 
        /* send IRP_MJ_SHUTDOWN */
        Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SHUTDOWN,
@@ -211,14 +224,14 @@ IoShutdownRegisteredFileSystems(VOID)
          {
             KeWaitForSingleObject(&Event,Executive,KernelMode,FALSE,NULL);
          }
-
-       current_entry = current_entry->Flink;
      }
 
+#ifndef LIBCAPTIVE
+   /* filesystems cannot be called at DISPATCH_LEVEL */
    KeReleaseSpinLock(&FileSystemListLock,oldlvl);
+#endif /* LIBCAPTIVE */
 }
 
-#endif /* LIBCAPTIVE */
 
 static NTSTATUS
 IopMountFileSystem(PDEVICE_OBJECT DeviceObject,
@@ -587,7 +600,6 @@ IoRegisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
 #endif /* LIBCAPTIVE */
 }
 
-#ifndef LIBCAPTIVE
 
 VOID STDCALL
 IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
@@ -608,7 +620,9 @@ IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
          RemoveEntryList(current_entry);
          ExFreePool(current);
          KeReleaseSpinLock(&FileSystemListLock,oldlvl);
+#ifndef LIBCAPTIVE
          IopNotifyFileSystemChange(DeviceObject, FALSE);
+#endif /* LIBCAPTIVE */
          return;
        }
       current_entry = current_entry->Flink;
@@ -617,6 +631,8 @@ IoUnregisterFileSystem(IN PDEVICE_OBJECT DeviceObject)
 }
 
 
+#ifndef LIBCAPTIVE
+
 /**********************************************************************
  * NAME                                                        EXPORTED
  *     IoGetBaseFileSystemDeviceObject@4