GnomeVFSMethod->set_file_info()
authorshort <>
Mon, 3 Feb 2003 19:10:54 +0000 (19:10 +0000)
committershort <>
Mon, 3 Feb 2003 19:10:54 +0000 (19:10 +0000)
src/client/libcaptive-gnomevfs/gnome-vfs-method.c
src/libcaptive/client/file.c
src/libcaptive/include/captive/client-file.h

index 0616a6e..1e62807 100644 (file)
@@ -502,8 +502,6 @@ GnomeVFSResult captive_gnomevfs_check_same_fs(GnomeVFSMethod *method,
 GnomeVFSResult errvfsresult;
 
        g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(a!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
-       g_return_val_if_fail(b!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
        g_return_val_if_fail(same_fs_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
 
        errvfsresult=captive_gnomevfs_uri_parent_init(a);
@@ -519,6 +517,37 @@ GnomeVFSResult errvfsresult;
 }
 
 
+GnomeVFSResult captive_gnomevfs_set_file_info(GnomeVFSMethod *method,
+               GnomeVFSURI *a,const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask,GnomeVFSContext *context)
+{
+GnomeVFSResult errvfsresult;
+CaptiveFileObject *captive_file_object;
+
+       g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       errvfsresult=captive_gnomevfs_uri_parent_init(a);
+       g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
+
+       G_LOCK(libcaptive);
+       errvfsresult=captive_file_new_open(&captive_file_object,a->text,
+                       (GNOME_VFS_OPEN_WRITE | GNOME_VFS_OPEN_RANDOM));        /* mode; is it OK? */
+       G_UNLOCK(libcaptive);
+       if (errvfsresult!=GNOME_VFS_OK)
+               return errvfsresult;
+
+       G_LOCK(libcaptive);
+       errvfsresult=captive_file_file_info_set(captive_file_object,info,mask);
+       G_UNLOCK(libcaptive);
+
+       G_LOCK(libcaptive);
+       g_object_unref(captive_file_object);
+       G_UNLOCK(libcaptive);
+
+       return errvfsresult;
+}
+
+
 /**
  * captive_gnomevfs_init:
  *
@@ -552,7 +581,7 @@ GnomeVFSMethod *captive_gnomevfs_method_init(const gchar *fs_path)
        GnomeVFSMethod_static.move                     =captive_gnomevfs_move;
        GnomeVFSMethod_static.unlink                   =captive_gnomevfs_unlink;
        GnomeVFSMethod_static.check_same_fs            =captive_gnomevfs_check_same_fs;
-       /* TODO: GnomeVFSMethodSetFileInfo set_file_info; */
+       GnomeVFSMethod_static.set_file_info            =captive_gnomevfs_set_file_info;
        GnomeVFSMethod_static.truncate                 =captive_gnomevfs_truncate;
        /* TODO: GnomeVFSMethodFindDirectoryFunc find_directory; */
        /* TODO: GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; */
index 456b110..d53a164 100644 (file)
@@ -117,7 +117,7 @@ NTSTATUS err;
                        &file_Handle,   /* FileHandle */
                        0
                                        |(!(mode&GNOME_VFS_OPEN_READ ) ? 0 : FILE_READ_DATA)
-                                       |(!(mode&GNOME_VFS_OPEN_WRITE) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA)
+                                       |(!(mode&GNOME_VFS_OPEN_WRITE) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_WRITE_ATTRIBUTES)
                                        |(  mode!=0                    ? 0 : FILE_READ_ATTRIBUTES)
                                        ,       /* DesiredAccess */
                        &file_ObjectAttributes, /* ObjectAttributes */
@@ -449,7 +449,8 @@ ULONG tmp_ULONG;
 }
 
 
-GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info)
+GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object,
+               GnomeVFSFileInfo *file_info)
 {
 NTSTATUS err;
 IO_STATUS_BLOCK file_IoStatusBlock;
@@ -484,6 +485,133 @@ char QueryFile_buf[sizeof(FILE_ALL_INFORMATION)
 }
 
 
+GnomeVFSResult captive_file_file_info_set(CaptiveFileObject *captive_file_object,
+    const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask)
+{
+       g_return_val_if_fail(captive_file_object!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(captive_file_object->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       if (mask & GNOME_VFS_SET_FILE_INFO_NAME) {
+gchar *name_basename,*name_dirname;
+UNICODE_STRING *name_UnicodeString;
+FILE_RENAME_INFORMATION *FileRenameInformation_structp;
+gsize FileRenameInformation_struct_len;
+IO_STATUS_BLOCK file_IoStatusBlock;
+NTSTATUS err;
+GnomeVFSResult errvfsresult;
+
+               /* non-existing dirname assertion */
+               name_dirname=g_path_get_dirname(info->name);
+               if (strcmp(name_basename,info->name)) {
+                       g_assert_not_reached();
+                       errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS;
+                       goto err_free_name_dirname;
+                       }
+
+               /* fully-matching basename assertion */
+               name_basename=g_path_get_basename(info->name);
+               if (*name_basename) {
+                       g_assert_not_reached();
+                       errvfsresult=GNOME_VFS_ERROR_BAD_PARAMETERS;
+                       goto err_free_name_basename;
+                       }
+
+               name_UnicodeString=captive_utf8_to_UnicodeString_alloca(info->name);
+               FileRenameInformation_struct_len=sizeof(*FileRenameInformation_structp)
+                               +name_UnicodeString->MaximumLength;     /* ==Length+(0-terminator); is the terminator needed? */
+
+               FileRenameInformation_structp=g_alloca(FileRenameInformation_struct_len);
+               FileRenameInformation_structp->Replace=FALSE;
+               FileRenameInformation_structp->RootDir=NULL;    /* we do 'simple rename' here */
+               FileRenameInformation_structp->FileNameLength=name_UnicodeString->Length;
+               memcpy(FileRenameInformation_structp->FileName,name_UnicodeString->Buffer,
+                               name_UnicodeString->MaximumLength);     /* ==Length+(0-terminator); is the terminator needed? */
+
+               err=NtSetInformationFile(
+                               captive_file_object->file_Handle,       /* FileHandle */
+                               &file_IoStatusBlock,    /* IoStatusBlock */
+                               FileRenameInformation_structp,  /* FileInformation */
+                               FileRenameInformation_struct_len,       /* Length */
+                               FileRenameInformation); /* FileInformationClass */
+               if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) {
+                       g_assert_not_reached();
+                       errvfsresult=GNOME_VFS_ERROR_GENERIC;
+                       goto err_free_name_basename;
+                       }
+
+               errvfsresult=GNOME_VFS_OK;
+
+err_free_name_basename:
+               g_free(name_basename);
+err_free_name_dirname:
+               g_free(name_dirname);
+
+               if (errvfsresult!=GNOME_VFS_OK)
+                       return errvfsresult;
+               }
+
+       if (mask & (GNOME_VFS_SET_FILE_INFO_PERMISSIONS | GNOME_VFS_SET_FILE_INFO_TIME)) {
+FILE_BASIC_INFORMATION FileBasicInformation_struct;
+IO_STATUS_BLOCK file_IoStatusBlock;
+NTSTATUS err;
+
+               err=NtQueryInformationFile(
+                               captive_file_object->file_Handle,       /* FileHandle */
+                               &file_IoStatusBlock,    /* IoStatusBlock */
+                               &FileBasicInformation_struct,   /* FileInformation */
+                               sizeof(FileBasicInformation_struct),    /* Length */
+                               FileBasicInformation);  /* FileInformationClass */
+               g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+
+               if (mask & GNOME_VFS_SET_FILE_INFO_PERMISSIONS) {
+                       FileBasicInformation_struct.FileAttributes&=~FILE_ATTRIBUTE_READONLY;
+                       g_assert(info->valid_fields & GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS);
+                       if (!(info->permissions&0200))
+                               FileBasicInformation_struct.FileAttributes|=FILE_ATTRIBUTE_READONLY;
+                       }
+
+               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));
+                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_ATIME) {
+                               RtlSecondsSince1970ToTime(
+                                               info->atime,    /* SecondsSince1970 */
+                                               &FileBasicInformation_struct.LastAccessTime);   /* Time */
+                               }
+                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_MTIME) {
+                               RtlSecondsSince1970ToTime(
+                                               info->mtime,    /* SecondsSince1970 */
+                                               &FileBasicInformation_struct.LastWriteTime);    /* Time */
+                               FileBasicInformation_struct.ChangeTime=FileBasicInformation_struct.LastWriteTime;
+                               }
+                       if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_CTIME) {
+                               RtlSecondsSince1970ToTime(
+                                               info->ctime,    /* SecondsSince1970 */
+                                               &FileBasicInformation_struct.CreationTime);     /* Time */
+                               }
+                       }
+
+               err=NtSetInformationFile(
+                               captive_file_object->file_Handle,       /* FileHandle */
+                               &file_IoStatusBlock,    /* IoStatusBlock */
+                               &FileBasicInformation_struct,   /* FileInformation */
+                               sizeof(FileBasicInformation_struct),    /* Length */
+                               FileBasicInformation);  /* FileInformationClass */
+               g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+               }
+
+       if (mask & GNOME_VFS_SET_FILE_INFO_OWNER) {
+               /* FIXME: g_assert(info->valid_fields & ???); */
+               /* owner ignored for W32 */
+               }
+
+       return GNOME_VFS_OK;
+}
+
+
 GnomeVFSResult captive_file_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size)
 {
 NTSTATUS err;
index a7fd5a0..949e7db 100644 (file)
@@ -63,7 +63,10 @@ GnomeVFSResult captive_file_seek
                (CaptiveFileObject *captive_file_object,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset);
 GnomeVFSResult captive_file_tell(CaptiveFileObject *captive_file_object,GnomeVFSFileOffset *offset_return);
 GnomeVFSResult captive_file_remove(CaptiveFileObject *captive_file_object);
-GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info);
+GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object,
+               GnomeVFSFileInfo *file_info);
+GnomeVFSResult captive_file_file_info_set(CaptiveFileObject *captive_file_object,
+               const GnomeVFSFileInfo *info,GnomeVFSSetFileInfoMask mask);
 GnomeVFSResult captive_file_truncate(CaptiveFileObject *captive_file_object,GnomeVFSFileSize file_size);
 GnomeVFSResult captive_file_move(CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace);