Fixed build for R5 and dano targets. Bug fixes for fs_rename and fs_walk functions. Added simple identify functions for haiku.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20302 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Gerasim Troeglazov
2007-03-02 07:48:19 +00:00
parent 6b3592ca4b
commit 7106362e9c
11 changed files with 664 additions and 479 deletions
+5 -4
View File
@@ -2,8 +2,10 @@ SubDir HAIKU_TOP src add-ons kernel file_systems ntfs ;
SubDirHdrs [ FDirName $(SUBDIR) libntfs ] ;
SubDirCcFlags -DHAVE_CONFIG_H=1 -D_READ_ONLY_=1 ;
SubDirC++Flags -DHAVE_CONFIG_H=1 -D_READ_ONLY_=1 ;
SetSubDirSupportedPlatformsBeOSCompatible ;
SubDirCcFlags -DHAVE_CONFIG_H=1 ;
SubDirC++Flags -DHAVE_CONFIG_H=1 ;
UsePrivateHeaders kernel ;
@@ -14,8 +16,7 @@ KernelAddon ntfs :
ntfsdir.c
volume_util.c
fs_func.c
kernel_interface.cpp
kernel_cpp.cpp
kernel_interface.c
:
libntfs.a
;
@@ -54,8 +54,13 @@ status_t set_mime(vnode *node, const char *filename)
}
#ifdef __HAIKU__
status_t
fs_open_attrib_dir(void *_ns, void *_node, void **_cookie)
#else
int
fs_open_attrib_dir(void *_ns, void *_node, void **_cookie)
#endif
{
nspace *ns = (nspace *)_ns;
int result = B_NO_ERROR;
@@ -80,8 +85,13 @@ exit:
return result;
}
#ifdef __HAIKU__
status_t
fs_close_attrib_dir(void *_ns, void *_node, void *_cookie)
#else
int
fs_close_attrib_dir(void *_ns, void *_node, void *_cookie)
#endif
{
nspace *ns = (nspace *)_ns;
@@ -98,9 +108,13 @@ fs_close_attrib_dir(void *_ns, void *_node, void *_cookie)
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_free_attrib_dir_cookie(void *_ns, void *_node, void *_cookie)
#else
int
fs_free_attrib_dir_cookie(void *_ns, void *_node, void *_cookie)
#endif
{
nspace *ns = (nspace *)_ns;
int result = B_NO_ERROR;
@@ -127,9 +141,13 @@ exit:
return result;
}
#ifdef __HAIKU__
status_t
fs_rewind_attrib_dir(void *_ns, void *_node, void *_cookie)
#else
int
fs_rewind_attrib_dir(void *_ns, void *_node, void *_cookie)
#endif
{
nspace *ns = (nspace *)_ns;
int result = B_NO_ERROR;
@@ -156,8 +174,13 @@ exit:
}
#ifdef __HAIKU__
status_t
fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, struct dirent *entry, size_t bufsize, uint32 *num)
#else
int
fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, long *num, struct dirent *entry, size_t bufsize)
#endif
{
nspace *ns = (nspace *)_ns;
vnode *node = (vnode *)_node;
@@ -187,7 +210,28 @@ fs_read_attrib_dir(void *_ns, void *_node, void *_cookie, struct dirent *entry,
return B_NO_ERROR;
}
#ifndef __HAIKU__
int
fs_read_attrib_stat(void *_ns, void *_node, const char *name, struct attr_info *buf)
{
nspace *ns = (nspace *)_ns;
vnode *node = (vnode *)_node;
if (strcmp(name, "BEOS:TYPE"))
return ENOENT;
if (node->mime == NULL) {
return ENOENT;
}
buf->type = MIME_STRING_TYPE;
buf->size = strlen(node->mime) + 1;
return 0;
}
#endif
#ifdef __HAIKU__
status_t
fs_open_attrib(void *_ns, void *_node, const char *name, int openMode, fs_cookie *_cookie)
{
@@ -219,22 +263,25 @@ exit:
return result;
}
#endif
#ifdef __HAIKU__
status_t
fs_close_attrib(void *_ns, void *_node, fs_cookie cookie)
{
return B_NO_ERROR;
}
#endif
#ifdef __HAIKU__
status_t
fs_free_attrib_cookie(void *_ns, void *_node, fs_cookie cookie)
{
return B_NO_ERROR;
}
#endif
#ifdef __HAIKU__
status_t
fs_read_attrib_stat(void *_ns, void *_node, fs_cookie _cookie, struct stat *stat)
{
@@ -267,10 +314,15 @@ exit:
return B_NO_ERROR;
}
#endif
#ifdef __HAIKU__
status_t
fs_read_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, void *buffer, size_t *_length)
#else
int
fs_read_attrib(void *_ns, void *_node, const char *name, int type, void *buffer, size_t *_length, off_t pos)
#endif
{
nspace *ns = (nspace *)_ns;
vnode *node = (vnode *)_node;
@@ -280,10 +332,12 @@ fs_read_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos, void *buffe
ERRPRINT("fs_read_attr - ENTER\n");
#ifdef __HAIKU_
if (_cookie != &kBeOSTypeCookie) {
result = ENOENT;
goto exit;
}
#endif
if (node->mime == NULL) {
result = ENOENT;
@@ -309,9 +363,13 @@ exit:
}
#ifdef __HAIKU__
status_t
fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos,
const void *buffer, size_t *_length)
fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos,const void *buffer, size_t *_length)
#else
int
fs_write_attrib(void *_ns, void *_node, const char *name, int type, const void *buffer, size_t *_length, off_t pos)
#endif
{
nspace *ns = (nspace *)_ns;
int result = B_NO_ERROR;
@@ -321,11 +379,12 @@ fs_write_attrib(void *_ns, void *_node, fs_cookie _cookie, off_t pos,
ERRPRINT("fs_write_attr - ENTER\n");
*_length = 0;
#ifdef __HAIKU_
if (_cookie != &kBeOSTypeCookie) {
result = ENOSYS;
goto exit;
}
#endif
exit:
ERRPRINT("fs_write_attrib - EXIT, result is %s\n", strerror(result));
@@ -14,6 +14,9 @@
status_t set_mime(vnode *node, const char *filename);
#ifdef __HAIKU__
status_t fs_open_attrib_dir(void *_vol, void *_node, void **_cookie);
status_t fs_close_attrib_dir(void *_vol, void *_node, void *_cookie);
status_t fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie);
@@ -26,4 +29,17 @@ status_t fs_read_attrib_stat(void *_vol, void *_node, fs_cookie _cookie, struct
status_t fs_read_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos,void *buffer, size_t *_length);
status_t fs_write_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos, const void *buffer, size_t *_length);
#else
int fs_open_attrib_dir(void *_vol, void *_node, void **_cookie);
int fs_close_attrib_dir(void *_vol, void *_node, void *_cookie);
int fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie);
int fs_rewind_attrib_dir(void *_vol, void *_node, void *_cookie);
int fs_read_attrib_dir(void *_vol, void *_node, void *_cookie, long *num, struct dirent *buf, size_t bufsize);
int fs_read_attrib_stat(void *_vol, void *_node, const char *name, struct attr_info *buf);
int fs_read_attrib(void *_vol, void *_node, const char *name, int type, void *buf, size_t *len, off_t pos);
int fs_write_attrib(void *_vol, void *_node, const char *name, int type, const void *buf, size_t *len, off_t pos);
#endif //__HAIKU__
#endif
+272 -96
View File
@@ -2,7 +2,7 @@
* Copyright (c) 2000-2004 Anton Altaparmakov
* Copyright (c) 2002-2006 Szabolcs Szakacsits
*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
@@ -34,84 +34,85 @@
#include <time.h>
#include <malloc.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include <fs_interface.h>
#include <fs_cache.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <fs_index.h>
#include <fs_query.h>
#include <fs_volume.h>
#include "ntfs.h"
#include "attributes.h"
#include "lock.h"
#include "volume_util.h"
status_t fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid );
status_t fs_unmount(void *_ns);
status_t fs_rfsstat(void *_ns, struct fs_info *);
status_t fs_wfsstat(void *_vol, const struct fs_info *fss, uint32 mask);
status_t fs_sync(void *_ns);
status_t fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type);
status_t fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize);
status_t fs_read_vnode(void *_ns, vnode_id vnid, void **_node, bool reenter);
status_t fs_write_vnode(void *_ns, void *_node, bool reenter);
status_t fs_remove_vnode( void *_ns, void *_node, bool reenter );
status_t fs_access( void *ns, void *node, int mode );
status_t fs_rstat(void *_ns, void *_node, struct stat *st);
status_t fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask);
status_t fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid);
status_t fs_open(void *_ns, void *_node, int omode, void **cookie);
status_t fs_close(void *ns, void *node, void *cookie);
status_t fs_free_cookie(void *ns, void *node, void *cookie);
status_t fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len);
status_t fs_write(void *ns, void *node, void *cookie, off_t pos, const void *buf, size_t *len);
status_t fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid);
status_t fs_rmdir(void *_ns, void *dir, const char *name);
status_t fs_opendir(void* _ns, void* _node, void** cookie);
status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num );
status_t fs_rewinddir(void *_ns, void *_node, void *cookie);
status_t fs_closedir(void *_ns, void *_node, void *cookie);
status_t fs_free_dircookie(void *_ns, void *_node, void *cookie);
status_t fs_readlink(void *_ns, void *_node, char *buf, size_t *bufsize);
status_t fs_fsync(void *_ns, void *_node);
status_t fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname);
status_t fs_unlink(void *_ns, void *_node, const char *name);
status_t fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode);
void fs_free_identify_partition_cookie(partition_data *partition, void *_cookie);
status_t fs_scan_partition(int fd, partition_data *partition, void *_cookie);
float fs_identify_partition(int fd, partition_data *partition, void **_cookie);
#include "fs_func.h"
#ifndef _READ_ONLY_
static status_t do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir);
#endif
//not emplemented now
#ifdef __HAIKU__
typedef struct identify_cookie {
NTFS_BOOT_SECTOR boot;
} identify_cookie;
float
fs_identify_partition(int fd, partition_data *partition, void **_cookie)
{
return 0.0f;
NTFS_BOOT_SECTOR boot;
identify_cookie *cookie;
uint8 *buf=(uint8*)&boot;
// read in the boot sector
ERRPRINT("fs_identify_partition: read in the boot sector\n");
if (read_pos(fd, 0, (void*)&boot, 512) != 512) {
return -1;
}
// only check boot signature on hard disks to account for broken mtools
// behavior
// check boot signature
if (((buf[0x1fe] != 0x55) || (buf[0x1ff] != 0xaa)) && (buf[0x15] == 0xf8))
return -1;
//check boot signature NTFS
if (memcmp(buf+3, "NTFS ", 8)!=0)
return -1;
//allocate identify_cookie
cookie = (identify_cookie *)malloc(sizeof(identify_cookie));
if (!cookie)
return -1;
memcpy(&(cookie->boot),&boot,512);
*_cookie = cookie;
return 0.8f;
}
//not emplemented now
status_t
fs_scan_partition(int fd, partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
partition->status = B_PARTITION_VALID;
partition->flags |= B_PARTITION_FILE_SYSTEM;
partition->content_size = sle64_to_cpu(cookie->boot.number_of_sectors) * le16_to_cpu(cookie->boot.bpb.bytes_per_sector);
partition->block_size = le16_to_cpu(cookie->boot.bpb.bytes_per_sector);
partition->content_name = strdup("NTFS Volume");
return B_OK;
}
//not emplemented now
void
fs_free_identify_partition_cookie(partition_data *partition, void *_cookie)
{
identify_cookie *cookie = (identify_cookie *)_cookie;
free(cookie);
}
#endif //__HAIKU__
#ifdef __HAIKU__
status_t
fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid )
#else
int
fs_mount(nspace_id nsid, const char *device, ulong flags, void *parms, size_t len, void **data, vnode_id *vnid)
#endif
{
nspace *ns;
vnode *newNode = NULL;
@@ -119,7 +120,7 @@ fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void
status_t result = B_NO_ERROR;
ERRPRINT("fs_mount - ENTER\n");
ns = ntfs_malloc(sizeof(nspace));
if (!ns) {
result = ENOMEM;
@@ -138,11 +139,17 @@ fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void
strcpy(ns->devicePath,device);
sprintf(lockname, "ntfs_lock %lx", ns->id);
if ((result = recursive_lock_init(&(ns->vlock), lockname)) != 0) {
#ifdef __HAIKU__
if ((result = recursive_lock_init(&(ns->vlock), lockname)) != 0)
#else
if ((result = new_lock(&(ns->vlock), lockname)) != B_OK)
#endif
{
ERRPRINT("fs_mount - error creating lock (%s)\n", strerror(result));
goto exit;
}
ns->ntvol=utils_mount_volume(device,0,true);
if(ns->ntvol!=NULL)
result = B_NO_ERROR;
@@ -183,8 +190,13 @@ exit:
return result;
}
#ifdef __HAIKU__
status_t
fs_unmount(void *_ns)
#else
int
fs_unmount(void *_ns)
#endif
{
nspace *ns = (nspace*)_ns;
status_t result = B_NO_ERROR;
@@ -192,8 +204,12 @@ fs_unmount(void *_ns)
ERRPRINT("fs_unmount - ENTER\n");
ntfs_device_umount( ns->ntvol, true );
#ifdef __HAIKU__
recursive_lock_destroy(&(ns->vlock));
#else
free_lock(&(ns->vlock));
#endif
free( ns );
@@ -202,8 +218,13 @@ fs_unmount(void *_ns)
return result;
}
#ifdef __HAIKU__
status_t
fs_rfsstat( void *_ns, struct fs_info * fss )
#else
int
fs_rfsstat( void *_ns, struct fs_info * fss )
#endif
{
nspace *ns = (nspace*)_ns;
int i;
@@ -242,15 +263,24 @@ fs_rfsstat( void *_ns, struct fs_info * fss )
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_wfsstat(void *_vol, const struct fs_info * fss, uint32 mask)
#else
int
fs_wfsstat(void *_vol, struct fs_info *fss, long mask)
#endif
{
nspace* ns = (nspace*)_vol;
status_t result = B_NO_ERROR;
LOCK_VOL(ns);
#ifdef __HAIKU__
if (mask & FS_WRITE_FSINFO_NAME) {
#else
if (mask & WFSSTAT_NAME) {
#endif
result = ntfs_change_label( ns->ntvol, (char*)fss->volume_name );
goto exit;
}
@@ -263,8 +293,13 @@ exit:
}
#endif
#ifdef __HAIKU__
status_t
fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type)
#else
int
fs_walk(void *_ns, void *_base, const char *file, char **newpath, vnode_id *vnid)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *baseNode = (vnode*)_base;
@@ -317,6 +352,9 @@ fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type)
if( get_vnode( ns->id, *vnid, (void**)&newNode ) !=0 )
result = ENOENT;
if(newNode!=NULL)
newNode->parent_vnid = baseNode->vnid;
}
exit:
@@ -328,7 +366,7 @@ exit:
return result;
}
#ifdef __HAIKU__
status_t
fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize)
{
@@ -366,12 +404,17 @@ exit:
return result;
}
#endif
#ifdef __HAIKU__
status_t
fs_read_vnode(void *_ns, vnode_id vnid, void **node, bool reenter)
#else
int
fs_read_vnode(void *_ns, vnode_id vnid, char reenter, void **node)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *newNode = NULL;
@@ -424,8 +467,13 @@ exit:
return result;
}
#ifdef __HAIKU__
status_t
fs_write_vnode( void *_ns, void *_node, bool reenter )
#else
int
fs_write_vnode( void *_ns, void *_node, char reenter )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -448,8 +496,13 @@ fs_write_vnode( void *_ns, void *_node, bool reenter )
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_remove_vnode( void *_ns, void *_node, bool reenter )
#else
int
fs_remove_vnode( void *_ns, void *_node, char reenter )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -471,9 +524,14 @@ fs_remove_vnode( void *_ns, void *_node, bool reenter )
return result;
}
#endif
#ifdef __HAIKU__
status_t
fs_rstat( void *_ns, void *_node, struct stat *stbuf )
#else
int
fs_rstat( void *_ns, void *_node, struct stat *stbuf )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -570,8 +628,13 @@ exit:
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
#else
int
fs_wstat(void *_vol, void *_node, struct stat *st, long mask)
#endif
{
nspace *ns = (nspace*)_vol;
vnode *node = (vnode*)_node;
@@ -588,8 +651,11 @@ fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
goto exit;
}
#ifdef __HAIKU__
if ( mask & FS_WRITE_STAT_SIZE ) {
#else
if (mask & WSTAT_SIZE) {
#endif
ERRPRINT("fs_wstat: setting file size to %Lx\n", st->st_size);
if ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ) {
@@ -606,22 +672,31 @@ fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask)
ntfs_attr_close(na);
ntfs_mark_free_space_outdated(ns);
//notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL);
#ifdef __HAIKU__
notify_stat_changed(ns->id, MREF(ni->mft_no), mask);
#else
notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL);
#endif
}
}
#ifdef __HAIKU__
if (mask & FS_WRITE_STAT_MTIME) {
#else
if (mask & WSTAT_MTIME) {
#endif
ERRPRINT("fs_wstat: setting modification time\n");
ni->last_access_time = st->st_atime;
ni->last_data_change_time = st->st_mtime;
ni->last_mft_change_time = st->st_ctime;
//notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL);
#ifdef __HAIKU__
notify_stat_changed(ns->id, MREF(ni->mft_no), mask);
#else
notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL);
#endif
}
exit:
@@ -629,7 +704,7 @@ exit:
if(ni)
ntfs_inode_close(ni);
ERRPRINT("dosfs_wstat: EXIT with (%s)\n", strerror(err));
ERRPRINT("dosfs_wstat: EXIT with (%s)\n", strerror(result));
UNLOCK_VOL(ns);
@@ -638,16 +713,23 @@ exit:
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_sync(void *_ns)
#else
int
fs_sync(void *_ns)
#endif
{
nspace *ns = (nspace *)_ns;
LOCK_VOL(ns);
ERRPRINT("fs_sync - ENTER\n");
// flush_device(DEV_FD(ns->ntvol->dev), 0);
#ifndef __HAIKU__
flush_device(DEV_FD(ns->ntvol->dev), 0);
#endif
ERRPRINT("fs_sync - EXIT\n");
@@ -658,8 +740,13 @@ fs_sync(void *_ns)
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_fsync(void *_ns, void *_node)
#else
int
fs_fsync(void *_ns, void *_node)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -696,9 +783,13 @@ exit:
}
#endif
#ifdef __HAIKU__
status_t
fs_open(void *_ns, void *_node, int omode, void **_cookie)
#else
int
fs_open(void *_ns, void *_node, int omode, void **_cookie)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -758,8 +849,13 @@ exit:
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid)
#else
int
fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, vnode_id *_vnid, void **_cookie)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *dir = (vnode*)_dir;
@@ -842,9 +938,14 @@ fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **
result = B_NO_ERROR;
result = publish_vnode(ns->id, *_vnid, (void*)newNode);
ntfs_mark_free_space_outdated(ns);
ntfs_mark_free_space_outdated(ns);
#ifdef __HAIKU__
notify_entry_created(ns->id, MREF( bi->mft_no ), name, *_vnid);
//notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, *_vnid, name);
#else
notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, *_vnid, name);
#endif
} else
result = errno;
}
@@ -873,9 +974,13 @@ exit:
}
#endif
#ifdef __HAIKU__
status_t
fs_read( void *_ns, void *_node, void *_cookie, off_t offset, void *buf, size_t *len )
#else
int
fs_read( void *_ns, void *_node, void *_cookie, off_t offset, void *buf, size_t *len )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -952,8 +1057,13 @@ exit2:
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf, size_t *len )
#else
int
fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf, size_t *len )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -1005,9 +1115,12 @@ fs_write( void *_ns, void *_node, void *_cookie, off_t offset, const void *buf,
if(ntfs_attr_truncate(na, offset + size))
size = na->data_size - offset;
else
#ifdef __HAIKU__
notify_stat_changed(ns->id, MREF(ni->mft_no), B_STAT_SIZE);
#else
notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL);
#endif
}
//notify_listener(B_STAT_CHANGED, ns->id, 0, 0, MREF(ni->mft_no), NULL); }
while (size) {
result = ntfs_attr_pwrite(na, offset, size, buf);
@@ -1042,8 +1155,13 @@ exit2:
}
#endif
#ifdef __HAIKU__
status_t
fs_close(void *ns, void *node, void *cookie)
#else
int
fs_close(void *ns, void *node, void *cookie)
#endif
{
ERRPRINT("fs_close - ENTER\n");
@@ -1051,8 +1169,13 @@ fs_close(void *ns, void *node, void *cookie)
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_free_cookie( void *ns, void *node, void *cookie )
#else
int
fs_free_cookie( void *ns, void *node, void *cookie )
#endif
{
ERRPRINT("fs_free_cookie - ENTER\n");
@@ -1063,9 +1186,13 @@ fs_free_cookie( void *ns, void *node, void *cookie )
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_access( void *ns, void *node, int mode )
#else
int
fs_access( void *ns, void *node, int mode )
#endif
{
ERRPRINT("fs_access - ENTER\n");
@@ -1073,8 +1200,13 @@ fs_access( void *ns, void *node, int mode )
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_readlink(void *_ns, void *_node, char *buff, size_t *buff_size)
#else
int
fs_readlink(void *_ns, void *_node, char *buff, size_t *buff_size)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
@@ -1169,8 +1301,13 @@ exit:
}
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode)
#else
int
fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *dir = (vnode*)_dir;
@@ -1231,12 +1368,15 @@ fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, i
set_mime(symnode, name);
if ((result = publish_vnode(ns->id, MREF(sym->mft_no), symnode)) != 0)
ERRPRINT("fs_symlink - new_vnode failed for vnid %Ld: %s\n", MREF(sym->mft_no), strerror(res));
ERRPRINT("fs_symlink - new_vnode failed for vnid %Ld: %s\n", MREF(sym->mft_no), strerror(result));
put_vnode(ns->id, MREF(sym->mft_no) );
// notify_listener(B_ENTRY_CREATED, ns->id, MREF(dir->ntnode->mft_no), 0, MREF(sym->mft_no), name);
#ifdef __HAIKU__
notify_entry_created(ns->id, MREF( bi->mft_no ), name, MREF(sym->mft_no));
#else
notify_listener(B_ENTRY_CREATED, ns->id, MREF(bi->mft_no), 0, MREF(sym->mft_no), name);
#endif
exit:
@@ -1254,8 +1394,13 @@ exit:
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid)
#else
int
fs_mkdir(void *_ns, void *_node, const char *name, int perms)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *dir = (vnode*)_node;
@@ -1280,13 +1425,14 @@ fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid)
result = ENOENT;
goto exit;
}
// if (is_vnode_removed(ns->id, MREF(dir->ntnode->mft_no)) > 0)
// {
// ERRPRINT("fs_mkdir - called in removed directory\n");
// result = EPERM;
// goto exit;
// }
#ifndef __HAIKU__
if (is_vnode_removed(ns->id, MREF(bi->mft_no)) > 0) {
ERRPRINT("fs_mkdir - called in removed directory\n");
result = EPERM;
goto exit;
}
#endif
if (! bi->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
result = EINVAL;
@@ -1316,15 +1462,19 @@ fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid)
set_mime(newNode, ".***");
result = publish_vnode(ns->id, vnid, (void*)newNode);
#ifdef __HAIKU__
*_vnid = vnid;
#endif
put_vnode(ns->id, MREF(ni->mft_no));
ntfs_mark_free_space_outdated(ns);
// notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, vnid, name);
#ifdef __HAIKU__
notify_entry_created(ns->id, MREF( bi->mft_no ), name, vnid);
#else
notify_listener(B_ENTRY_CREATED, ns->id, MREF( bi->mft_no ), 0, vnid, name);
#endif
}
else
result = errno;
@@ -1345,8 +1495,13 @@ exit:
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname)
#else
int
fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *odir = (vnode*)_odir;
@@ -1460,11 +1615,15 @@ fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *
ntfs_delete(oi, odi, uoldname, uoldname_len);
onode->parent_vnid = MREF( ndi->mft_no );
#ifdef __HAIKU__
notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( ndi->mft_no ), newname, onode->vnid );
notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED);
//notify_listener(B_ENTRY_MOVED, ns->id, MREF( odir->ntnode->mft_no ), MREF( ndir->ntnode->mft_no ), MREF( onode->ntnode->mft_no ), newname);
//notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, nvnid, "BEOS:TYPE");
#else
notify_listener(B_ENTRY_MOVED, ns->id, MREF( odi->mft_no ), MREF( ndi->mft_no ), MREF( onode->vnid ), newname);
notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, onode->vnid, "BEOS:TYPE");
#endif
put_vnode(ns->id, onode->vnid );
} else { //renaming
@@ -1505,11 +1664,13 @@ fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *
}
ntfs_delete(oi, odi, uoldname, uoldname_len);
#ifdef __HAIKU__
notify_entry_moved(ns->id, MREF( odi->mft_no ), oldname, MREF( odi->mft_no ), newname, onode->vnid );
notify_attribute_changed(ns->id, onode->vnid, "BEOS:TYPE", B_ATTR_CHANGED);
//notify_listener(B_ENTRY_MOVED, ns->id, MREF( odir->ntnode->mft_no ), MREF( ndir->ntnode->mft_no ), MREF( onode->ntnode->mft_no ), newname);
//notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, nvnid, "BEOS:TYPE");
#else
notify_listener(B_ENTRY_MOVED, ns->id, MREF( odi->mft_no ), MREF( odi->mft_no ), MREF( onode->vnid ), newname);
notify_listener(B_ATTR_CHANGED, ns->id, 0, 0, onode->vnid, "BEOS:TYPE");
#endif
put_vnode(ns->id, onode->vnid );
}
@@ -1597,9 +1758,14 @@ do_unlink(nspace *vol, vnode *dir, const char *name, bool isdir)
else
ni = NULL;
node->parent_vnid = dir->vnid;
//notify_listener(B_ENTRY_REMOVED, vol->id, MREF(dir->ntnode->mft_no), 0, vnid, NULL);
node->parent_vnid = dir->vnid;
#ifdef __HAIKU__
notify_entry_removed(vol->id, dir->vnid, name, vnid);
#else
notify_listener(B_ENTRY_REMOVED, vol->id, MREF(dir->vnid), 0, vnid, NULL);
#endif
result = remove_vnode(vol->id, vnid);
exit2:
put_vnode(vol->id, vnid);
@@ -1618,8 +1784,13 @@ exit1:
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_rmdir(void *_ns, void *_node, const char *name)
#else
int
fs_rmdir(void *_ns, void *_node, const char *name)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *dir = (vnode*)_node;
@@ -1659,8 +1830,13 @@ exit1:
#endif
#ifndef _READ_ONLY_
#ifdef __HAIKU__
status_t
fs_unlink(void *_ns, void *_node, const char *name)
#else
int
fs_unlink(void *_ns, void *_node, const char *name)
#endif
{
nspace *ns = (nspace*)_ns;
vnode *dir = (vnode*)_node;
@@ -1,270 +0,0 @@
/* kernel_interface - file system interface to Haiku's vnode layer
*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program/include file is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program (in the main directory of the Linux-NTFS
* distribution in the file COPYING); if not, write to the Free Software
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <time.h>
#include <lock.h>
#include <malloc.h>
#include <stdio.h>
#include <ByteOrder.h>
#include <fs_info.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include <fs_interface.h>
#include <fs_cache.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <fs_index.h>
#include <fs_query.h>
#include <fs_volume.h>
#include <util/kernel_cpp.h>
extern "C"{
status_t fs_mount( mount_id nsid, const char *device, ulong flags, const char *args, void **data, vnode_id *vnid );
status_t fs_unmount(void *_ns);
status_t fs_rfsstat(void *_ns, struct fs_info *);
status_t fs_wfsstat(void *_vol, const struct fs_info *fss, uint32 mask);
status_t fs_sync(void *_ns);
status_t fs_walk(void *_ns, void *_base, const char *file, vnode_id *vnid,int *_type);
status_t fs_get_vnode_name(void *_ns, void *_node, char *buffer, size_t bufferSize);
status_t fs_read_vnode(void *_ns, vnode_id vnid, void **_node, bool reenter);
status_t fs_write_vnode(void *_ns, void *_node, bool reenter);
status_t fs_remove_vnode( void *_ns, void *_node, bool reenter );
status_t fs_access( void *ns, void *node, int mode );
status_t fs_rstat(void *_ns, void *_node, struct stat *st);
status_t fs_wstat(void *_vol, void *_node, const struct stat *st, uint32 mask);
status_t fs_create(void *_ns, void *_dir, const char *name, int omode, int perms, void **_cookie, vnode_id *_vnid);
status_t fs_open(void *_ns, void *_node, int omode, void **cookie);
status_t fs_close(void *ns, void *node, void *cookie);
status_t fs_free_cookie(void *ns, void *node, void *cookie);
status_t fs_read(void *_ns, void *_node, void *cookie, off_t pos, void *buf, size_t *len);
status_t fs_write(void *ns, void *node, void *cookie, off_t pos, const void *buf, size_t *len);
status_t fs_mkdir(void *_ns, void *_node, const char *name, int perms, vnode_id *_vnid);
status_t fs_rmdir(void *_ns, void *dir, const char *name);
status_t fs_opendir(void* _ns, void* _node, void** cookie);
status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num );
status_t fs_rewinddir(void *_ns, void *_node, void *cookie);
status_t fs_closedir(void *_ns, void *_node, void *cookie);
status_t fs_free_dircookie(void *_ns, void *_node, void *cookie);
status_t fs_readlink(void *_ns, void *_node, char *buf, size_t *bufsize);
status_t fs_fsync(void *_ns, void *_node);
status_t fs_rename(void *_ns, void *_odir, const char *oldname, void *_ndir, const char *newname);
status_t fs_unlink(void *_ns, void *_node, const char *name);
status_t fs_create_symlink(void *_ns, void *_dir, const char *name, const char *target, int mode);
status_t fs_open_attrib_dir(void *_vol, void *_node, void **_cookie);
status_t fs_close_attrib_dir(void *_vol, void *_node, void *_cookie);
status_t fs_free_attrib_dir_cookie(void *_vol, void *_node, void *_cookie);
status_t fs_rewind_attrib_dir(void *_vol, void *_node, void *_cookie);
status_t fs_read_attrib_dir(void *_vol, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num);
status_t fs_open_attrib(void *_vol, void *_node, const char *name, int openMode,fs_cookie *_cookie);
status_t fs_close_attrib(void *_vol, void *_node, fs_cookie cookie);
status_t fs_free_attrib_cookie(void *_vol, void *_node, fs_cookie cookie);
status_t fs_read_attrib_stat(void *_vol, void *_node, fs_cookie _cookie, struct stat *stat);
status_t fs_read_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos,void *buffer, size_t *_length);
status_t fs_write_attrib(void *_vol, void *_node, fs_cookie _cookie, off_t pos, const void *buffer, size_t *_length);
void fs_free_identify_partition_cookie(partition_data *partition, void *_cookie);
status_t fs_scan_partition(int fd, partition_data *partition, void *_cookie);
float fs_identify_partition(int fd, partition_data *partition, void **_cookie);
};
static status_t
ntfs_std_ops(int32 op, ...)
{
switch (op) {
case B_MODULE_INIT:
return B_OK;
case B_MODULE_UNINIT:
return B_OK;
default:
return B_ERROR;
}
}
static file_system_module_info sNTFSFileSystem = {
{
"file_systems/ntfs" B_CURRENT_FS_API_VERSION,
0,
ntfs_std_ops,
},
"ntfs File System",
// scanning
fs_identify_partition,
fs_scan_partition,
fs_free_identify_partition_cookie,
NULL, // free_partition_content_cookie()
&fs_mount,
&fs_unmount,
&fs_rfsstat,
#ifdef _READ_ONLY_
NULL,
#else
&fs_wfsstat,
#endif
NULL,
/* vnode operations */
&fs_walk,
&fs_get_vnode_name,
&fs_read_vnode,
&fs_write_vnode,
#ifdef _READ_ONLY_
NULL,
#else
&fs_remove_vnode,
#endif
/* VM file access */
NULL, // &fs_can_page
NULL, // &fs_read_pages
NULL, // &fs_write_pages
NULL, // &fs_get_file_map
NULL, // &fs_ioctl
NULL, // &fs_set_flags
NULL, // &fs_select
NULL, // &fs_deselect
#ifdef _READ_ONLY_
NULL,
#else
&fs_fsync,
#endif
&fs_readlink,
#ifdef _READ_ONLY_
NULL,
NULL,
NULL,
NULL,
NULL,
#else
NULL, // write link
&fs_create_symlink,
NULL, // &fs_link,
&fs_unlink,
&fs_rename,
#endif
&fs_access,
&fs_rstat,
#ifdef _READ_ONLY_
NULL,
#else
&fs_wstat,
#endif
/* file operations */
#ifdef _READ_ONLY_
NULL,
#else
&fs_create,
#endif
&fs_open,
&fs_close,
&fs_free_cookie,
&fs_read,
#ifdef _READ_ONLY_
NULL,
#else
&fs_write,
#endif
/* directory operations */
#ifdef _READ_ONLY_
NULL,
NULL,
#else
&fs_mkdir,
&fs_rmdir,
#endif
&fs_opendir,
&fs_closedir,
&fs_free_dircookie,
&fs_readdir,
&fs_rewinddir,
/* attribute directory operations */
&fs_open_attrib_dir,
&fs_close_attrib_dir,
&fs_free_attrib_dir_cookie,
&fs_read_attrib_dir,
&fs_rewind_attrib_dir,
/* attribute operations */
NULL, //&fs_create_attr,
&fs_open_attrib,
&fs_close_attrib,
&fs_free_attrib_cookie,
&fs_read_attrib,
&fs_write_attrib,
&fs_read_attrib_stat,
NULL, //&fs_write_attr_stat,
NULL, //&fs_rename_attr,
NULL, //&fs_remove_attr,
/* index directory & index operations */
NULL, // &fs_open_index_dir
NULL, // &fs_close_index_dir
NULL, // &fs_free_index_dir_cookie
NULL, // &fs_read_index_dir
NULL, // &fs_rewind_index_dir
NULL, // &fs_create_index
NULL, // &fs_remove_index
NULL, // &fs_stat_index
/* query operations */
NULL, // &fs_open_query
NULL, // &fs_close_query
NULL, // &fs_free_query_cookie
NULL, // &fs_read_query
NULL, // &fs_rewind_query
};
module_info *modules[] = {
(module_info *)&sNTFSFileSystem,
NULL,
};
@@ -5,10 +5,54 @@
#include <lock.h>
#ifdef __HAIKU__
typedef recursive_lock lock;
#define LOCK(l) recursive_lock_lock(&l);
#define UNLOCK(l) recursive_lock_unlock(&l);
#else
typedef struct lock lock;
typedef struct mlock mlock;
struct lock {
sem_id s;
long c;
};
struct mlock {
sem_id s;
};
extern int new_lock(lock *l, const char *name);
extern int free_lock(lock *l);
static inline status_t LOCK(lock *l)
{
if (atomic_add(&(l->c), -1) <= 0)
return acquire_sem(l->s);
return B_OK;
}
static inline status_t UNLOCK(lock *l)
{
if (atomic_add(&(l->c), 1) < 0)
return release_sem(l->s);
return B_OK;
}
#define LOCK(l) if (atomic_add(&l.c, -1) <= 0) acquire_sem(l.s);
#define UNLOCK(l) if (atomic_add(&l.c, 1) < 0) release_sem(l.s);
extern int new_mlock(mlock *l, long c, const char *name);
extern int free_mlock(mlock *l);
#define LOCKM(l,cnt) acquire_sem_etc(l.s, cnt, 0, 0)
#define UNLOCKM(l,cnt) release_sem_etc(l.s, cnt, 0)
#endif //__HAIKU__
#endif
+20 -3
View File
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -24,15 +24,28 @@
extern "C" {
#endif
#include <KernelExport.h>
#include <NodeMonitor.h>
#ifdef __HAIKU__
#include <fs_interface.h>
#include <kernel/lock.h>
#include <fs_info.h>
#include <fs_cache.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <fs_index.h>
#include <fs_query.h>
#include <fs_volume.h>
#include <NodeMonitor.h>
#include <util/kernel_cpp.h>
#else
#include "fsproto.h"
#include "lock.h"
#define publish_vnode new_vnode
#endif
#include "config.h"
#include "attrib.h"
@@ -98,7 +111,11 @@ typedef struct nspace
{
ntfs_volume *ntvol;
char devicePath[MAX_PATH];
#ifdef __HAIKU__
mount_id id;
#else
nspace_id id;
#endif
int free_cluster_count;
char volumeLabel[MAX_PATH];
+211 -91
View File
@@ -1,6 +1,6 @@
/* ntfsdir.c - directory functions
*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -32,56 +32,109 @@
#include <time.h>
#include <malloc.h>
#include <KernelExport.h>
#include <NodeMonitor.h>
#include <fs_interface.h>
#include <fs_cache.h>
#include <fs_attr.h>
#include <fs_info.h>
#include <fs_index.h>
#include <fs_query.h>
#include <fs_volume.h>
#include "ntfs.h"
#include "attributes.h"
#include "lock.h"
#include "ntfsdir.h"
//callback function for readdir()
static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type);
static int _ntfs_dirent_filler(void *_dirent, const ntfschar *name,
static
int _ntfs_dirent_dot_filler(void *_dirent, const ntfschar *name,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type)
{
char *filename = NULL;
dircookie *cookie = (dircookie*)_dirent;
if (name_type == FILE_NAME_DOS)
if (name_type == FILE_NAME_DOS)return 0;
if (ntfs_ucstombs(name, name_len, &filename, 0) < 0)
{
ERRPRINT("Skipping unrepresentable filename\n");
return 0;
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || cookie->show_sys_files) {
if(cookie->readed==1) {
cookie->pos=pos;
cookie->readed = 0;
return -1;
} else {
if (ntfs_ucstombs(name, name_len, &filename, 0) < 0)
return -1;
strcpy(cookie->name,filename);
cookie->ino=MREF(mref);
cookie->readed = 1;
return 0;
}
}
if(strcmp(filename,".")==0 || strcmp(filename,"..")==0)
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || false)
{
struct direntry *ent = (direntry*)ntfs_calloc(sizeof(direntry));
ent->name = (char*)ntfs_calloc(strlen(filename)+1);
strcpy(ent->name,filename);
ent->dev=cookie->dev;
ent->ino=MREF(mref);
ent->next = NULL;
if(cookie->root==NULL)
{
cookie->root = ent;
cookie->walk = ent;
}
if(cookie->last != NULL)
cookie->last->next = ent;
cookie->last = ent;
} else {
free(filename);
return -1;
}
free(filename);
return 0;
}
static
int _ntfs_dirent_filler(void *_dirent, const ntfschar *name,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type)
{
char *filename = NULL;
dircookie *cookie = (dircookie*)_dirent;
if (name_type == FILE_NAME_DOS)return 0;
if (ntfs_ucstombs(name, name_len, &filename, 0) < 0)
{
ERRPRINT("Skipping unrepresentable filename\n");
return 0;
}
if(strcmp(filename,".")==0 || strcmp(filename,"..")==0)
return 0;
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || false)
{
struct direntry *ent = (direntry*)ntfs_calloc(sizeof(direntry));
ent->name = (char*)ntfs_calloc(strlen(filename)+1);
strcpy(ent->name,filename);
ent->dev=cookie->dev;
ent->ino=MREF(mref);
ent->next = NULL;
if(cookie->root==NULL)
{
cookie->root = ent;
cookie->walk = ent;
}
if(cookie->last != NULL)
cookie->last->next = ent;
cookie->last = ent;
}
free(filename);
return 0;
}
#ifdef __HAIKU__
status_t
fs_free_dircookie( void *_ns, void *node, void *cookie )
#else
int
fs_free_dircookie( void *_ns, void *node, void *cookie )
#endif
{
nspace *ns = (nspace*)_ns;
@@ -97,20 +150,25 @@ fs_free_dircookie( void *_ns, void *node, void *cookie )
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_opendir( void *_ns, void *_node, void **_cookie )
#else
int
fs_opendir( void *_ns, void *_node, void **_cookie )
#endif
{
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
dircookie *cookie = (dircookie*)ntfs_calloc( sizeof(dircookie) );
int result = B_NO_ERROR;
ntfs_inode *ni=NULL;
dircookie *cookie = (dircookie*)ntfs_calloc( sizeof(dircookie) );
u64 pos=0;
LOCK_VOL(ns);
ERRPRINT("fs_opendir - ENTER\n");
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
@@ -121,37 +179,66 @@ fs_opendir( void *_ns, void *_node, void **_cookie )
result = EMFILE;
goto exit;
}
if ( cookie != NULL ) {
cookie->pos = 0;
cookie->ino = 0;
cookie->readed = 0;
cookie->name[0] = 0;
cookie->show_sys_files = ns->show_sys_files;
if ( cookie != NULL )
{
cookie->dev = ns->id;
cookie->pos = 0;
//cookie->walk_dir = ni;
cookie->vnid = node->vnid;
cookie->root = NULL;
cookie->last = NULL;
cookie->walk = NULL;
*_cookie = (void*)cookie;
}
else
result = ENOMEM;
exit:
exit:
if(ni)
ntfs_inode_close(ni);
ntfs_inode_close(ni);
ERRPRINT("fs_opendir - EXIT\n");
UNLOCK_VOL(ns);
return result;
}
#ifdef __HAIKU__
status_t
fs_closedir( void *_ns, void *node, void *_cookie )
#else
int
fs_closedir( void *_ns, void *node, void *_cookie )
#endif
{
nspace *ns = (nspace*)_ns;
nspace *ns = (nspace*)_ns;
dircookie *cookie = (dircookie*)_cookie;
struct direntry *entry,*entrynext;
LOCK_VOL(ns);
ERRPRINT("fs_closedir - ENTER\n");
entry=cookie->root;
if(entry)
for(;;)
{
entrynext = entry->next;
if(entry->name)
free(entry->name);
if(entry)
free(entry);
entry = entrynext;
if(!entry)
break;
}
ERRPRINT("fs_closedir - EXIT\n");
UNLOCK_VOL(ns);
@@ -159,55 +246,81 @@ fs_closedir( void *_ns, void *node, void *_cookie )
return B_NO_ERROR;
}
#ifdef __HAIKU__
status_t
fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num )
#else
int
fs_readdir(void *_ns, void *_node, void *_cookie, long *num, struct dirent *buf, size_t bufsize)
#endif
{
int result = B_NO_ERROR;
nspace *ns = (nspace*)_ns;
vnode *node = (vnode*)_node;
dircookie *cookie = (dircookie*)_cookie;
uint32 nameLength = bufsize - sizeof(buf) + 1, realLen;
int result = B_NO_ERROR;
ntfs_inode *ni=NULL;
uint32 nameLength = bufsize - sizeof(buf) + 1, realLen;
u64 pos=0;
LOCK_VOL(ns);
ERRPRINT("fs_readdir - ENTER\n");
ERRPRINT("fs_readdir - ENTER:\n");
if (!ns || !node || !cookie || !num || bufsize < sizeof(buf)) {
result = EINVAL;
goto exit;
if (!ns || !node || !cookie || !num || bufsize < sizeof(buf))
{
result = -1;
goto quit;
}
if(cookie->readed == 1) {
result = ENOENT;
goto exit;
}
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
goto exit;
}
result = ntfs_readdir(ni, &cookie->pos, cookie, (ntfs_filldir_t)_ntfs_dirent_filler);
if(result==0) {
realLen = nameLength>255?255:nameLength;
buf->d_dev = ns->id;
buf->d_ino = cookie->ino;
memcpy(buf->d_name,cookie->name, realLen+1);
buf->d_reclen = sizeof(buf) + realLen - 1;
result = B_NO_ERROR;
if(cookie->pos==0)
{
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
goto quit;
}
ntfs_readdir(ni, &pos, cookie, (ntfs_filldir_t)_ntfs_dirent_dot_filler);
cookie->pos+=2;
}
else
result = ENOENT;
ERRPRINT("fs_readdir - FILE: [%s]\n",buf->d_name);
exit:
if(ni)
ntfs_inode_close(ni);
if(cookie->pos==2)
{
ni = ntfs_inode_open(ns->ntvol, node->vnid);
if(ni==NULL) {
result = ENOENT;
goto quit;
}
ntfs_readdir(ni, &pos, cookie, (ntfs_filldir_t)_ntfs_dirent_filler);
cookie->pos++;
}
if(cookie->root==NULL || cookie->last==NULL)
{
result = -1;
goto quit;
}
if(cookie->walk==NULL)
{
result = ENOENT;
goto quit;
}
realLen = ( strlen(cookie->walk->name)>=nameLength?(nameLength):(strlen(cookie->walk->name)) )+1;
buf->d_dev = cookie->walk->dev;
buf->d_ino = cookie->walk->ino;
memcpy(buf->d_name,cookie->walk->name, realLen);
buf->d_reclen = sizeof(buf) + realLen - 1;
cookie->walk = cookie->walk->next;
ERRPRINT("fs_readdir - FILE: %s\n",buf->d_name);
quit:
if ( result == B_NO_ERROR )
*num = 1;
else
@@ -215,29 +328,36 @@ exit:
if ( result == ENOENT )
result = B_NO_ERROR;
if(ni)
ntfs_inode_close(ni);
ERRPRINT("fs_readdir - EXIT result (%s)\n", strerror(result));
ERRPRINT("fs_readdir - EXIT, result is %s\n", strerror(result));
UNLOCK_VOL(ns);
return result;
}
#ifdef __HAIKU__
status_t
fs_rewinddir( void *_ns, void *_node, void *_cookie )
#else
int
fs_rewinddir( void *_ns, void *_node, void *_cookie )
#endif
{
nspace *ns = (nspace*)_ns;
dircookie *cookie = (dircookie*)_cookie;
int result = EINVAL;
dircookie *cookie = (dircookie*)_cookie;
LOCK_VOL(ns);
ERRPRINT("fs_rewinddir - ENTER\n");
if ( cookie != NULL ) {
cookie->pos = 0;
cookie->ino = 0;
cookie->readed = 0;
cookie->name[0] = 0;
if ( cookie != NULL )
{
//cookie->pos = 0;
cookie->walk = cookie->root;
result = B_NO_ERROR;
}
ERRPRINT("fs_rewinddir - EXIT, result is %s\n", strerror(result));
+26 -4
View File
@@ -22,19 +22,41 @@
#define _NTFSDIR_H
typedef struct direntry
{
char *name;
dev_t dev;
ino_t ino;
struct direntry *next;
} direntry;
typedef struct dircookie
{
dev_t dev;
vnode_id vnid;
struct direntry * root;
struct direntry * last;
struct direntry * walk;
u64 pos;
int readed;
ino_t ino;
BOOL show_sys_files;
char name[MAX_PATH];
} dircookie;
#ifdef __HAIKU__
status_t fs_free_dircookie( void *_ns, void *node, void *cookie );
status_t fs_opendir( void *_ns, void *_node, void **_cookie );
status_t fs_closedir( void *_ns, void *node, void *_cookie );
status_t fs_rewinddir( void *_ns, void *_node, void *_cookie );
status_t fs_readdir( void *_ns, void *_node, void *_cookie, struct dirent *buf, size_t bufsize, uint32 *num );
#else
int fs_free_dircookie( void *_ns, void *node, void *cookie );
int fs_opendir( void *_ns, void *_node, void **_cookie );
int fs_closedir( void *_ns, void *node, void *_cookie );
int fs_rewinddir( void *_ns, void *_node, void *_cookie );
int fs_readdir(void *_ns, void *_node, void *cookie, long *num, struct dirent *buf, size_t bufsize);
#endif //__HAIKU__
#endif
@@ -1,6 +1,6 @@
/* volume_util.c - volume functions
*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
@@ -1,6 +1,6 @@
/* volume_util.h - volume functions
*
* Copyright (c) 2006 Troeglazov Gerasim (3dEyes**)
* Copyright (c) 2006-2007 Troeglazov Gerasim (3dEyes**)
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published