Integrate static packaing into the CVS HEAD; make it even default.
[captive.git] / src / libcaptive / client / init.c
index 7a963a0..9e9466c 100644 (file)
@@ -53,6 +53,8 @@
 #include <syslog.h>
 #include "captive/macros.h"
 #include "../storage/relastblock.h"    /* for captive_storage_relastblock() */
+#include "../cc/sharedcachemap.h"      /* for captive_shared_cache_map_flush_all() */
+#include "standalone.h"
 
 
 struct captive_options *captive_options;
@@ -326,16 +328,21 @@ gboolean errbool;
                        |G_LOG_LEVEL_DEBUG
                        ));
 
+       g_return_val_if_fail(captive_standalone_init_done==FALSE,FALSE);
        g_return_val_if_fail(active==FALSE,FALSE);
 
        g_return_val_if_fail(captive_options!=NULL,FALSE);
        g_return_val_if_fail(captive_options->image_iochannel!=NULL,FALSE);
 
-       /* Initialize GObject subsystem of GLib. */
-       g_type_init();
+       /* Do not: g_type_init();
+        * as it is done by: captive_standalone_init()
+        */
 
        captive_log_init(captive_options);
 
+       if (captive_options->rwmode==CAPTIVE_OPTION_RWMODE_RW && !captive_options->sandbox)
+               g_error(_("Rejecting --rw --no-sandbox operation as too dangerous - use --blind or --sandbox"));
+
        captive_image_iochannel=captive_options->image_iochannel;
        g_io_channel_ref(captive_image_iochannel);
 
@@ -365,7 +372,7 @@ gboolean errbool;
 static void dismount_volume(void)
 {
 IO_STATUS_BLOCK IoStatusBlock;
-PIO_STACK_LOCATION StackPtr;
+PEXTENDED_IO_STACK_LOCATION StackPtr;
 PIRP Irp;
 NTSTATUS Status;
 DEVICE_OBJECT *DeviceObject=captive_DriverObject.DeviceObject;
@@ -375,10 +382,26 @@ FILE_OBJECT *FileObject;
 GnomeVFSResult errvfsresult;
 NTSTATUS err;
 IO_STATUS_BLOCK dir_IoStatusBlock;
+/*
+ * 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
-static const ULONG fsctls[2]={ FSCTL_LOCK_VOLUME,FSCTL_DISMOUNT_VOLUME };
-int fsctlsi;
+       /* 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);
@@ -423,10 +446,7 @@ WCHAR wzero;
        FileObject->FileName.MaximumLength=2;
        FileObject->FileName.Buffer=&wzero;
 
-#if 0
-       for (fsctlsi=0;fsctlsi<2;fsctlsi++)
-#endif
-       {
+       for (stepi=0;stepi<STEP_MAX;stepi++) {
                Irp=IoAllocateIrp(DeviceObject->StackSize,TRUE);
                g_return_if_fail(Irp!=NULL);
 
@@ -434,26 +454,40 @@ WCHAR wzero;
                Irp->UserEvent=&FileObject->Event;
                Irp->Tail.Overlay.Thread=PsGetCurrentThread();
 
-               StackPtr=IoGetNextIrpStackLocation(Irp);
-#if 0
-               StackPtr->MajorFunction=IRP_MJ_FILE_SYSTEM_CONTROL;
-               StackPtr->MinorFunction=IRP_MN_USER_FS_REQUEST;
-#else
-               StackPtr->MajorFunction=IRP_MJ_FLUSH_BUFFERS;
+               StackPtr=(EXTENDED_IO_STACK_LOCATION *)IoGetNextIrpStackLocation(Irp);
+               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 0
-               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'.
@@ -467,7 +501,7 @@ WCHAR wzero;
                        }
                g_assert(NT_SUCCESS(Status)
                                || (Status==STATUS_MEDIA_WRITE_PROTECTED && captive_options->rwmode==CAPTIVE_OPTION_RWMODE_RO));
-       }
+               }
 
        ObDereferenceObject(FileObject);
 }
@@ -503,8 +537,14 @@ GIOStatus erriostatus;
         * replaced by IRP_MJ_FLUSH_BUFFERS.
         */
 
+       /* Probably not needed: captive_shared_cache_map_flush_all();
+        */
+
        dismount_volume();
 
+       /* 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(
                        NULL,   /* context; NULL means default one */