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);
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);
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'.
}
g_assert(NT_SUCCESS(Status)
|| (Status==STATUS_MEDIA_WRITE_PROTECTED && captive_options->rwmode==CAPTIVE_OPTION_RWMODE_RO));
- }
+ }
ObDereferenceObject(FileObject);
}
* 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(