Limit maximum number of SharedCacheMap mapped objects.
[captive.git] / src / libcaptive / client / file-slave.c
index 42b17aa..8193e38 100644 (file)
 #include "captive/usecount.h"
 #include "vfs.h"
 #include "vfs-slave.h"
+#include "../cc/sharedcachemap.h"
+
+
+/* Config: */
+#define MAX_FILE_READ   0x8000000      /* FIXME: Workaround memory consumption for non-journalled fastfat.sys */
+#define MAX_FILE_WRITTEN 0x100000      /* FIXME: Workaround memory consumption for non-journalled fastfat.sys */
 
 
 struct _CaptiveFileSlaveObject {
@@ -145,6 +151,9 @@ NTSTATUS err;
        g_return_val_if_fail(captive_file_slave_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       if (captive_shared_cache_map_restart_needed())
+               return GNOME_VFS_ERROR_SERVICE_OBSOLETE;
+
        errvfsresult=captive_ObjectAttributes_init(pathname,&file_ObjectAttributes);
        g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
        
@@ -152,6 +161,7 @@ NTSTATUS err;
        err=IoCreateFile(
                        &file_Handle,   /* FileHandle */
                        0
+                                       /* sniffed: | SYNCHRONIZE       */
                                        |(!(mode&GNOME_VFS_OPEN_READ ) ? 0 : FILE_READ_DATA)
                                        |(!(mode&GNOME_VFS_OPEN_WRITE) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES)
                                        |(  mode!=0                    ? 0 : FILE_READ_ATTRIBUTES)
@@ -169,7 +179,10 @@ NTSTATUS err;
                                 * Alertability should have only effect on asynchronous events
                                 * from KeWaitForSingleObject() by setting/clearing its parameter 'Alertable'.
                                 */
-                       FILE_SYNCHRONOUS_IO_ALERT,      /* CreateOptions */
+                       FILE_SYNCHRONOUS_IO_ALERT       /* CreateOptions */
+                                       /* sniffed: | FILE_DIRECTORY_FILE */
+                                       /* sniffed: | FILE_OPEN_FOR_BACKUP_INTENT */
+                                       ,
                        NULL,   /* EaBuffer */
                        0,      /* EaLength */
                        CreateFileTypeNone,     /* CreateFileType */
@@ -290,6 +303,7 @@ NTSTATUS err;
 IO_STATUS_BLOCK file_IoStatusBlock;
 LARGE_INTEGER file_offset;
 GnomeVFSResult errvfsresult;
+static GnomeVFSFileSize total_read=0;
 
        g_return_val_if_fail(CAPTIVE_FILE_SLAVE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -300,6 +314,11 @@ GnomeVFSResult errvfsresult;
 
        g_return_val_if_fail(captive_file_slave_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       /* FIXME: Workaround memory consumption for non-journalled fastfat.sys */
+       if (total_read>=MAX_FILE_READ && captive_options->sandbox)
+               return GNOME_VFS_ERROR_SERVICE_OBSOLETE;
+       total_read+=num_bytes;
+
        file_offset.QuadPart=captive_file_slave_object->offset;
        err=NtReadFile(
                        captive_file_slave_object->file_Handle, /* FileHandle */
@@ -341,6 +360,7 @@ LARGE_INTEGER file_offset;
 GnomeVFSFileInfo file_info;
 GnomeVFSFileSize endoffile_wanted;
 GnomeVFSResult errvfsresult;
+static GnomeVFSFileSize total_written=0;
 
        g_return_val_if_fail(CAPTIVE_FILE_SLAVE_IS_OBJECT(captive_file_object),GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
@@ -351,6 +371,11 @@ GnomeVFSResult errvfsresult;
 
        g_return_val_if_fail(captive_file_slave_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
+       /* FIXME: Workaround memory consumption for non-journalled fastfat.sys */
+       if (total_written>=MAX_FILE_WRITTEN && captive_options->sandbox)
+               return GNOME_VFS_ERROR_SERVICE_OBSOLETE;
+       total_written+=num_bytes;
+
        if ((GnomeVFSFileOffset)(captive_file_slave_object->offset+num_bytes) < captive_file_slave_object->offset)
                return GNOME_VFS_ERROR_TOO_BIG;
        endoffile_wanted=captive_file_slave_object->offset+num_bytes;
@@ -381,7 +406,7 @@ GnomeVFSResult errvfsresult;
                 * really occured. We expect so and we will remount the volume.
                 */
                *bytes_written_return=0;
-               return GNOME_VFS_ERROR_LAUNCH;
+               return GNOME_VFS_ERROR_SERVICE_OBSOLETE;
                }
        g_return_val_if_fail(file_IoStatusBlock.Information==num_bytes,GNOME_VFS_ERROR_GENERIC);
 
@@ -761,8 +786,8 @@ NTSTATUS err;
                if (mask & GNOME_VFS_SET_FILE_INFO_TIME) {
                        g_assert(info->valid_fields & (0
                                        | GNOME_VFS_FILE_INFO_FIELDS_ATIME
-                                       | GNOME_VFS_FILE_INFO_FIELDS_MTIME
-                                       | GNOME_VFS_FILE_INFO_FIELDS_CTIME));
+                                       | GNOME_VFS_FILE_INFO_FIELDS_MTIME));
+                       /* !GNOME_VFS_FILE_INFO_FIELDS_CTIME is used by FUSE op_utime(). */
                        if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) {
                                RtlSecondsSince1970ToTime(
                                                info->atime,    /* SecondsSince1970 */