X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Fgnome-vfs-method.c;h=0758d2eca648a234444659fd9026d735d17b306a;hb=60ee2e529c7408e07b9e3aca6d423ee2fff6a687;hp=21e97c25c2a64e19d54dbd1c00aa222df7ab09a4;hpb=2748d5f2fc00e49bf83fe9f8284f3911694ea9bd;p=ntfsprogs-gnomevfs.git diff --git a/src/gnome-vfs-method.c b/src/gnome-vfs-method.c index 21e97c2..0758d2e 100644 --- a/src/gnome-vfs-method.c +++ b/src/gnome-vfs-method.c @@ -31,6 +31,7 @@ #include "gnome-vfs-module.h" #include #include +#include #include #include @@ -182,6 +183,7 @@ int errint; mref=FILE_root; for (;;) { uchar_t *pathname_parse_ucs2; +gchar *pathname_parse_unescaped; int i; G_LOCK(libntfs); @@ -199,10 +201,13 @@ int i; 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; + g_free(pathname_parse_unescaped); G_LOCK(libntfs); mref=ntfs_inode_lookup_by_name(inode,pathname_parse_ucs2,i); G_UNLOCK(libntfs); @@ -236,8 +241,8 @@ struct libntfs_directory *libntfs_directory; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri))) + return errvfsresult; if (GNOME_VFS_OK!=(errvfsresult=inode_open_by_pathname(&inode,volume,uri->text))) return errvfsresult; @@ -267,7 +272,17 @@ int errint; 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); @@ -287,6 +302,9 @@ int i; FALSE); /* free_segment */ } +/* Do not lock 'libntfs' here as we are already locked + * inside ntfs_readdir(). + */ static int libntfs_gnomevfs_read_directory_filldir(struct libntfs_directory *libntfs_directory /* dirent */, const uchar_t *name,const int name_len,const int name_type,const s64 pos,const MFT_REF mref,const unsigned dt_type) { @@ -297,6 +315,9 @@ GnomeVFSFileInfo *file_info; 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; @@ -315,6 +336,32 @@ GnomeVFSFileInfo *file_info; if (file_info->type!=GNOME_VFS_FILE_TYPE_UNKNOWN) file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE; + /* Detect 'file_info->size': */ + if (file_info->type==GNOME_VFS_FILE_TYPE_REGULAR) { +ntfs_inode *inode; + + inode=ntfs_inode_open(libntfs_directory->inode->vol,mref); + /* FIXME: Check failed 'inode' open. */ + if (inode) { +ntfs_attr *attr; +int errint; + + attr=ntfs_attr_open( + inode, /* ni */ + AT_DATA, /* type */ + NULL, /* name */ + 0); /* name_len */ + /* FIXME: Check failed 'attr' open. */ + if (attr) { + file_info->size=attr->data_size; /* FIXME: Is 'data_size' the right field? */ + file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE; + ntfs_attr_close(attr); + } + errint=ntfs_inode_close(inode); + /* FIXME: Check 'errint'. */ + } + } + libntfs_directory->file_info_list=g_list_prepend(libntfs_directory->file_info_list,file_info); return 0; /* continue traversal */ @@ -353,6 +400,7 @@ s64 pos; if (!libntfs_directory->file_info_list->data) { g_assert(libntfs_directory->file_info_list->next==NULL); + /* Do not clear the list to leave us stuck at EOF - GnomeVFS behaves that way. */ errvfsresult=GNOME_VFS_ERROR_EOF; } else { @@ -361,10 +409,10 @@ s64 pos; file_info, /* dest */ libntfs_directory->file_info_list->data); /* src */ gnome_vfs_file_info_unref(libntfs_directory->file_info_list->data); + libntfs_directory->file_info_list=g_list_delete_link( + libntfs_directory->file_info_list,libntfs_directory->file_info_list); errvfsresult=GNOME_VFS_OK; } - libntfs_directory->file_info_list=g_list_delete_link( - libntfs_directory->file_info_list,libntfs_directory->file_info_list); return errvfsresult; } @@ -407,8 +455,8 @@ struct libntfs_file *libntfs_file; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri))) + return errvfsresult; if (mode & GNOME_VFS_OPEN_WRITE) return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; @@ -435,8 +483,8 @@ ntfs_volume *volume; g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); - errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); - g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri))) + return errvfsresult; return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; } @@ -571,12 +619,19 @@ struct libntfs_file *libntfs_file; 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'. */ + 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;