0
|(!(mode&GNOME_VFS_OPEN_READ ) ? 0 : FILE_READ_DATA)
|(!(mode&GNOME_VFS_OPEN_WRITE) ? 0 : FILE_WRITE_DATA | FILE_APPEND_DATA)
+ |( mode!=0 ? 0 : FILE_READ_ATTRIBUTES)
, /* DesiredAccess */
&file_ObjectAttributes, /* ObjectAttributes */
&file_IoStatusBlock, /* IoStatusBlock */
return GNOME_VFS_OK;
}
+
+
+/* Use 'FileAllInformationStruct' identifier instead of the logical 'FileAllInformation'
+ * to prevent override of enum member 'FileAllInformation'
+ */
+static GnomeVFSResult FileAllInformationStruct_to_GnomeVFSFileInfo(GnomeVFSFileInfo *file_info,
+ FILE_ALL_INFORMATION *FileAllInformationStruct,IO_STATUS_BLOCK *IoStatusBlock)
+{
+UNICODE_STRING FileName_UnicodeString;
+BOOLEAN errBOOLEAN;
+ULONG tmp_ULONG;
+
+ g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_GENERIC);
+ g_return_val_if_fail(FileAllInformationStruct!=NULL,GNOME_VFS_ERROR_GENERIC);
+
+ g_return_val_if_fail(NT_SUCCESS(IoStatusBlock->Status),GNOME_VFS_ERROR_GENERIC);
+
+ file_info->valid_fields=0;
+
+ FileName_UnicodeString.Length=FileAllInformationStruct->NameInformation.FileNameLength;
+ FileName_UnicodeString.MaximumLength=FileAllInformationStruct->NameInformation.FileNameLength
+ +sizeof(*FileAllInformationStruct->NameInformation.FileName); /* 0-terminator */
+ g_assert((gpointer)(((char *)FileAllInformationStruct->NameInformation.FileName)+FileName_UnicodeString.Length)
+ <=(gpointer)(((char *)FileAllInformationStruct)+IoStatusBlock->Information));
+ /* ensure we fit below '->IoStatusBlock->Information' at least without the 0-terminator */
+ FileAllInformationStruct->NameInformation.FileName[FileAllInformationStruct->NameInformation.FileNameLength
+ /sizeof(*FileAllInformationStruct->NameInformation.FileName)]=0; /* 0-terminate it */
+ FileName_UnicodeString.Buffer=FileAllInformationStruct->NameInformation.FileName;
+ file_info->name=captive_UnicodeString_to_utf8_malloc(&FileName_UnicodeString);
+ /* '->name' assumed for 'file_info->valid_fields' */
+
+ /* FIXME: What is 'FILE_ATTRIBUTE_NORMAL'? */
+ switch (FileAllInformationStruct->BasicInformation.FileAttributes & (0
+ | FILE_ATTRIBUTE_DIRECTORY
+ | FILE_ATTRIBUTE_DEVICE)) {
+ case 0: file_info->type=GNOME_VFS_FILE_TYPE_REGULAR; break;
+ case FILE_ATTRIBUTE_DIRECTORY: file_info->type=GNOME_VFS_FILE_TYPE_DIRECTORY; break;
+ case FILE_ATTRIBUTE_DEVICE: file_info->type=GNOME_VFS_FILE_TYPE_SOCKET;
+ /* or GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE or GNOME_VFS_FILE_TYPE_BLOCK_DEVICE ? */
+ break;
+ default: file_info->type=GNOME_VFS_FILE_TYPE_UNKNOWN; break;
+ }
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE;
+
+ /* we use 0600 for r/w files, 0400 for FILE_ATTRIBUTE_READONLY */
+ file_info->permissions=GNOME_VFS_PERM_USER_READ;
+ if (file_info->type==GNOME_VFS_FILE_TYPE_DIRECTORY)
+ file_info->permissions|=GNOME_VFS_PERM_USER_EXEC;
+ if (!(FileAllInformationStruct->BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY))
+ file_info->permissions|=GNOME_VFS_PERM_USER_WRITE;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_PERMISSIONS;
+
+ file_info->size=FileAllInformationStruct->StandardInformation.EndOfFile.QuadPart;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
+
+ file_info->block_count=FileAllInformationStruct->StandardInformation.AllocationSize.QuadPart/512;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_BLOCK_COUNT;
+
+ file_info->flags=GNOME_VFS_FILE_FLAGS_LOCAL;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_FLAGS;
+
+ if (FileAllInformationStruct->BasicInformation.LastAccessTime.QuadPart) { /* it may be 0 if not set */
+ errBOOLEAN=RtlTimeToSecondsSince1970(&FileAllInformationStruct->BasicInformation.LastAccessTime,&tmp_ULONG);
+ g_assert(errBOOLEAN==TRUE);
+ file_info->atime=tmp_ULONG;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_ATIME;
+ }
+
+ /* it may be 0 if not set */
+ if (FileAllInformationStruct->BasicInformation.LastWriteTime.QuadPart || FileAllInformationStruct->BasicInformation.ChangeTime.QuadPart) {
+ errBOOLEAN=RtlTimeToSecondsSince1970(
+ /* take the more recent (==bigger) time: */
+ (FileAllInformationStruct->BasicInformation.LastWriteTime.QuadPart > FileAllInformationStruct->BasicInformation.ChangeTime.QuadPart
+ ? &FileAllInformationStruct->BasicInformation.LastWriteTime : &FileAllInformationStruct->BasicInformation.ChangeTime),
+ &tmp_ULONG);
+ g_assert(errBOOLEAN==TRUE);
+ file_info->mtime=tmp_ULONG;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_MTIME;
+ }
+
+ if (FileAllInformationStruct->BasicInformation.CreationTime.QuadPart) { /* it may be 0 if not set */
+ errBOOLEAN=RtlTimeToSecondsSince1970(&FileAllInformationStruct->BasicInformation.CreationTime,&tmp_ULONG);
+ g_assert(errBOOLEAN==TRUE);
+ file_info->ctime=tmp_ULONG;
+ file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_CTIME;
+ }
+
+ return GNOME_VFS_OK;
+}
+
+
+GnomeVFSResult captive_file_file_info_get(CaptiveFileObject *captive_file_object,GnomeVFSFileInfo *file_info)
+{
+NTSTATUS err;
+IO_STATUS_BLOCK file_IoStatusBlock;
+FILE_ALL_INFORMATION *FileAllInformationStruct;
+GnomeVFSResult errvfsresult;
+char QueryFile_buf[sizeof(FILE_ALL_INFORMATION)
+ +0x1000 /* max 'FileName' length, 255 should be enough */ * sizeof(WCHAR /* *FILE_ALL_INFORMATION.NameInformation.FileName */ )];
+
+ 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(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
+
+ /* query */
+ FileAllInformationStruct=(void *)QueryFile_buf;
+ err=NtQueryInformationFile(
+ captive_file_object->file_Handle, /* FileHandle */
+ &file_IoStatusBlock, /* IoStatusBlock */
+ (gpointer)QueryFile_buf, /* FileInformation */
+ sizeof(QueryFile_buf) /* Length */
+ -sizeof(*FileAllInformationStruct->NameInformation.FileName), /* reserve space for 0-terminator */
+ FileAllInformation); /* FileInformationClass; =>FILE_ALL_INFORMATION */
+ if (GNOME_VFS_OK!=(errvfsresult=captive_NTSTATUS_to_GnomeVFSResult(err)))
+ return errvfsresult;
+ g_return_val_if_fail(NT_SUCCESS(err),GNOME_VFS_ERROR_GENERIC);
+
+ /* process gathered info */
+ errvfsresult=FileAllInformationStruct_to_GnomeVFSFileInfo(file_info,FileAllInformationStruct,
+ &file_IoStatusBlock);
+ g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult);
+
+ return GNOME_VFS_OK;
+}