Added support for fake attributes.
If necessary, you can disable support for extended attributes in the settings file.
This commit is contained in:
@@ -9,6 +9,7 @@ UsePrivateHeaders kernel ;
|
||||
|
||||
KernelAddon ntfs :
|
||||
attributes.c
|
||||
fake_attributes.c
|
||||
mime_table.c
|
||||
utils.c
|
||||
ntfsdir.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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 <SupportDefs.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <dirent.h>
|
||||
#include <fs_attr.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
@@ -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 <fs_attr.h>
|
||||
|
||||
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_
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <KernelExport.h>
|
||||
|
||||
#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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
hide_sys_files true
|
||||
read_only false
|
||||
no_atime true
|
||||
fake_attributes true
|
||||
|
||||
Reference in New Issue
Block a user