Fixed crash of directory_close() of its unreffing NULL EOF marker.
Filter-out '$'-lead filenames to ignore NTFS system directories.
Support 'GNOME_VFS_FILE_TYPE_DIRECTORY' type for file_info_get().
#include "gnome-vfs-module.h"
#include <glib/ghash.h>
#include <string.h>
#include "gnome-vfs-module.h"
#include <glib/ghash.h>
#include <string.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
#include <ntfs/volume.h>
#include <ntfs/dir.h>
#include <ntfs/volume.h>
#include <ntfs/dir.h>
mref=FILE_root;
for (;;) {
uchar_t *pathname_parse_ucs2;
mref=FILE_root;
for (;;) {
uchar_t *pathname_parse_ucs2;
+gchar *pathname_parse_unescaped;
while (*pathname_next==G_DIR_SEPARATOR)
pathname_next++;
/* FIXME: Is 'pathname' utf8? */
while (*pathname_next==G_DIR_SEPARATOR)
pathname_next++;
/* FIXME: Is 'pathname' utf8? */
- libntfs_newn(pathname_parse_ucs2,strlen(pathname_parse)+1);
- for (i=0;pathname_parse[i];i++)
- pathname_parse_ucs2[i]=pathname_parse[i];
+ pathname_parse_unescaped=gnome_vfs_unescape_string(pathname_parse,
+ NULL); /* illegal_characters */
+ libntfs_newn(pathname_parse_ucs2,strlen(pathname_parse_unescaped)+1);
+ for (i=0;pathname_parse_unescaped[i];i++)
+ pathname_parse_ucs2[i]=pathname_parse_unescaped[i];
pathname_parse_ucs2[i]=0;
pathname_parse_ucs2[i]=0;
+ g_free(pathname_parse_unescaped);
G_LOCK(libntfs);
mref=ntfs_inode_lookup_by_name(inode,pathname_parse_ucs2,i);
G_UNLOCK(libntfs);
G_LOCK(libntfs);
mref=ntfs_inode_lookup_by_name(inode,pathname_parse_ucs2,i);
G_UNLOCK(libntfs);
if (errint)
g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL);
if (errint)
g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL);
- gnome_vfs_file_info_list_free(libntfs_directory->file_info_list);
+ if (libntfs_directory->file_info_list) {
+GList *last_l;
+
+ /* Prevent gnome_vfs_file_info_list_free() and its gnome_vfs_file_info_unref()
+ * on the last 'file_info_list' items as it is EOF with NULL '->data'.
+ */
+ last_l=g_list_last(libntfs_directory->file_info_list);
+ g_assert(last_l->data==NULL);
+ libntfs_directory->file_info_list=g_list_delete_link(libntfs_directory->file_info_list,last_l);
+ gnome_vfs_file_info_list_free(libntfs_directory->file_info_list);
+ }
g_free(libntfs_directory);
g_free(libntfs_directory);
g_return_val_if_fail(name_len>=0,-1);
g_return_val_if_fail(pos>=0,-1);
g_return_val_if_fail(name_len>=0,-1);
g_return_val_if_fail(pos>=0,-1);
+ if (name_len>0 && name[0]=='$') /* system directory; FIXME: What is its proper identification? */
+ return 0; /* continue traversal */
+
file_info=gnome_vfs_file_info_new();
file_info->name=libntfs_uchar_to_utf8(name,name_len);
file_info->valid_fields=0;
file_info=gnome_vfs_file_info_new();
file_info->name=libntfs_uchar_to_utf8(name,name_len);
file_info->valid_fields=0;
g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
/* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */
g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS);
/* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */
- if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file)))
- return errvfsresult;
-
file_info->valid_fields=0;
file_info->name=NULL; /* FIXME: It is complicated to read filename of open 'ntfs_inode'. */
file_info->valid_fields=0;
file_info->name=NULL; /* FIXME: It is complicated to read filename of open 'ntfs_inode'. */
+ if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file))) {
+ /* Assume we are directory: */
+ file_info->type=GNOME_VFS_FILE_TYPE_DIRECTORY;
+ /* Do not: file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE;
+ * as gnome-vfs-xfer.c/copy_items() does not check 'GNOME_VFS_FILE_INFO_FIELDS_TYPE'
+ * and we are just bluffing we know it.
+ */
+ return GNOME_VFS_OK;
+ }
+
file_info->size=libntfs_file->attr->data_size; /* FIXME: Is 'data_size' the right field? */
file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;
file_info->size=libntfs_file->attr->data_size; /* FIXME: Is 'data_size' the right field? */
file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE;