#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;
&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.
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;
+}