captive_file_new_internal(): Allow full READ/WRITE (+DELETE) file sharing
authorshort <>
Mon, 3 Feb 2003 14:36:19 +0000 (14:36 +0000)
committershort <>
Mon, 3 Feb 2003 14:36:19 +0000 (14:36 +0000)
+file move

src/libcaptive/client/file.c

index 7b9921f..456b110 100644 (file)
@@ -28,6 +28,9 @@
 #include "reactos/ddk/iofuncs.h"       /* for IoCreateFile() */
 #include "captive/sandbox.h"
 #include "result.h"
+#include "captive/client-directory.h"
+#include "reactos/ddk/obfuncs.h"       /* for ObReferenceObjectByHandle() */
+#include "captive/macros.h"
 
 
 static gpointer captive_file_object_parent_class=NULL;
@@ -121,7 +124,9 @@ NTSTATUS err;
                        &file_IoStatusBlock,    /* IoStatusBlock */
                        NULL,   /* AllocationSize; ignored for open */
                        (!create || create_perm&0200 ? FILE_ATTRIBUTE_NORMAL: FILE_ATTRIBUTE_READONLY), /* FileAttributes; ignored for open */
-                       (!create || !create_exclusive ? FILE_SHARE_DELETE : 0), /* ShareAccess; 0 means exclusive */
+                       (!create || !create_exclusive   /* ShareAccess; 0 means exclusive */
+                                       ? (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE)
+                                       : 0),
                        (!create ? FILE_OPEN : FILE_CREATE),    /* CreateDisposition */
                        /* FILE_SYNCHRONOUS_IO_{,NON}ALERT: We need to allow W32 filesystem
                                 * any waits to not to let it return STATUS_CANT_WAIT us.
@@ -503,3 +508,73 @@ GnomeVFSResult errvfsresult;
 
        return GNOME_VFS_OK;
 }
+
+
+GnomeVFSResult captive_file_move(CaptiveFileObject *captive_file_object_old,const gchar *pathname_new,gboolean force_replace)
+{
+NTSTATUS err;
+FILE_RENAME_INFORMATION FileRenameInformation_struct;
+IO_STATUS_BLOCK file_IoStatusBlock;
+GnomeVFSResult errvfsresult;
+gchar *pathname_new_dirname,*pathname_new_basename;
+CaptiveDirectoryObject *captive_target_directory_object;
+FILE_OBJECT *target_dir_FileObject;
+UNICODE_STRING *target_dir_FileObject_FileName_UnicodeString_local;
+
+       g_return_val_if_fail(captive_file_object_old!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(captive_file_object_old->file_Handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+       g_return_val_if_fail(pathname_new!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+       pathname_new_dirname=g_path_get_dirname(pathname_new);
+       pathname_new_basename=g_path_get_basename(pathname_new);
+
+       errvfsresult=captive_directory_new_open(&captive_target_directory_object,pathname_new_dirname);
+       if (errvfsresult!=GNOME_VFS_OK)
+               goto err_free_pathnames;
+
+       err=ObReferenceObjectByHandle(
+                       captive_target_directory_object->dir_Handle,    /* Handle */
+                       (FILE_ADD_FILE | FILE_ADD_SUBDIRECTORY),        /* DesiredAccess */
+                       IoFileObjectType,       /* ObjectType */
+                       KernelMode,     /* AccessMode */
+                       (PVOID *)&target_dir_FileObject,        /* Object */
+                       NULL);  /* HandleInfo */
+       if (!NT_SUCCESS(err)) {
+               g_assert_not_reached();
+               errvfsresult=GNOME_VFS_ERROR_GENERIC;
+               goto err_close_captive_target_directory_object;
+               }
+
+       /* Supply only the 'basename' to 'target_dir_FileObject->FileName'
+        * as the directory is fully determined by its other attributes.
+        */
+       target_dir_FileObject_FileName_UnicodeString_local=captive_utf8_to_UnicodeString_alloca(pathname_new_basename);
+       target_dir_FileObject->FileName=*target_dir_FileObject_FileName_UnicodeString_local;
+
+       ObDereferenceObject(target_dir_FileObject);
+
+       FileRenameInformation_struct.Replace=force_replace;
+       FileRenameInformation_struct.RootDir=captive_target_directory_object->dir_Handle;       /* ->'target_dir_FileObject' */
+       FileRenameInformation_struct.FileNameLength=0;  /* provided by 'FileRenameInformation_struct.RootDir' */
+
+       err=NtSetInformationFile(
+                       captive_file_object_old->file_Handle,   /* FileHandle */
+                       &file_IoStatusBlock,    /* IoStatusBlock */
+                       &FileRenameInformation_struct,  /* FileInformation */
+                       sizeof(FileRenameInformation_struct),   /* Length */
+                       FileRenameInformation); /* FileInformationClass */
+       if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err))) {
+               g_assert_not_reached();
+               errvfsresult=GNOME_VFS_ERROR_GENERIC;
+               }
+
+       /* PASSTHRU */
+
+err_close_captive_target_directory_object:
+       g_object_unref(captive_target_directory_object);
+err_free_pathnames:
+       g_free(pathname_new_dirname);
+       g_free(pathname_new_basename);
+
+       return errvfsresult;
+}