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);
}
+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:
*
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; */
&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 */
}
-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;
}
+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;