+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;
+}
+
+