Prevent 'FSCTL_LOCK_VOLUME' for dismount as we may get 'STATUS_ACCESS_DENIED'.
authorshort <>
Sat, 6 Dec 2003 19:09:10 +0000 (19:09 +0000)
committershort <>
Sat, 6 Dec 2003 19:09:10 +0000 (19:09 +0000)
src/libcaptive/client/init.c

index 781437d..f3c35c9 100644 (file)
@@ -376,8 +376,26 @@ FILE_OBJECT *FileObject;
 GnomeVFSResult errvfsresult;
 NTSTATUS err;
 IO_STATUS_BLOCK dir_IoStatusBlock;
-static const ULONG fsctls[2]={ FSCTL_LOCK_VOLUME,FSCTL_DISMOUNT_VOLUME };
-int fsctlsi;
+/*
+ * TraceFS reported only IRP_MJ_FLUSH_BUFFERS
+ * and IRP_MJ_SHUTDOWN.
+ * Apparently it is not enough, FSCTL_DISMOUNT_VOLUME is needed,
+ * otherwise NT-5.1 autochkdsks the disk and W2000 may give BSOD during boot.
+ */
+enum step {
+       /* First item value assumed to be 0. */
+       STEP_IRP_MJ_FLUSH_BUFFERS_PRE,
+#if 0
+       /* DISABLED: STATUS_ACCESS_DENIED; FIXME: Why?
+        * The official way of device modification is: LOCK,DISMOUNT
+        * but LOCK fails for Captive if any file was written (and closed).
+        */
+       STEP_FSCTL_LOCK_VOLUME,
+#endif
+       STEP_FSCTL_DISMOUNT_VOLUME,
+       STEP_IRP_MJ_FLUSH_BUFFERS_POST,
+       STEP_MAX=3,
+       } stepi;
 WCHAR wzero;
 
        errvfsresult=captive_ObjectAttributes_init("/!Captive!del",&dir_ObjectAttributes);
@@ -422,7 +440,7 @@ WCHAR wzero;
        FileObject->FileName.MaximumLength=2;
        FileObject->FileName.Buffer=&wzero;
 
-       for (fsctlsi=0;fsctlsi<2;fsctlsi++) {
+       for (stepi=0;stepi<STEP_MAX;stepi++) {
                Irp=IoAllocateIrp(DeviceObject->StackSize,TRUE);
                g_return_if_fail(Irp!=NULL);
 
@@ -431,25 +449,39 @@ WCHAR wzero;
                Irp->Tail.Overlay.Thread=PsGetCurrentThread();
 
                StackPtr=(EXTENDED_IO_STACK_LOCATION *)IoGetNextIrpStackLocation(Irp);
-#if 1
-               StackPtr->MajorFunction=IRP_MJ_FILE_SYSTEM_CONTROL;
-               StackPtr->MinorFunction=IRP_MN_USER_FS_REQUEST;
-#else
-               StackPtr->MajorFunction=IRP_MJ_FLUSH_BUFFERS;
+               switch (stepi) {
+                       case STEP_IRP_MJ_FLUSH_BUFFERS_PRE:
+                               StackPtr->MajorFunction=IRP_MJ_FLUSH_BUFFERS;
+                               break;
+#if 0  /* Disabled, see 'STEP_FSCTL_LOCK_VOLUME'. */
+                       case STEP_FSCTL_LOCK_VOLUME:
+                               StackPtr->MajorFunction=IRP_MJ_FILE_SYSTEM_CONTROL;
+                               StackPtr->MinorFunction=IRP_MN_USER_FS_REQUEST;
+                               StackPtr->Parameters.FileSystemControl.OutputBufferLength=0;
+                               StackPtr->Parameters.FileSystemControl.InputBufferLength=0;
+                               StackPtr->Parameters.FileSystemControl.FsControlCode=FSCTL_LOCK_VOLUME;
+                               StackPtr->Parameters.FileSystemControl.Type3InputBuffer=NULL;
+                               break;
 #endif
+                       case STEP_FSCTL_DISMOUNT_VOLUME:
+                               StackPtr->MajorFunction=IRP_MJ_FILE_SYSTEM_CONTROL;
+                               StackPtr->MinorFunction=IRP_MN_USER_FS_REQUEST;
+                               StackPtr->Parameters.FileSystemControl.OutputBufferLength=0;
+                               StackPtr->Parameters.FileSystemControl.InputBufferLength=0;
+                               StackPtr->Parameters.FileSystemControl.FsControlCode=FSCTL_DISMOUNT_VOLUME;
+                               StackPtr->Parameters.FileSystemControl.Type3InputBuffer=NULL;
+                               break;
+                       case STEP_IRP_MJ_FLUSH_BUFFERS_POST:
+                               StackPtr->MajorFunction=IRP_MJ_FLUSH_BUFFERS;
+                               break;
+                       default: g_assert_not_reached();
+                       }
                StackPtr->Flags=0;
                StackPtr->Control=0;
                StackPtr->DeviceObject=DeviceObject;    /* FIXME: FileObject->Vpb->DeviceObject ? */
                StackPtr->FileObject=FileObject;
                StackPtr->CompletionRoutine=NULL;
 
-#if 1
-               StackPtr->Parameters.FileSystemControl.OutputBufferLength=0;
-               StackPtr->Parameters.FileSystemControl.InputBufferLength=0;
-               StackPtr->Parameters.FileSystemControl.FsControlCode=fsctls[fsctlsi];
-               StackPtr->Parameters.FileSystemControl.Type3InputBuffer=NULL;
-#endif
-
                /* IoCallDriver() will do one ObDereferenceObject(FileObject)
                 * in its IoSecondStageCompletion().
                 * Do not leave to dereference it itself as we need its 'FileObject->Event'.
@@ -463,7 +495,7 @@ WCHAR wzero;
                        }
                g_assert(NT_SUCCESS(Status)
                                || (Status==STATUS_MEDIA_WRITE_PROTECTED && captive_options->rwmode==CAPTIVE_OPTION_RWMODE_RO));
-       }
+               }
 
        ObDereferenceObject(FileObject);
 }
@@ -499,15 +531,13 @@ GIOStatus erriostatus;
         * replaced by IRP_MJ_FLUSH_BUFFERS.
         */
 
-#if 0
-       captive_shared_cache_map_flush_all();
-#endif
+       /* Probably not needed: captive_shared_cache_map_flush_all();
+        */
 
        dismount_volume();
 
-#if 0
-       captive_shared_cache_map_flush_all();
-#endif
+       /* Probably not needed: captive_shared_cache_map_flush_all();
+        */
 
        /* Invoke all pending idle functions just to not to forget for anything... */
        while (g_main_context_iteration(