diff --git a/src/add-ons/kernel/file_systems/ntfs/Jamfile b/src/add-ons/kernel/file_systems/ntfs/Jamfile index afffa6e31c..1b61b11623 100644 --- a/src/add-ons/kernel/file_systems/ntfs/Jamfile +++ b/src/add-ons/kernel/file_systems/ntfs/Jamfile @@ -9,6 +9,7 @@ UsePrivateHeaders kernel ; KernelAddon ntfs : attributes.c + fake_attributes.c mime_table.c utils.c ntfsdir.c diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.c b/src/add-ons/kernel/file_systems/ntfs/attributes.c index c6fe2a56c8..bef6dcd11c 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.c +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.c @@ -25,41 +25,6 @@ //TODO: notify*() - -int32 kBeOSTypeCookie = 0x1234; - - -status_t -set_mime(vnode *node, const char *filename) -{ - struct ext_mime *p; - int32 namelen, ext_len; - - TRACE("set_mime - for [%s]\n", filename); - - node->mime = NULL; - - namelen = strlen(filename); - - for (p = mimes; p->extension; p++) { - ext_len = strlen(p->extension); - - if (namelen <= ext_len) - continue; - - if (filename[namelen-ext_len-1] != '.') - continue; - - if (!strcasecmp(filename + namelen - ext_len, p->extension)) - break; - } - - node->mime = p->mime; - - return B_NO_ERROR; -} - - status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) { diff --git a/src/add-ons/kernel/file_systems/ntfs/attributes.h b/src/add-ons/kernel/file_systems/ntfs/attributes.h index a485bd539a..a7d924ef81 100644 --- a/src/add-ons/kernel/file_systems/ntfs/attributes.h +++ b/src/add-ons/kernel/file_systems/ntfs/attributes.h @@ -14,9 +14,6 @@ #include "ntfs.h" - -status_t set_mime(vnode *node, const char *filename); - status_t fs_create_attrib(fs_volume *_vol, fs_vnode *_node, const char* name, uint32 type, int openMode, void** _cookie); status_t fs_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie); diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c new file mode 100644 index 0000000000..517add5d57 --- /dev/null +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.c @@ -0,0 +1,337 @@ +/* + Copyright 1999-2001, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ +/* fake_attributes.c + * handles mime type information for ntfs + * gets/sets mime information in vnode + */ + +#define MIME_STRING_TYPE 'MIMS' + +#include +#include + +#include +#include +#include +#include + +#include "ntfs.h" +#include "fake_attributes.h" +#include "mime_table.h" + +int32 kBeOSTypeCookie = 0x1234; + +status_t set_mime(vnode *node, const char *filename) +{ + struct ext_mime *p; + int32 namelen, ext_len; + node->mime = NULL; + namelen = strlen(filename); + + for (p=mimes; p->extension; p++) { + ext_len = strlen(p->extension); + + if (namelen <= ext_len) + continue; + + if (filename[namelen-ext_len-1] != '.') + continue; + + if (!strcasecmp(filename + namelen - ext_len, p->extension)) + break; + } + node->mime = p->mime; + return B_NO_ERROR; +} + + +status_t +fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, void **_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + TRACE("fake_open_attrdir - ENTER\n"); + + LOCK_VOL(ns); + + if ((*_cookie = malloc(sizeof(uint32))) == NULL) { + result = ENOMEM; + goto exit; + } + + *(int32 *)(*_cookie) = 0; + +exit: + + TRACE("fs_open_attrdir - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + +status_t +fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + TRACE("fake_close_attrdir - ENTER\n"); + + LOCK_VOL(ns); + + *(int32 *)_cookie = 1; + + TRACE("fake_close_attrdir - EXIT\n"); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + +status_t +fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_free_attrib_dir_cookie - ENTER\n"); + + if (_cookie == NULL) { + TRACE("fake_free_attrib_dir_cookie - error:called with null cookie\n"); + result = EINVAL; + goto exit; + } + + *(int32 *)_cookie = 0x87654321; + free(_cookie); + +exit: + + TRACE("fake_free_attrib_dir_cookie - EXIT, result is %s\n", + strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + +status_t +fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_rewind_attrcookie - ENTER\n"); + + if (_cookie == NULL) { + TRACE("fake_rewind_attrcookie - error: fs_rewind_attrcookie" + "called with null cookie\n"); + result = EINVAL; + goto exit; + } + + *(uint32 *)_cookie = 0; + +exit: + + TRACE("fake_rewind_attrcookie - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +status_t +fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, + struct dirent *entry, size_t bufsize, uint32 *num) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + + int32 *cookie = (int32 *)_cookie; + + LOCK_VOL(ns); + + TRACE("fake_read_attrdir - ENTER\n"); + + *num = 0; + + if ((*cookie == 0) && (node->mime)) { + *num = 1; + + entry->d_ino = node->vnid; + entry->d_dev = ns->id; + entry->d_reclen = 10; + strcpy(entry->d_name, "BEOS:TYPE"); + } + + *cookie = 1; + + TRACE("fake_read_attrdir - EXIT\n"); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + +status_t +fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, + int openMode, void **_cookie) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_open_attrib - ENTER\n"); + + if (strcmp(name, "BEOS:TYPE")) { + result = ENOENT; + goto exit; + } + + if (node->mime == NULL) { + result = ENOENT; + goto exit; + } + + *_cookie = &kBeOSTypeCookie; + +exit: + + TRACE("fake_open_attrib - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +status_t +fake_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie) +{ + return B_NO_ERROR; +} + + +status_t +fake_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, void *cookie) +{ + return B_NO_ERROR; +} + + +status_t +fake_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *_cookie, + struct stat *stat) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_read_attr_stat - ENTER\n"); + + if (_cookie != &kBeOSTypeCookie) { + result = ENOENT; + goto exit; + } + + if (node->mime == NULL) { + result = ENOENT; + goto exit; + } + + stat->st_type = MIME_STRING_TYPE; + stat->st_size = strlen(node->mime) + 1; + +exit: + + TRACE("fake_read_attrib_stat - EXIT, result is %s\n", + strerror(result)); + + UNLOCK_VOL(ns); + + return B_NO_ERROR; +} + + +status_t +fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, + off_t pos,void *buffer, size_t *_length) +{ + nspace *ns = (nspace *)_vol->private_volume; + vnode *node = (vnode *)_node->private_node; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_read_attr - ENTER\n"); + + if (_cookie != &kBeOSTypeCookie) { + result = ENOENT; + goto exit; + } + + if (node->mime == NULL) { + result = ENOENT; + goto exit; + } + + if ((pos < 0) || (pos > strlen(node->mime))) { + result = EINVAL; + goto exit; + } + + strncpy(buffer, node->mime + pos, *_length - 1); + ((char *)buffer)[*_length - 1] = 0; + *_length = strlen(buffer) + 1; + +exit: + + TRACE("fake_read_attr - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} + + +status_t +fake_write_attrib(fs_volume *_vol, fs_vnode *_node, void *_cookie, off_t pos, + const void *buffer, size_t *_length) +{ + nspace *ns = (nspace *)_vol->private_volume; + + int result = B_NO_ERROR; + + LOCK_VOL(ns); + + TRACE("fake_write_attr - ENTER\n"); + + *_length = 0; + + if (_cookie != &kBeOSTypeCookie) { + result = ENOSYS; + } + + TRACE("fake_write_attrib - EXIT, result is %s\n", strerror(result)); + + UNLOCK_VOL(ns); + + return result; +} diff --git a/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h new file mode 100644 index 0000000000..c12749418a --- /dev/null +++ b/src/add-ons/kernel/file_systems/ntfs/fake_attributes.h @@ -0,0 +1,39 @@ +/* + Copyright 1999-2001, Be Incorporated. All Rights Reserved. + This file may be used under the terms of the Be Sample Code License. +*/ +/* fake_attributes.h + * handles mime type information for ntfs + * gets/sets mime information in vnode + */ + +#ifndef NTFS_FAKE_ATTR_H_ +#define NTFS_FAKE_ATTR_H_ + +#include + +status_t set_mime(vnode *node, const char *filename); + +status_t fake_open_attrib_dir(fs_volume *_vol, fs_vnode *_node, + void **_cookie); +status_t fake_close_attrib_dir(fs_volume *_vol, fs_vnode *_node, + void *_cookie); +status_t fake_free_attrib_dir_cookie(fs_volume *_vol, fs_vnode *_node, + void *_cookie); +status_t fake_rewind_attrib_dir(fs_volume *_vol, fs_vnode *_node, + void *_cookie); +status_t fake_read_attrib_dir(fs_volume *_vol, fs_vnode *_node, void *_cookie, + struct dirent *buf, size_t bufsize, uint32 *num); +status_t fake_open_attrib(fs_volume *_vol, fs_vnode *_node, const char *name, + int openMode, void **_cookie); +status_t fake_close_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie); +status_t fake_free_attrib_cookie(fs_volume *_vol, fs_vnode *_node, + void *cookie); +status_t fake_read_attrib_stat(fs_volume *_vol, fs_vnode *_node, void *cookie, + struct stat *stat); +status_t fake_read_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, + off_t pos,void *buffer, size_t *_length); +status_t fake_write_attrib(fs_volume *_vol, fs_vnode *_node, void *cookie, + off_t pos, const void *buffer, size_t *_length); + +#endif //NTFS_FAKE_ATTR_H_ diff --git a/src/add-ons/kernel/file_systems/ntfs/fs_func.c b/src/add-ons/kernel/file_systems/ntfs/fs_func.c index fd8c6e423c..3427e4b314 100644 --- a/src/add-ons/kernel/file_systems/ntfs/fs_func.c +++ b/src/add-ons/kernel/file_systems/ntfs/fs_func.c @@ -38,6 +38,7 @@ #include #include "attributes.h" +#include "fake_attributes.h" #include "lock.h" #include "ntfs.h" #include "volume_util.h" @@ -404,6 +405,7 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, .state = NF_FreeClustersOutdate | NF_FreeMFTOutdate, .show_sys_files = false, .ro = false, + .fake_attrib = false, .flags = 0 }; @@ -419,6 +421,8 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, "false"), "false") != 0; ns->noatime = strcasecmp(get_driver_parameter(handle, "no_atime", "true", "true"), "true") == 0; + ns->fake_attrib = strcasecmp(get_driver_parameter(handle, "fake_attributes", + "false", "false"), "false") != 0; unload_driver_settings(handle); if (ns->ro || (flags & B_MOUNT_READ_ONLY) != 0 @@ -427,6 +431,21 @@ fs_mount(fs_volume *_vol, const char *device, ulong flags, const char *args, ns->flags |= B_FS_IS_READONLY; } + if (ns->fake_attrib) { + gNTFSVnodeOps.open_attr_dir = fake_open_attrib_dir; + gNTFSVnodeOps.close_attr_dir = fake_close_attrib_dir; + gNTFSVnodeOps.free_attr_dir_cookie = fake_free_attrib_dir_cookie; + gNTFSVnodeOps.read_attr_dir = fake_read_attrib_dir; + gNTFSVnodeOps.rewind_attr_dir = fake_rewind_attrib_dir; + gNTFSVnodeOps.create_attr = NULL; + gNTFSVnodeOps.open_attr = fake_open_attrib; + gNTFSVnodeOps.close_attr = fake_close_attrib; + gNTFSVnodeOps.free_attr_cookie = fake_free_attrib_cookie; + gNTFSVnodeOps.read_attr = fake_read_attrib; + gNTFSVnodeOps.read_attr_stat = fake_read_attrib_stat; + gNTFSVnodeOps.write_attr = fake_write_attrib; + } + ns->ntvol = utils_mount_volume(device, mountFlags | MS_RECOVER); if (ns->ntvol != NULL) result = B_NO_ERROR; @@ -701,18 +720,19 @@ fs_read_vnode(fs_volume *_vol, ino_t vnid, fs_vnode *_node, int *_type, newNode->vnid = vnid; newNode->parent_vnid = ntfs_mft_get_parent_ref(ni); - - if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) - set_mime(newNode, ".***"); - else { - name = (char*)malloc(MAX_PATH); - if (name != NULL) { - if (utils_inode_get_name(ni, name, MAX_PATH) == 1) - set_mime(newNode, name); - free(name); + + if (ns->fake_attrib) { + if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) + set_mime(newNode, ".***"); + else { + name = (char*)malloc(MAX_PATH); + if (name != NULL) { + if (utils_inode_get_name(ni, name, MAX_PATH) == 1) + set_mime(newNode, name); + free(name); + } } } - _node->private_node = newNode; } else result = ENOMEM; @@ -1149,7 +1169,9 @@ fs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode, newNode->vnid = *_vnid; newNode->parent_vnid = MREF(bi->mft_no); - set_mime(newNode, name); + + if (ns->fake_attrib) + set_mime(newNode, name); ni->flags |= FILE_ATTR_ARCHIVE; ntfs_inode_update_mbsname(bi, name, ni->mft_no); @@ -1511,7 +1533,7 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, int unameLength; int utargetLength; status_t result = B_NO_ERROR; - int fmode; + int fmode = FS_FILE_MODE; le32 securid = 0; LOCK_VOL(ns); @@ -1557,12 +1579,13 @@ fs_create_symlink(fs_volume *_vol, fs_vnode *_dir, const char *name, symnode->vnid = MREF(sym->mft_no); symnode->parent_vnid = MREF(bi->mft_no); - if (sym->mrec->flags & MFT_RECORD_IS_DIRECTORY) { - set_mime(symnode, ".***"); - fmode = FS_DIR_MODE; - } else { - set_mime(symnode, name); - fmode = FS_FILE_MODE; + if (ns->fake_attrib) { + if (sym->mrec->flags & MFT_RECORD_IS_DIRECTORY) { + set_mime(symnode, ".***"); + fmode = FS_DIR_MODE; + } else { + set_mime(symnode, name); + } } result = publish_vnode(_vol, MREF(sym->mft_no), symnode, &gNTFSVnodeOps, @@ -1655,7 +1678,9 @@ fs_mkdir(fs_volume *_vol, fs_vnode *_dir, const char *name, int perms) newNode->vnid = vnid; newNode->parent_vnid = MREF(bi->mft_no); - set_mime(newNode, ".***"); + + if (ns->fake_attrib) + set_mime(newNode, ".***"); ni->flags |= FILE_ATTR_ARCHIVE; ntfs_inode_update_mbsname(bi, name, ni->mft_no); @@ -1761,6 +1786,13 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, fs_ntfs_update_times(_vol, ni, NTFS_UPDATE_CTIME); fs_ntfs_update_times(_vol, dir_ni, NTFS_UPDATE_MCTIME); + + if (ns->fake_attrib) { + if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) + set_mime(file, ".***"); + else + set_mime(file, newname); + } ntfs_inode_close(dir_ni); ntfs_inode_close(ni); @@ -1769,7 +1801,8 @@ fs_rename(fs_volume *_vol, fs_vnode *_odir, const char *name, ntfs_remove(_vol, parent, name); - file->parent_vnid = newparent; + file->parent_vnid = newparent; + put_vnode(_vol, file->vnid); notify_entry_moved(ns->id, parent, name, newparent, newname, ino); diff --git a/src/add-ons/kernel/file_systems/ntfs/ntfs.h b/src/add-ons/kernel/file_systems/ntfs/ntfs.h index df87c89a9b..e26147d1e7 100644 --- a/src/add-ons/kernel/file_systems/ntfs/ntfs.h +++ b/src/add-ons/kernel/file_systems/ntfs/ntfs.h @@ -119,6 +119,7 @@ typedef struct nspace { long free_mft; BOOL ro; BOOL show_sys_files; + BOOL fake_attrib; BOOL silent; BOOL force; BOOL debug; diff --git a/src/add-ons/kernel/file_systems/ntfs/settings/ntfs b/src/add-ons/kernel/file_systems/ntfs/settings/ntfs index 3a8e574252..d3f182acf0 100644 --- a/src/add-ons/kernel/file_systems/ntfs/settings/ntfs +++ b/src/add-ons/kernel/file_systems/ntfs/settings/ntfs @@ -6,3 +6,4 @@ hide_sys_files true read_only false no_atime true +fake_attributes true