From: short <> Date: Sat, 6 Dec 2003 19:09:10 +0000 (+0000) Subject: Prevent 'FSCTL_LOCK_VOLUME' for dismount as we may get 'STATUS_ACCESS_DENIED'. X-Git-Tag: captive-1_1_3~7 X-Git-Url: http://git.jankratochvil.net/?p=captive.git;a=commitdiff_plain;h=64f0e1ef4bd10f61d2fc0902ef4555481b981c1b Prevent 'FSCTL_LOCK_VOLUME' for dismount as we may get 'STATUS_ACCESS_DENIED'. --- diff --git a/src/libcaptive/client/init.c b/src/libcaptive/client/init.c index 781437d..f3c35c9 100644 --- a/src/libcaptive/client/init.c +++ b/src/libcaptive/client/init.c @@ -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;stepiStackSize,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(