1*9663SMark.Logan@Sun.COM /* 2*9663SMark.Logan@Sun.COM * gnome-vfs-method.c - Gnome-VFS init/shutdown implementation of interface to 3*9663SMark.Logan@Sun.COM * libntfs. Part of the Linux-NTFS project. 4*9663SMark.Logan@Sun.COM * 5*9663SMark.Logan@Sun.COM * Copyright (c) 2003 Jan Kratochvil <project-captive@jankratochvil.net> 6*9663SMark.Logan@Sun.COM * Copyright (c) 2003-2006 Anton Altaparmakov 7*9663SMark.Logan@Sun.COM * 8*9663SMark.Logan@Sun.COM * This program/include file is free software; you can redistribute it and/or 9*9663SMark.Logan@Sun.COM * modify it under the terms of the GNU General Public License as published 10*9663SMark.Logan@Sun.COM * by the Free Software Foundation; either version 2 of the License, or 11*9663SMark.Logan@Sun.COM * (at your option) any later version. 12*9663SMark.Logan@Sun.COM * 13*9663SMark.Logan@Sun.COM * This program/include file is distributed in the hope that it will be 14*9663SMark.Logan@Sun.COM * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 15*9663SMark.Logan@Sun.COM * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16*9663SMark.Logan@Sun.COM * GNU General Public License for more details. 17*9663SMark.Logan@Sun.COM * 18*9663SMark.Logan@Sun.COM * You should have received a copy of the GNU General Public License 19*9663SMark.Logan@Sun.COM * along with this program (in the main directory of the Linux-NTFS 20*9663SMark.Logan@Sun.COM * distribution in the file COPYING); if not, write to the Free Software 21*9663SMark.Logan@Sun.COM * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22*9663SMark.Logan@Sun.COM */ 23*9663SMark.Logan@Sun.COM 24*9663SMark.Logan@Sun.COM #include "config.h" 25*9663SMark.Logan@Sun.COM 26*9663SMark.Logan@Sun.COM #undef FALSE 27*9663SMark.Logan@Sun.COM #undef TRUE 28*9663SMark.Logan@Sun.COM #include "types.h" /* for 'FALSE'/'TRUE' libntfs definition */ 29*9663SMark.Logan@Sun.COM #define FALSE FALSE 30*9663SMark.Logan@Sun.COM #define TRUE TRUE 31*9663SMark.Logan@Sun.COM 32*9663SMark.Logan@Sun.COM #include "gnome-vfs-method.h" /* self */ 33*9663SMark.Logan@Sun.COM #include <libgnomevfs/gnome-vfs-method.h> 34*9663SMark.Logan@Sun.COM #include <glib/gmessages.h> 35*9663SMark.Logan@Sun.COM #include "gnome-vfs-module.h" 36*9663SMark.Logan@Sun.COM #include <glib/ghash.h> 37*9663SMark.Logan@Sun.COM #ifdef HAVE_STRING_H 38*9663SMark.Logan@Sun.COM #include <string.h> 39*9663SMark.Logan@Sun.COM #endif 40*9663SMark.Logan@Sun.COM #include <libgnomevfs/gnome-vfs-utils.h> 41*9663SMark.Logan@Sun.COM 42*9663SMark.Logan@Sun.COM #include "volume.h" 43*9663SMark.Logan@Sun.COM #include "dir.h" 44*9663SMark.Logan@Sun.COM 45*9663SMark.Logan@Sun.COM static GnomeVFSMethod GnomeVFSMethod_static; 46*9663SMark.Logan@Sun.COM G_LOCK_DEFINE_STATIC(GnomeVFSMethod_static); 47*9663SMark.Logan@Sun.COM 48*9663SMark.Logan@Sun.COM /* map: (gchar *)method_name -> (struct method_name_info *) */ 49*9663SMark.Logan@Sun.COM static GHashTable *method_name_hash; 50*9663SMark.Logan@Sun.COM G_LOCK_DEFINE_STATIC(method_name_hash); 51*9663SMark.Logan@Sun.COM 52*9663SMark.Logan@Sun.COM #ifdef __sun 53*9663SMark.Logan@Sun.COM G_LOCK_DEFINE(libntfs); 54*9663SMark.Logan@Sun.COM #endif 55*9663SMark.Logan@Sun.COM 56*9663SMark.Logan@Sun.COM struct method_name_info { 57*9663SMark.Logan@Sun.COM gchar *args; 58*9663SMark.Logan@Sun.COM }; 59*9663SMark.Logan@Sun.COM 60*9663SMark.Logan@Sun.COM static void method_name_hash_key_destroy_func(gchar *key) 61*9663SMark.Logan@Sun.COM { 62*9663SMark.Logan@Sun.COM g_return_if_fail(key != NULL); 63*9663SMark.Logan@Sun.COM 64*9663SMark.Logan@Sun.COM g_free(key); 65*9663SMark.Logan@Sun.COM } 66*9663SMark.Logan@Sun.COM 67*9663SMark.Logan@Sun.COM static void method_name_hash_value_destroy_func(struct method_name_info *value) 68*9663SMark.Logan@Sun.COM { 69*9663SMark.Logan@Sun.COM g_return_if_fail(value != NULL); 70*9663SMark.Logan@Sun.COM 71*9663SMark.Logan@Sun.COM g_free(value->args); 72*9663SMark.Logan@Sun.COM g_free(value); 73*9663SMark.Logan@Sun.COM } 74*9663SMark.Logan@Sun.COM 75*9663SMark.Logan@Sun.COM static void method_name_hash_init(void) 76*9663SMark.Logan@Sun.COM { 77*9663SMark.Logan@Sun.COM G_LOCK(method_name_hash); 78*9663SMark.Logan@Sun.COM if (!method_name_hash) { 79*9663SMark.Logan@Sun.COM method_name_hash = g_hash_table_new_full( 80*9663SMark.Logan@Sun.COM g_str_hash, /* hash_func */ 81*9663SMark.Logan@Sun.COM g_str_equal, /* key_equal_func */ 82*9663SMark.Logan@Sun.COM (GDestroyNotify) method_name_hash_key_destroy_func, /* key_destroy_func */ 83*9663SMark.Logan@Sun.COM (GDestroyNotify) method_name_hash_value_destroy_func); /* value_destroy_func */ 84*9663SMark.Logan@Sun.COM } 85*9663SMark.Logan@Sun.COM G_UNLOCK(method_name_hash); 86*9663SMark.Logan@Sun.COM } 87*9663SMark.Logan@Sun.COM 88*9663SMark.Logan@Sun.COM /* 89*9663SMark.Logan@Sun.COM * map: (gchar *)uri_parent_string "method_name:uri_parent" -> (ntfs_volume *) 90*9663SMark.Logan@Sun.COM */ 91*9663SMark.Logan@Sun.COM static GHashTable *uri_parent_string_hash; 92*9663SMark.Logan@Sun.COM G_LOCK_DEFINE_STATIC(uri_parent_string_hash); 93*9663SMark.Logan@Sun.COM 94*9663SMark.Logan@Sun.COM static void uri_parent_string_hash_key_destroy_func(gchar *key) 95*9663SMark.Logan@Sun.COM { 96*9663SMark.Logan@Sun.COM g_return_if_fail(key != NULL); 97*9663SMark.Logan@Sun.COM 98*9663SMark.Logan@Sun.COM g_free(key); 99*9663SMark.Logan@Sun.COM } 100*9663SMark.Logan@Sun.COM 101*9663SMark.Logan@Sun.COM static void uri_parent_string_hash_value_destroy_func(ntfs_volume *value) 102*9663SMark.Logan@Sun.COM { 103*9663SMark.Logan@Sun.COM g_return_if_fail(value != NULL); 104*9663SMark.Logan@Sun.COM 105*9663SMark.Logan@Sun.COM ntfs_umount( /* errors ignored */ 106*9663SMark.Logan@Sun.COM value, /* vol */ 107*9663SMark.Logan@Sun.COM TRUE); /* force; possibly loose modifications */ 108*9663SMark.Logan@Sun.COM } 109*9663SMark.Logan@Sun.COM 110*9663SMark.Logan@Sun.COM static void uri_parent_string_hash_init(void) 111*9663SMark.Logan@Sun.COM { 112*9663SMark.Logan@Sun.COM G_LOCK(uri_parent_string_hash); 113*9663SMark.Logan@Sun.COM if (!uri_parent_string_hash) { 114*9663SMark.Logan@Sun.COM uri_parent_string_hash = g_hash_table_new_full( 115*9663SMark.Logan@Sun.COM g_str_hash, /* hash_func */ 116*9663SMark.Logan@Sun.COM g_str_equal, /* key_equal_func */ 117*9663SMark.Logan@Sun.COM (GDestroyNotify) uri_parent_string_hash_key_destroy_func, /* key_destroy_func */ 118*9663SMark.Logan@Sun.COM (GDestroyNotify) uri_parent_string_hash_value_destroy_func); /* value_destroy_func */ 119*9663SMark.Logan@Sun.COM } 120*9663SMark.Logan@Sun.COM G_UNLOCK(uri_parent_string_hash); 121*9663SMark.Logan@Sun.COM } 122*9663SMark.Logan@Sun.COM 123*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_uri_parent_init( 124*9663SMark.Logan@Sun.COM ntfs_volume **volume_return, GnomeVFSURI *uri) 125*9663SMark.Logan@Sun.COM { 126*9663SMark.Logan@Sun.COM gchar *uri_parent_string; 127*9663SMark.Logan@Sun.COM gchar *uri_parent_string_parent; 128*9663SMark.Logan@Sun.COM ntfs_volume *volume; 129*9663SMark.Logan@Sun.COM 130*9663SMark.Logan@Sun.COM g_return_val_if_fail(uri != NULL, GNOME_VFS_ERROR_INVALID_URI); 131*9663SMark.Logan@Sun.COM g_return_val_if_fail(volume_return != NULL, 132*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 133*9663SMark.Logan@Sun.COM 134*9663SMark.Logan@Sun.COM uri_parent_string_hash_init(); 135*9663SMark.Logan@Sun.COM 136*9663SMark.Logan@Sun.COM if (!uri->parent) 137*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_INVALID_URI; 138*9663SMark.Logan@Sun.COM if (!uri->text) /* not needed here but we don't permit non-specific fs-image reference */ 139*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_INVALID_URI; 140*9663SMark.Logan@Sun.COM uri_parent_string_parent = gnome_vfs_uri_to_string(uri->parent, 141*9663SMark.Logan@Sun.COM GNOME_VFS_URI_HIDE_NONE); 142*9663SMark.Logan@Sun.COM g_assert(uri_parent_string_parent != NULL); 143*9663SMark.Logan@Sun.COM 144*9663SMark.Logan@Sun.COM uri_parent_string = g_strdup_printf("%s:%s", uri->method_string, 145*9663SMark.Logan@Sun.COM uri_parent_string_parent); 146*9663SMark.Logan@Sun.COM g_assert(uri_parent_string != NULL); 147*9663SMark.Logan@Sun.COM 148*9663SMark.Logan@Sun.COM G_LOCK(uri_parent_string_hash); 149*9663SMark.Logan@Sun.COM volume = g_hash_table_lookup(uri_parent_string_hash, uri_parent_string); 150*9663SMark.Logan@Sun.COM G_UNLOCK(uri_parent_string_hash); 151*9663SMark.Logan@Sun.COM if (!volume) { 152*9663SMark.Logan@Sun.COM struct method_name_info *method_name_info; 153*9663SMark.Logan@Sun.COM 154*9663SMark.Logan@Sun.COM G_LOCK(method_name_hash); 155*9663SMark.Logan@Sun.COM method_name_info = g_hash_table_lookup(method_name_hash, 156*9663SMark.Logan@Sun.COM uri->method_string); 157*9663SMark.Logan@Sun.COM G_UNLOCK(method_name_hash); 158*9663SMark.Logan@Sun.COM if (!method_name_info) { 159*9663SMark.Logan@Sun.COM /* should not happend */ 160*9663SMark.Logan@Sun.COM g_return_val_if_reached(GNOME_VFS_ERROR_INVALID_URI); 161*9663SMark.Logan@Sun.COM } 162*9663SMark.Logan@Sun.COM 163*9663SMark.Logan@Sun.COM /* TODO: Generic GnomeVFS filter. */ 164*9663SMark.Logan@Sun.COM if (strcmp(uri->parent->method_string, "file")) { 165*9663SMark.Logan@Sun.COM g_free(uri_parent_string); 166*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_INVALID_URI; 167*9663SMark.Logan@Sun.COM } 168*9663SMark.Logan@Sun.COM 169*9663SMark.Logan@Sun.COM if (!(volume = ntfs_mount(uri->parent->text, 170*9663SMark.Logan@Sun.COM NTFS_MNT_RDONLY))) { 171*9663SMark.Logan@Sun.COM g_free(uri_parent_string); 172*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_WRONG_FORMAT; 173*9663SMark.Logan@Sun.COM } 174*9663SMark.Logan@Sun.COM 175*9663SMark.Logan@Sun.COM G_LOCK(uri_parent_string_hash); 176*9663SMark.Logan@Sun.COM g_hash_table_insert(uri_parent_string_hash, 177*9663SMark.Logan@Sun.COM g_strdup(uri_parent_string), volume); 178*9663SMark.Logan@Sun.COM G_UNLOCK(uri_parent_string_hash); 179*9663SMark.Logan@Sun.COM } 180*9663SMark.Logan@Sun.COM g_free(uri_parent_string); 181*9663SMark.Logan@Sun.COM 182*9663SMark.Logan@Sun.COM *volume_return = volume; 183*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 184*9663SMark.Logan@Sun.COM } 185*9663SMark.Logan@Sun.COM 186*9663SMark.Logan@Sun.COM static GnomeVFSResult inode_open_by_pathname(ntfs_inode **inode_return, 187*9663SMark.Logan@Sun.COM ntfs_volume *volume, const gchar *pathname) 188*9663SMark.Logan@Sun.COM { 189*9663SMark.Logan@Sun.COM MFT_REF mref; 190*9663SMark.Logan@Sun.COM ntfs_inode *inode; 191*9663SMark.Logan@Sun.COM gchar *pathname_parse, *pathname_next; 192*9663SMark.Logan@Sun.COM int errint; 193*9663SMark.Logan@Sun.COM 194*9663SMark.Logan@Sun.COM g_return_val_if_fail(inode_return != NULL, 195*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 196*9663SMark.Logan@Sun.COM g_return_val_if_fail(volume != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 197*9663SMark.Logan@Sun.COM g_return_val_if_fail(pathname != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 198*9663SMark.Logan@Sun.COM 199*9663SMark.Logan@Sun.COM pathname = g_path_skip_root(pathname); 200*9663SMark.Logan@Sun.COM pathname_parse = g_alloca(strlen(pathname) + 1); 201*9663SMark.Logan@Sun.COM strcpy(pathname_parse, pathname); 202*9663SMark.Logan@Sun.COM mref = FILE_root; 203*9663SMark.Logan@Sun.COM for (;;) { 204*9663SMark.Logan@Sun.COM ntfschar *pathname_parse_ucs2; 205*9663SMark.Logan@Sun.COM gchar *pathname_parse_unescaped; 206*9663SMark.Logan@Sun.COM int i; 207*9663SMark.Logan@Sun.COM 208*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 209*9663SMark.Logan@Sun.COM inode = ntfs_inode_open(volume, mref); 210*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 211*9663SMark.Logan@Sun.COM if (!inode) 212*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_NOT_FOUND; 213*9663SMark.Logan@Sun.COM if (!*pathname_parse) { 214*9663SMark.Logan@Sun.COM *inode_return = inode; 215*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 216*9663SMark.Logan@Sun.COM } 217*9663SMark.Logan@Sun.COM for (pathname_next = pathname_parse; *pathname_next && 218*9663SMark.Logan@Sun.COM *pathname_next != G_DIR_SEPARATOR; pathname_next++) ; 219*9663SMark.Logan@Sun.COM if (*pathname_next) { 220*9663SMark.Logan@Sun.COM /* terminate current path element */ 221*9663SMark.Logan@Sun.COM *pathname_next++ = 0; 222*9663SMark.Logan@Sun.COM } 223*9663SMark.Logan@Sun.COM while (*pathname_next == G_DIR_SEPARATOR) 224*9663SMark.Logan@Sun.COM pathname_next++; 225*9663SMark.Logan@Sun.COM /* FIXME: Is 'pathname' utf8? */ 226*9663SMark.Logan@Sun.COM pathname_parse_unescaped = gnome_vfs_unescape_string( 227*9663SMark.Logan@Sun.COM pathname_parse, NULL); /* illegal_characters */ 228*9663SMark.Logan@Sun.COM #ifdef __sun 229*9663SMark.Logan@Sun.COM pathname_parse_ucs2 = g_malloc(strlen(pathname_parse_unescaped) + 1); 230*9663SMark.Logan@Sun.COM #else /* !__sun */ 231*9663SMark.Logan@Sun.COM libntfs_newn(pathname_parse_ucs2, 232*9663SMark.Logan@Sun.COM strlen(pathname_parse_unescaped) + 1); 233*9663SMark.Logan@Sun.COM #endif /* __sun */ 234*9663SMark.Logan@Sun.COM for (i = 0; pathname_parse_unescaped[i]; i++) 235*9663SMark.Logan@Sun.COM pathname_parse_ucs2[i] = cpu_to_le16( 236*9663SMark.Logan@Sun.COM pathname_parse_unescaped[i]); 237*9663SMark.Logan@Sun.COM pathname_parse_ucs2[i] = 0; 238*9663SMark.Logan@Sun.COM g_free(pathname_parse_unescaped); 239*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 240*9663SMark.Logan@Sun.COM mref = ntfs_inode_lookup_by_name(inode, pathname_parse_ucs2, i); 241*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 242*9663SMark.Logan@Sun.COM g_free(pathname_parse_ucs2); 243*9663SMark.Logan@Sun.COM if ((MFT_REF)-1 == mref) 244*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_NOT_FOUND; 245*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 246*9663SMark.Logan@Sun.COM errint = ntfs_inode_close(inode); 247*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 248*9663SMark.Logan@Sun.COM if (errint) 249*9663SMark.Logan@Sun.COM g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); 250*9663SMark.Logan@Sun.COM pathname_parse = pathname_next; 251*9663SMark.Logan@Sun.COM } 252*9663SMark.Logan@Sun.COM /* NOTREACHED */ 253*9663SMark.Logan@Sun.COM } 254*9663SMark.Logan@Sun.COM 255*9663SMark.Logan@Sun.COM struct libntfs_directory { 256*9663SMark.Logan@Sun.COM ntfs_inode *inode; 257*9663SMark.Logan@Sun.COM GList *file_info_list; /* of (GnomeVFSFileInfo *); last item has ->data == NULL */ 258*9663SMark.Logan@Sun.COM }; 259*9663SMark.Logan@Sun.COM 260*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_open_directory(GnomeVFSMethod *method, 261*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle **method_handle, GnomeVFSURI *uri, 262*9663SMark.Logan@Sun.COM GnomeVFSFileInfoOptions options __attribute__((unused)), 263*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 264*9663SMark.Logan@Sun.COM { 265*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 266*9663SMark.Logan@Sun.COM ntfs_volume *volume; 267*9663SMark.Logan@Sun.COM ntfs_inode *inode; 268*9663SMark.Logan@Sun.COM struct libntfs_directory *libntfs_directory; 269*9663SMark.Logan@Sun.COM 270*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 271*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 272*9663SMark.Logan@Sun.COM g_return_val_if_fail(method_handle != NULL, 273*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 274*9663SMark.Logan@Sun.COM 275*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 276*9663SMark.Logan@Sun.COM libntfs_gnomevfs_uri_parent_init(&volume, uri))) 277*9663SMark.Logan@Sun.COM return errvfsresult; 278*9663SMark.Logan@Sun.COM 279*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = inode_open_by_pathname(&inode, 280*9663SMark.Logan@Sun.COM volume, uri->text))) 281*9663SMark.Logan@Sun.COM return errvfsresult; 282*9663SMark.Logan@Sun.COM 283*9663SMark.Logan@Sun.COM #ifdef __sun 284*9663SMark.Logan@Sun.COM libntfs_directory = g_new(struct libntfs_directory, 1); 285*9663SMark.Logan@Sun.COM #else /* !__sun */ 286*9663SMark.Logan@Sun.COM libntfs_new(libntfs_directory); 287*9663SMark.Logan@Sun.COM #endif /* __sun */ 288*9663SMark.Logan@Sun.COM 289*9663SMark.Logan@Sun.COM libntfs_directory->inode = inode; 290*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = NULL; 291*9663SMark.Logan@Sun.COM 292*9663SMark.Logan@Sun.COM *method_handle = (GnomeVFSMethodHandle *)libntfs_directory; 293*9663SMark.Logan@Sun.COM return errvfsresult; 294*9663SMark.Logan@Sun.COM } 295*9663SMark.Logan@Sun.COM 296*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_close_directory(GnomeVFSMethod *method, 297*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, 298*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 299*9663SMark.Logan@Sun.COM { 300*9663SMark.Logan@Sun.COM struct libntfs_directory *libntfs_directory; 301*9663SMark.Logan@Sun.COM int errint; 302*9663SMark.Logan@Sun.COM 303*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 304*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 305*9663SMark.Logan@Sun.COM libntfs_directory = (struct libntfs_directory *)method_handle; 306*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_directory != NULL, 307*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 308*9663SMark.Logan@Sun.COM 309*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 310*9663SMark.Logan@Sun.COM errint = ntfs_inode_close(libntfs_directory->inode); 311*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 312*9663SMark.Logan@Sun.COM if (errint) 313*9663SMark.Logan@Sun.COM g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); 314*9663SMark.Logan@Sun.COM 315*9663SMark.Logan@Sun.COM if (libntfs_directory->file_info_list) { 316*9663SMark.Logan@Sun.COM GList *last_l; 317*9663SMark.Logan@Sun.COM 318*9663SMark.Logan@Sun.COM /* 319*9663SMark.Logan@Sun.COM * Prevent gnome_vfs_file_info_list_free() and its 320*9663SMark.Logan@Sun.COM * gnome_vfs_file_info_unref() on the last 'file_info_list' 321*9663SMark.Logan@Sun.COM * items as it is EOF with NULL '->data'. 322*9663SMark.Logan@Sun.COM */ 323*9663SMark.Logan@Sun.COM last_l = g_list_last(libntfs_directory->file_info_list); 324*9663SMark.Logan@Sun.COM g_assert(last_l->data == NULL); 325*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = g_list_delete_link( 326*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list, last_l); 327*9663SMark.Logan@Sun.COM gnome_vfs_file_info_list_free( 328*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list); 329*9663SMark.Logan@Sun.COM } 330*9663SMark.Logan@Sun.COM 331*9663SMark.Logan@Sun.COM g_free(libntfs_directory); 332*9663SMark.Logan@Sun.COM 333*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 334*9663SMark.Logan@Sun.COM } 335*9663SMark.Logan@Sun.COM 336*9663SMark.Logan@Sun.COM static gchar *libntfs_ntfscharo_utf8(const ntfschar *name, const int name_len) 337*9663SMark.Logan@Sun.COM { 338*9663SMark.Logan@Sun.COM GString *gstring; 339*9663SMark.Logan@Sun.COM int i; 340*9663SMark.Logan@Sun.COM 341*9663SMark.Logan@Sun.COM gstring = g_string_sized_new(name_len); 342*9663SMark.Logan@Sun.COM for (i = 0; i < name_len; i++) 343*9663SMark.Logan@Sun.COM gstring = g_string_append_unichar(gstring, 344*9663SMark.Logan@Sun.COM le16_to_cpu(name[i])); 345*9663SMark.Logan@Sun.COM return g_string_free(gstring, /* returns utf8-formatted string */ 346*9663SMark.Logan@Sun.COM FALSE); /* free_segment */ 347*9663SMark.Logan@Sun.COM } 348*9663SMark.Logan@Sun.COM 349*9663SMark.Logan@Sun.COM /* 350*9663SMark.Logan@Sun.COM * Do not lock 'libntfs' here as we are already locked inside ntfs_readdir(). 351*9663SMark.Logan@Sun.COM */ 352*9663SMark.Logan@Sun.COM static int libntfs_gnomevfs_read_directory_filldir( 353*9663SMark.Logan@Sun.COM struct libntfs_directory *libntfs_directory /* dirent */, 354*9663SMark.Logan@Sun.COM const ntfschar *name, const int name_len, 355*9663SMark.Logan@Sun.COM const int name_type __attribute__((unused)), 356*9663SMark.Logan@Sun.COM const s64 pos, const MFT_REF mref, const unsigned dt_type) 357*9663SMark.Logan@Sun.COM { 358*9663SMark.Logan@Sun.COM GnomeVFSFileInfo *file_info; 359*9663SMark.Logan@Sun.COM 360*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_directory != NULL, -1); 361*9663SMark.Logan@Sun.COM g_return_val_if_fail(name != NULL, -1); 362*9663SMark.Logan@Sun.COM g_return_val_if_fail(name_len >= 0, -1); 363*9663SMark.Logan@Sun.COM g_return_val_if_fail(pos >= 0, -1); 364*9663SMark.Logan@Sun.COM 365*9663SMark.Logan@Sun.COM /* system directory */ 366*9663SMark.Logan@Sun.COM if (MREF(mref) != FILE_root && MREF(mref) < FILE_first_user) 367*9663SMark.Logan@Sun.COM return 0; /* continue traversal */ 368*9663SMark.Logan@Sun.COM 369*9663SMark.Logan@Sun.COM file_info = gnome_vfs_file_info_new(); 370*9663SMark.Logan@Sun.COM file_info->name = libntfs_ntfscharo_utf8(name, name_len); 371*9663SMark.Logan@Sun.COM file_info->valid_fields = 0; 372*9663SMark.Logan@Sun.COM 373*9663SMark.Logan@Sun.COM switch (dt_type) { 374*9663SMark.Logan@Sun.COM case NTFS_DT_FIFO: 375*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_FIFO; 376*9663SMark.Logan@Sun.COM break; 377*9663SMark.Logan@Sun.COM case NTFS_DT_CHR: 378*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE; 379*9663SMark.Logan@Sun.COM break; 380*9663SMark.Logan@Sun.COM case NTFS_DT_DIR: 381*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; 382*9663SMark.Logan@Sun.COM break; 383*9663SMark.Logan@Sun.COM case NTFS_DT_BLK: 384*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_BLOCK_DEVICE; 385*9663SMark.Logan@Sun.COM break; 386*9663SMark.Logan@Sun.COM case NTFS_DT_REG: 387*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; 388*9663SMark.Logan@Sun.COM break; 389*9663SMark.Logan@Sun.COM case NTFS_DT_LNK: 390*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; 391*9663SMark.Logan@Sun.COM break; 392*9663SMark.Logan@Sun.COM case NTFS_DT_SOCK: 393*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_SOCKET; 394*9663SMark.Logan@Sun.COM break; 395*9663SMark.Logan@Sun.COM /* FIXME: What is 'NTFS_DT_WHT'? */ 396*9663SMark.Logan@Sun.COM default: 397*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_UNKNOWN; 398*9663SMark.Logan@Sun.COM } 399*9663SMark.Logan@Sun.COM if (file_info->type != GNOME_VFS_FILE_TYPE_UNKNOWN) 400*9663SMark.Logan@Sun.COM file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_TYPE; 401*9663SMark.Logan@Sun.COM 402*9663SMark.Logan@Sun.COM /* Detect 'file_info->size': */ 403*9663SMark.Logan@Sun.COM if (file_info->type == GNOME_VFS_FILE_TYPE_REGULAR) { 404*9663SMark.Logan@Sun.COM ntfs_inode *inode; 405*9663SMark.Logan@Sun.COM 406*9663SMark.Logan@Sun.COM inode = ntfs_inode_open(libntfs_directory->inode->vol, mref); 407*9663SMark.Logan@Sun.COM /* FIXME: Check failed 'inode' open. */ 408*9663SMark.Logan@Sun.COM if (inode) { 409*9663SMark.Logan@Sun.COM ntfs_attr *attr; 410*9663SMark.Logan@Sun.COM int errint; 411*9663SMark.Logan@Sun.COM 412*9663SMark.Logan@Sun.COM attr = ntfs_attr_open(inode, /* ni */ 413*9663SMark.Logan@Sun.COM AT_DATA, /* type */ 414*9663SMark.Logan@Sun.COM AT_UNNAMED, /* name */ 415*9663SMark.Logan@Sun.COM 0); /* name_len */ 416*9663SMark.Logan@Sun.COM /* FIXME: Check failed 'attr' open. */ 417*9663SMark.Logan@Sun.COM if (attr) { 418*9663SMark.Logan@Sun.COM /* FIXME: Is 'data_size' the right field? */ 419*9663SMark.Logan@Sun.COM file_info->size = attr->data_size; 420*9663SMark.Logan@Sun.COM file_info->valid_fields |= 421*9663SMark.Logan@Sun.COM GNOME_VFS_FILE_INFO_FIELDS_SIZE; 422*9663SMark.Logan@Sun.COM ntfs_attr_close(attr); 423*9663SMark.Logan@Sun.COM } 424*9663SMark.Logan@Sun.COM errint = ntfs_inode_close(inode); 425*9663SMark.Logan@Sun.COM /* FIXME: Check 'errint'. */ 426*9663SMark.Logan@Sun.COM } 427*9663SMark.Logan@Sun.COM } 428*9663SMark.Logan@Sun.COM 429*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = g_list_prepend( 430*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list, file_info); 431*9663SMark.Logan@Sun.COM 432*9663SMark.Logan@Sun.COM return 0; /* continue traversal */ 433*9663SMark.Logan@Sun.COM } 434*9663SMark.Logan@Sun.COM 435*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_read_directory(GnomeVFSMethod *method, 436*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, 437*9663SMark.Logan@Sun.COM GnomeVFSFileInfo *file_info, 438*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 439*9663SMark.Logan@Sun.COM { 440*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 441*9663SMark.Logan@Sun.COM struct libntfs_directory *libntfs_directory; 442*9663SMark.Logan@Sun.COM 443*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 444*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 445*9663SMark.Logan@Sun.COM libntfs_directory = (struct libntfs_directory *)method_handle; 446*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_directory != NULL, 447*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 448*9663SMark.Logan@Sun.COM g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 449*9663SMark.Logan@Sun.COM 450*9663SMark.Logan@Sun.COM if (!libntfs_directory->file_info_list) { 451*9663SMark.Logan@Sun.COM int errint; 452*9663SMark.Logan@Sun.COM s64 pos; 453*9663SMark.Logan@Sun.COM 454*9663SMark.Logan@Sun.COM pos = 0; /* read from the start; incl. "." and ".." entries */ 455*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 456*9663SMark.Logan@Sun.COM errint = ntfs_readdir(libntfs_directory->inode, /* dir_ni */ 457*9663SMark.Logan@Sun.COM &pos, /* pos */ 458*9663SMark.Logan@Sun.COM libntfs_directory, /* dirent */ 459*9663SMark.Logan@Sun.COM (ntfs_filldir_t)libntfs_gnomevfs_read_directory_filldir); /* filldir */ 460*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 461*9663SMark.Logan@Sun.COM if (errint) 462*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_INTERNAL; 463*9663SMark.Logan@Sun.COM 464*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = g_list_prepend( 465*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list, NULL); /* EOF */ 466*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = g_list_reverse( 467*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list); 468*9663SMark.Logan@Sun.COM } 469*9663SMark.Logan@Sun.COM 470*9663SMark.Logan@Sun.COM if (!libntfs_directory->file_info_list->data) { 471*9663SMark.Logan@Sun.COM g_assert(libntfs_directory->file_info_list->next == NULL); 472*9663SMark.Logan@Sun.COM /* 473*9663SMark.Logan@Sun.COM * Do not clear the list to leave us stuck at EOF - GnomeVFS 474*9663SMark.Logan@Sun.COM * behaves that way. 475*9663SMark.Logan@Sun.COM */ 476*9663SMark.Logan@Sun.COM errvfsresult = GNOME_VFS_ERROR_EOF; 477*9663SMark.Logan@Sun.COM } else { 478*9663SMark.Logan@Sun.COM /* Cut first list item. */ 479*9663SMark.Logan@Sun.COM gnome_vfs_file_info_copy(file_info, /* dest */ 480*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list->data); /* src */ 481*9663SMark.Logan@Sun.COM gnome_vfs_file_info_unref( 482*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list->data); 483*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list = g_list_delete_link( 484*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list, 485*9663SMark.Logan@Sun.COM libntfs_directory->file_info_list); 486*9663SMark.Logan@Sun.COM errvfsresult = GNOME_VFS_OK; 487*9663SMark.Logan@Sun.COM } 488*9663SMark.Logan@Sun.COM return errvfsresult; 489*9663SMark.Logan@Sun.COM } 490*9663SMark.Logan@Sun.COM 491*9663SMark.Logan@Sun.COM struct libntfs_file { 492*9663SMark.Logan@Sun.COM ntfs_inode *inode; 493*9663SMark.Logan@Sun.COM ntfs_attr *attr; 494*9663SMark.Logan@Sun.COM s64 pos; 495*9663SMark.Logan@Sun.COM }; 496*9663SMark.Logan@Sun.COM 497*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_open_attr(struct libntfs_file *libntfs_file) 498*9663SMark.Logan@Sun.COM { 499*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 500*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 501*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file->inode != NULL, 502*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 503*9663SMark.Logan@Sun.COM 504*9663SMark.Logan@Sun.COM if (!libntfs_file->attr) { 505*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 506*9663SMark.Logan@Sun.COM libntfs_file->attr = ntfs_attr_open( 507*9663SMark.Logan@Sun.COM libntfs_file->inode, /* ni */ 508*9663SMark.Logan@Sun.COM AT_DATA, /* type */ 509*9663SMark.Logan@Sun.COM AT_UNNAMED, /* name */ 510*9663SMark.Logan@Sun.COM 0); /* name_len */ 511*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 512*9663SMark.Logan@Sun.COM if (!libntfs_file->attr) 513*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_BAD_FILE; 514*9663SMark.Logan@Sun.COM libntfs_file->pos = 0; 515*9663SMark.Logan@Sun.COM } 516*9663SMark.Logan@Sun.COM 517*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 518*9663SMark.Logan@Sun.COM } 519*9663SMark.Logan@Sun.COM 520*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_open(GnomeVFSMethod *method, 521*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle **method_handle_return, GnomeVFSURI *uri, 522*9663SMark.Logan@Sun.COM GnomeVFSOpenMode mode, 523*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 524*9663SMark.Logan@Sun.COM { 525*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 526*9663SMark.Logan@Sun.COM ntfs_volume *volume; 527*9663SMark.Logan@Sun.COM ntfs_inode *inode; 528*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 529*9663SMark.Logan@Sun.COM 530*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 531*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 532*9663SMark.Logan@Sun.COM g_return_val_if_fail(method_handle_return != NULL, 533*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 534*9663SMark.Logan@Sun.COM 535*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 536*9663SMark.Logan@Sun.COM libntfs_gnomevfs_uri_parent_init(&volume, uri))) 537*9663SMark.Logan@Sun.COM return errvfsresult; 538*9663SMark.Logan@Sun.COM 539*9663SMark.Logan@Sun.COM if (mode & GNOME_VFS_OPEN_WRITE) 540*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; 541*9663SMark.Logan@Sun.COM 542*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 543*9663SMark.Logan@Sun.COM inode_open_by_pathname(&inode, volume, uri->text))) 544*9663SMark.Logan@Sun.COM return errvfsresult; 545*9663SMark.Logan@Sun.COM 546*9663SMark.Logan@Sun.COM #ifdef __sun 547*9663SMark.Logan@Sun.COM libntfs_file = g_new(struct libntfs_file, 1); 548*9663SMark.Logan@Sun.COM #else /* !__sun */ 549*9663SMark.Logan@Sun.COM libntfs_new(libntfs_file); 550*9663SMark.Logan@Sun.COM #endif /* __sun */ 551*9663SMark.Logan@Sun.COM 552*9663SMark.Logan@Sun.COM libntfs_file->inode = inode; 553*9663SMark.Logan@Sun.COM libntfs_file->attr = NULL; 554*9663SMark.Logan@Sun.COM 555*9663SMark.Logan@Sun.COM *method_handle_return = (GnomeVFSMethodHandle *)libntfs_file; 556*9663SMark.Logan@Sun.COM return errvfsresult; 557*9663SMark.Logan@Sun.COM } 558*9663SMark.Logan@Sun.COM 559*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_create(GnomeVFSMethod *method, 560*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle **method_handle_return, GnomeVFSURI *uri, 561*9663SMark.Logan@Sun.COM GnomeVFSOpenMode mode __attribute__((unused)), 562*9663SMark.Logan@Sun.COM gboolean exclusive __attribute__((unused)), 563*9663SMark.Logan@Sun.COM guint perm __attribute__((unused)), 564*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 565*9663SMark.Logan@Sun.COM { 566*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 567*9663SMark.Logan@Sun.COM ntfs_volume *volume; 568*9663SMark.Logan@Sun.COM 569*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 570*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 571*9663SMark.Logan@Sun.COM g_return_val_if_fail(method_handle_return != NULL, 572*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 573*9663SMark.Logan@Sun.COM 574*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 575*9663SMark.Logan@Sun.COM libntfs_gnomevfs_uri_parent_init(&volume, uri))) 576*9663SMark.Logan@Sun.COM return errvfsresult; 577*9663SMark.Logan@Sun.COM 578*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; 579*9663SMark.Logan@Sun.COM } 580*9663SMark.Logan@Sun.COM 581*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_close(GnomeVFSMethod *method, 582*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, 583*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 584*9663SMark.Logan@Sun.COM { 585*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 586*9663SMark.Logan@Sun.COM int errint; 587*9663SMark.Logan@Sun.COM 588*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 589*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 590*9663SMark.Logan@Sun.COM libntfs_file = (struct libntfs_file *) method_handle; 591*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 592*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 593*9663SMark.Logan@Sun.COM 594*9663SMark.Logan@Sun.COM if (libntfs_file->attr) { 595*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 596*9663SMark.Logan@Sun.COM ntfs_attr_close(libntfs_file->attr); 597*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 598*9663SMark.Logan@Sun.COM } 599*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 600*9663SMark.Logan@Sun.COM errint = ntfs_inode_close(libntfs_file->inode); 601*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 602*9663SMark.Logan@Sun.COM if (errint) 603*9663SMark.Logan@Sun.COM g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); 604*9663SMark.Logan@Sun.COM 605*9663SMark.Logan@Sun.COM g_free(libntfs_file); 606*9663SMark.Logan@Sun.COM 607*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 608*9663SMark.Logan@Sun.COM } 609*9663SMark.Logan@Sun.COM 610*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_read(GnomeVFSMethod *method, 611*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, gpointer buffer, 612*9663SMark.Logan@Sun.COM GnomeVFSFileSize num_bytes, GnomeVFSFileSize *bytes_read_return, 613*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 614*9663SMark.Logan@Sun.COM { 615*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 616*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 617*9663SMark.Logan@Sun.COM s64 count_s64, got; 618*9663SMark.Logan@Sun.COM 619*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 620*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 621*9663SMark.Logan@Sun.COM libntfs_file = (struct libntfs_file *)method_handle; 622*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 623*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 624*9663SMark.Logan@Sun.COM g_return_val_if_fail(buffer != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 625*9663SMark.Logan@Sun.COM g_return_val_if_fail(bytes_read_return != NULL, 626*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 627*9663SMark.Logan@Sun.COM 628*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) 629*9663SMark.Logan@Sun.COM return errvfsresult; 630*9663SMark.Logan@Sun.COM 631*9663SMark.Logan@Sun.COM count_s64 = num_bytes; 632*9663SMark.Logan@Sun.COM g_assert((GnomeVFSFileSize)count_s64 == num_bytes); 633*9663SMark.Logan@Sun.COM G_LOCK(libntfs); 634*9663SMark.Logan@Sun.COM got = ntfs_attr_pread(libntfs_file->attr, libntfs_file->pos, count_s64, 635*9663SMark.Logan@Sun.COM buffer); 636*9663SMark.Logan@Sun.COM G_UNLOCK(libntfs); 637*9663SMark.Logan@Sun.COM if (got == -1) 638*9663SMark.Logan@Sun.COM return GNOME_VFS_ERROR_IO; 639*9663SMark.Logan@Sun.COM 640*9663SMark.Logan@Sun.COM libntfs_file->pos += got; 641*9663SMark.Logan@Sun.COM *bytes_read_return = got; 642*9663SMark.Logan@Sun.COM g_assert((s64)*bytes_read_return == got); 643*9663SMark.Logan@Sun.COM 644*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 645*9663SMark.Logan@Sun.COM } 646*9663SMark.Logan@Sun.COM 647*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_seek(GnomeVFSMethod *method, 648*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, 649*9663SMark.Logan@Sun.COM GnomeVFSSeekPosition whence, GnomeVFSFileOffset offset, 650*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 651*9663SMark.Logan@Sun.COM { 652*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 653*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 654*9663SMark.Logan@Sun.COM 655*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 656*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 657*9663SMark.Logan@Sun.COM libntfs_file = (struct libntfs_file *)method_handle; 658*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 659*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 660*9663SMark.Logan@Sun.COM 661*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) 662*9663SMark.Logan@Sun.COM return errvfsresult; 663*9663SMark.Logan@Sun.COM 664*9663SMark.Logan@Sun.COM switch (whence) { 665*9663SMark.Logan@Sun.COM case GNOME_VFS_SEEK_START: 666*9663SMark.Logan@Sun.COM libntfs_file->pos = offset; 667*9663SMark.Logan@Sun.COM break; 668*9663SMark.Logan@Sun.COM case GNOME_VFS_SEEK_CURRENT: 669*9663SMark.Logan@Sun.COM libntfs_file->pos += offset; 670*9663SMark.Logan@Sun.COM break; 671*9663SMark.Logan@Sun.COM case GNOME_VFS_SEEK_END: 672*9663SMark.Logan@Sun.COM /* FIXME: NOT IMPLEMENTED YET */ 673*9663SMark.Logan@Sun.COM g_return_val_if_reached(GNOME_VFS_ERROR_BAD_PARAMETERS); 674*9663SMark.Logan@Sun.COM default: 675*9663SMark.Logan@Sun.COM g_assert_not_reached(); 676*9663SMark.Logan@Sun.COM } 677*9663SMark.Logan@Sun.COM 678*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 679*9663SMark.Logan@Sun.COM } 680*9663SMark.Logan@Sun.COM 681*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_tell(GnomeVFSMethod *method, 682*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle, 683*9663SMark.Logan@Sun.COM GnomeVFSFileSize *offset_return) 684*9663SMark.Logan@Sun.COM { 685*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 686*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 687*9663SMark.Logan@Sun.COM 688*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 689*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 690*9663SMark.Logan@Sun.COM libntfs_file = (struct libntfs_file *)method_handle; 691*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 692*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 693*9663SMark.Logan@Sun.COM g_return_val_if_fail(offset_return != NULL, 694*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 695*9663SMark.Logan@Sun.COM 696*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) 697*9663SMark.Logan@Sun.COM return errvfsresult; 698*9663SMark.Logan@Sun.COM 699*9663SMark.Logan@Sun.COM *offset_return = libntfs_file->pos; 700*9663SMark.Logan@Sun.COM g_assert((s64)*offset_return == libntfs_file->pos); 701*9663SMark.Logan@Sun.COM 702*9663SMark.Logan@Sun.COM return errvfsresult; 703*9663SMark.Logan@Sun.COM } 704*9663SMark.Logan@Sun.COM 705*9663SMark.Logan@Sun.COM static gboolean libntfs_gnomevfs_is_local(GnomeVFSMethod *method, 706*9663SMark.Logan@Sun.COM const GnomeVFSURI *uri) 707*9663SMark.Logan@Sun.COM { 708*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 709*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 710*9663SMark.Logan@Sun.COM g_return_val_if_fail(uri != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 711*9663SMark.Logan@Sun.COM 712*9663SMark.Logan@Sun.COM return gnome_vfs_uri_is_local(uri->parent); 713*9663SMark.Logan@Sun.COM } 714*9663SMark.Logan@Sun.COM 715*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_get_file_info_from_handle( 716*9663SMark.Logan@Sun.COM GnomeVFSMethod *method, GnomeVFSMethodHandle *method_handle, 717*9663SMark.Logan@Sun.COM GnomeVFSFileInfo *file_info, 718*9663SMark.Logan@Sun.COM GnomeVFSFileInfoOptions options __attribute__((unused)), 719*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 720*9663SMark.Logan@Sun.COM { 721*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 722*9663SMark.Logan@Sun.COM struct libntfs_file *libntfs_file; 723*9663SMark.Logan@Sun.COM 724*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 725*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 726*9663SMark.Logan@Sun.COM libntfs_file = (struct libntfs_file *)method_handle; 727*9663SMark.Logan@Sun.COM g_return_val_if_fail(libntfs_file != NULL, 728*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 729*9663SMark.Logan@Sun.COM g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 730*9663SMark.Logan@Sun.COM /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ 731*9663SMark.Logan@Sun.COM 732*9663SMark.Logan@Sun.COM file_info->valid_fields = 0; 733*9663SMark.Logan@Sun.COM /* FIXME: It is complicated to read filename of open 'ntfs_inode'. */ 734*9663SMark.Logan@Sun.COM file_info->name = NULL; 735*9663SMark.Logan@Sun.COM 736*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = libntfs_open_attr(libntfs_file))) { 737*9663SMark.Logan@Sun.COM /* Assume we are directory: */ 738*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_DIRECTORY; 739*9663SMark.Logan@Sun.COM /* 740*9663SMark.Logan@Sun.COM * Do not: file_info->valid_fields |= 741*9663SMark.Logan@Sun.COM * GNOME_VFS_FILE_INFO_FIELDS_TYPE; 742*9663SMark.Logan@Sun.COM * as gnome-vfs-xfer.c/copy_items() does not check 743*9663SMark.Logan@Sun.COM * 'GNOME_VFS_FILE_INFO_FIELDS_TYPE' and we are just bluffing 744*9663SMark.Logan@Sun.COM * we know it. 745*9663SMark.Logan@Sun.COM */ 746*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 747*9663SMark.Logan@Sun.COM } 748*9663SMark.Logan@Sun.COM 749*9663SMark.Logan@Sun.COM /* FIXME: Is 'data_size' the right field? */ 750*9663SMark.Logan@Sun.COM file_info->size = libntfs_file->attr->data_size; 751*9663SMark.Logan@Sun.COM file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SIZE; 752*9663SMark.Logan@Sun.COM 753*9663SMark.Logan@Sun.COM /* 754*9663SMark.Logan@Sun.COM * FIXME: We do not really know the type of 'libntfs_file' but 755*9663SMark.Logan@Sun.COM * gnome-vfs-xfer.c/copy_items() requires 'GNOME_VFS_FILE_TYPE_REGULAR' 756*9663SMark.Logan@Sun.COM * to copy it. 757*9663SMark.Logan@Sun.COM */ 758*9663SMark.Logan@Sun.COM file_info->type = GNOME_VFS_FILE_TYPE_REGULAR; 759*9663SMark.Logan@Sun.COM /* 760*9663SMark.Logan@Sun.COM * Do not: file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE; 761*9663SMark.Logan@Sun.COM * as gnome-vfs-xfer.c/copy_items() does not check 762*9663SMark.Logan@Sun.COM * 'GNOME_VFS_FILE_INFO_FIELDS_TYPE' and we are just bluffing we know 763*9663SMark.Logan@Sun.COM * it. 764*9663SMark.Logan@Sun.COM */ 765*9663SMark.Logan@Sun.COM 766*9663SMark.Logan@Sun.COM return errvfsresult; 767*9663SMark.Logan@Sun.COM } 768*9663SMark.Logan@Sun.COM 769*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_get_file_info(GnomeVFSMethod *method, 770*9663SMark.Logan@Sun.COM GnomeVFSURI *uri, GnomeVFSFileInfo *file_info, 771*9663SMark.Logan@Sun.COM GnomeVFSFileInfoOptions options, GnomeVFSContext *context) 772*9663SMark.Logan@Sun.COM { 773*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 774*9663SMark.Logan@Sun.COM GnomeVFSMethodHandle *method_handle; 775*9663SMark.Logan@Sun.COM 776*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 777*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 778*9663SMark.Logan@Sun.COM g_return_val_if_fail(file_info != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS); 779*9663SMark.Logan@Sun.COM /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ 780*9663SMark.Logan@Sun.COM 781*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 782*9663SMark.Logan@Sun.COM libntfs_gnomevfs_open(method, &method_handle, uri, 783*9663SMark.Logan@Sun.COM GNOME_VFS_OPEN_READ, context))) 784*9663SMark.Logan@Sun.COM return errvfsresult; 785*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 786*9663SMark.Logan@Sun.COM libntfs_gnomevfs_get_file_info_from_handle(method, 787*9663SMark.Logan@Sun.COM method_handle, file_info, options, context))) 788*9663SMark.Logan@Sun.COM return errvfsresult; 789*9663SMark.Logan@Sun.COM if (GNOME_VFS_OK != (errvfsresult = 790*9663SMark.Logan@Sun.COM libntfs_gnomevfs_close(method, method_handle, context))) 791*9663SMark.Logan@Sun.COM return errvfsresult; 792*9663SMark.Logan@Sun.COM 793*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 794*9663SMark.Logan@Sun.COM } 795*9663SMark.Logan@Sun.COM 796*9663SMark.Logan@Sun.COM static GnomeVFSResult libntfs_gnomevfs_check_same_fs(GnomeVFSMethod *method, 797*9663SMark.Logan@Sun.COM GnomeVFSURI *a, GnomeVFSURI *b, gboolean *same_fs_return, 798*9663SMark.Logan@Sun.COM GnomeVFSContext *context __attribute__((unused))) 799*9663SMark.Logan@Sun.COM { 800*9663SMark.Logan@Sun.COM ntfs_volume *volume_a; 801*9663SMark.Logan@Sun.COM ntfs_volume *volume_b; 802*9663SMark.Logan@Sun.COM GnomeVFSResult errvfsresult; 803*9663SMark.Logan@Sun.COM 804*9663SMark.Logan@Sun.COM g_return_val_if_fail(method == &GnomeVFSMethod_static, 805*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 806*9663SMark.Logan@Sun.COM g_return_val_if_fail(same_fs_return != NULL, 807*9663SMark.Logan@Sun.COM GNOME_VFS_ERROR_BAD_PARAMETERS); 808*9663SMark.Logan@Sun.COM 809*9663SMark.Logan@Sun.COM errvfsresult = libntfs_gnomevfs_uri_parent_init(&volume_a, a); 810*9663SMark.Logan@Sun.COM g_return_val_if_fail(errvfsresult == GNOME_VFS_OK, errvfsresult); 811*9663SMark.Logan@Sun.COM 812*9663SMark.Logan@Sun.COM errvfsresult = libntfs_gnomevfs_uri_parent_init(&volume_b, b); 813*9663SMark.Logan@Sun.COM g_return_val_if_fail(errvfsresult == GNOME_VFS_OK, errvfsresult); 814*9663SMark.Logan@Sun.COM 815*9663SMark.Logan@Sun.COM *same_fs_return = (volume_a == volume_b); 816*9663SMark.Logan@Sun.COM 817*9663SMark.Logan@Sun.COM return GNOME_VFS_OK; 818*9663SMark.Logan@Sun.COM } 819*9663SMark.Logan@Sun.COM 820*9663SMark.Logan@Sun.COM /** 821*9663SMark.Logan@Sun.COM * libntfs_gnomevfs_init: 822*9663SMark.Logan@Sun.COM * 823*9663SMark.Logan@Sun.COM * Returns: Initialized structure of #GnomeVFSMethod with static methods of 824*9663SMark.Logan@Sun.COM * libntfs-gnomevfs. 825*9663SMark.Logan@Sun.COM */ 826*9663SMark.Logan@Sun.COM GnomeVFSMethod *libntfs_gnomevfs_method_init(const gchar *method_name, 827*9663SMark.Logan@Sun.COM const gchar *args) 828*9663SMark.Logan@Sun.COM { 829*9663SMark.Logan@Sun.COM struct method_name_info *method_name_info; 830*9663SMark.Logan@Sun.COM 831*9663SMark.Logan@Sun.COM g_return_val_if_fail(method_name != NULL, NULL); 832*9663SMark.Logan@Sun.COM /* 'args' may be NULL if not supplied. */ 833*9663SMark.Logan@Sun.COM 834*9663SMark.Logan@Sun.COM method_name_hash_init(); 835*9663SMark.Logan@Sun.COM 836*9663SMark.Logan@Sun.COM G_LOCK(method_name_hash); 837*9663SMark.Logan@Sun.COM method_name_info = g_hash_table_lookup(method_name_hash, method_name); 838*9663SMark.Logan@Sun.COM if (method_name_info && strcmp(method_name_info->args, args)) 839*9663SMark.Logan@Sun.COM method_name_info = NULL; 840*9663SMark.Logan@Sun.COM G_UNLOCK(method_name_hash); 841*9663SMark.Logan@Sun.COM if (!method_name_info) { 842*9663SMark.Logan@Sun.COM 843*9663SMark.Logan@Sun.COM #ifdef __sun 844*9663SMark.Logan@Sun.COM method_name_info = g_new(struct method_name_info, 1); 845*9663SMark.Logan@Sun.COM #else /* !__sun */ 846*9663SMark.Logan@Sun.COM libntfs_new(method_name_info); 847*9663SMark.Logan@Sun.COM #endif /* __sun */ 848*9663SMark.Logan@Sun.COM 849*9663SMark.Logan@Sun.COM method_name_info->args = g_strdup(args); 850*9663SMark.Logan@Sun.COM G_LOCK(method_name_hash); 851*9663SMark.Logan@Sun.COM g_hash_table_replace(method_name_hash, g_strdup(method_name), 852*9663SMark.Logan@Sun.COM method_name_info); 853*9663SMark.Logan@Sun.COM G_UNLOCK(method_name_hash); 854*9663SMark.Logan@Sun.COM } 855*9663SMark.Logan@Sun.COM 856*9663SMark.Logan@Sun.COM G_LOCK(GnomeVFSMethod_static); 857*9663SMark.Logan@Sun.COM LIBNTFS_MEMZERO(&GnomeVFSMethod_static); 858*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.method_table_size = sizeof(GnomeVFSMethod_static); 859*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.open = libntfs_gnomevfs_open; /* mandatory */ 860*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.create = libntfs_gnomevfs_create; /* mandatory */ 861*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.close = libntfs_gnomevfs_close; 862*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.read = libntfs_gnomevfs_read; 863*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.seek = libntfs_gnomevfs_seek; 864*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.tell = libntfs_gnomevfs_tell; 865*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.open_directory = libntfs_gnomevfs_open_directory; 866*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.close_directory = 867*9663SMark.Logan@Sun.COM libntfs_gnomevfs_close_directory; 868*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.read_directory = libntfs_gnomevfs_read_directory; 869*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.get_file_info = 870*9663SMark.Logan@Sun.COM libntfs_gnomevfs_get_file_info; /* mandatory */ 871*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.get_file_info_from_handle = 872*9663SMark.Logan@Sun.COM libntfs_gnomevfs_get_file_info_from_handle; 873*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.is_local = 874*9663SMark.Logan@Sun.COM libntfs_gnomevfs_is_local; /* mandatory */ 875*9663SMark.Logan@Sun.COM GnomeVFSMethod_static.check_same_fs = libntfs_gnomevfs_check_same_fs; 876*9663SMark.Logan@Sun.COM /* TODO: GnomeVFSMethodFindDirectoryFunc find_directory; */ 877*9663SMark.Logan@Sun.COM /* TODO: GnomeVFSMethodFileControlFunc file_control; */ 878*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; */ 879*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethodMonitorAddFunc monitor_add; */ 880*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethodMonitorCancelFunc monitor_cancel; */ 881*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.write; */ 882*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.truncate_handle; */ 883*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.make_directory; */ 884*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.remove_directory; */ 885*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.move; */ 886*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.unlink; */ 887*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.set_file_info; */ 888*9663SMark.Logan@Sun.COM /* R/W: GnomeVFSMethod_static.truncate; */ 889*9663SMark.Logan@Sun.COM G_UNLOCK(GnomeVFSMethod_static); 890*9663SMark.Logan@Sun.COM 891*9663SMark.Logan@Sun.COM return &GnomeVFSMethod_static; 892*9663SMark.Logan@Sun.COM } 893*9663SMark.Logan@Sun.COM 894*9663SMark.Logan@Sun.COM /** 895*9663SMark.Logan@Sun.COM * libntfs_gnomevfs_method_shutdown: 896*9663SMark.Logan@Sun.COM * 897*9663SMark.Logan@Sun.COM * Shutdowns libntfs-gnomevfs successfuly flushing all caches. 898*9663SMark.Logan@Sun.COM * 899*9663SMark.Logan@Sun.COM * Sad note about gnome-vfs-2.1.5 is that it never calls this function. :-) 900*9663SMark.Logan@Sun.COM */ 901*9663SMark.Logan@Sun.COM void libntfs_gnomevfs_method_shutdown(void) 902*9663SMark.Logan@Sun.COM { 903*9663SMark.Logan@Sun.COM uri_parent_string_hash_init(); 904*9663SMark.Logan@Sun.COM G_LOCK(uri_parent_string_hash); 905*9663SMark.Logan@Sun.COM g_hash_table_destroy(uri_parent_string_hash); 906*9663SMark.Logan@Sun.COM uri_parent_string_hash = NULL; 907*9663SMark.Logan@Sun.COM G_UNLOCK(uri_parent_string_hash); 908*9663SMark.Logan@Sun.COM 909*9663SMark.Logan@Sun.COM method_name_hash_init(); 910*9663SMark.Logan@Sun.COM G_LOCK(method_name_hash); 911*9663SMark.Logan@Sun.COM g_hash_table_destroy(method_name_hash); 912*9663SMark.Logan@Sun.COM method_name_hash = NULL; 913*9663SMark.Logan@Sun.COM G_UNLOCK(method_name_hash); 914*9663SMark.Logan@Sun.COM } 915*9663SMark.Logan@Sun.COM 916