marked files whose name has a dot initial as "hidden" if option hide_dot_files

PERMISSION_HANDLING_BRANCH
Jean-Pierre André 2010-05-25 09:58:36 +02:00
parent 51a9ab8c48
commit 3745d0a1e3
6 changed files with 138 additions and 16 deletions

View File

@ -107,6 +107,9 @@ typedef enum {
NV_ReadOnly, /* 1: Volume is read-only. */
NV_CaseSensitive, /* 1: Volume is mounted case-sensitive. */
NV_LogFileEmpty, /* 1: $logFile journal is empty. */
NV_ShowSysFiles, /* 1: Show NTFS metafiles. */
NV_ShowHidFiles, /* 1: Show files marked hidden. */
NV_HideDotFiles, /* 1: Set hidden flag on dot files */
} ntfs_volume_state_bits;
#define test_nvol_flag(nv, flag) test_bit(NV_##flag, (nv)->state)
@ -125,6 +128,18 @@ typedef enum {
#define NVolSetLogFileEmpty(nv) set_nvol_flag(nv, LogFileEmpty)
#define NVolClearLogFileEmpty(nv) clear_nvol_flag(nv, LogFileEmpty)
#define NVolShowSysFiles(nv) test_nvol_flag(nv, ShowSysFiles)
#define NVolSetShowSysFiles(nv) set_nvol_flag(nv, ShowSysFiles)
#define NVolClearShowSysFiles(nv) clear_nvol_flag(nv, ShowSysFiles)
#define NVolShowHidFiles(nv) test_nvol_flag(nv, ShowHidFiles)
#define NVolSetShowHidFiles(nv) set_nvol_flag(nv, ShowHidFiles)
#define NVolClearShowHidFiles(nv) clear_nvol_flag(nv, ShowHidFiles)
#define NVolHideDotFiles(nv) test_nvol_flag(nv, HideDotFiles)
#define NVolSetHideDotFiles(nv) set_nvol_flag(nv, HideDotFiles)
#define NVolClearHideDotFiles(nv) clear_nvol_flag(nv, HideDotFiles)
/*
* NTFS version 1.1 and 1.2 are used by Windows NT4.
* NTFS version 2.x is used by Windows 2000 Beta
@ -271,6 +286,8 @@ extern void ntfs_mount_error(const char *vol, const char *mntpoint, int err);
extern int ntfs_volume_get_free_space(ntfs_volume *vol);
extern int ntfs_set_shown_files(ntfs_volume *vol,
BOOL show_sys_files, BOOL show_hid_files, BOOL hide_dot_files);
extern int ntfs_set_locale(void);
#endif /* defined _NTFS_VOLUME_H */

View File

@ -858,6 +858,9 @@ static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
{
FILE_NAME_ATTR *fn = &ie->key.file_name;
unsigned dt_type;
BOOL metadata;
int res;
MFT_REF mref;
ntfs_log_trace("Entering.\n");
@ -877,9 +880,20 @@ static int ntfs_filldir(ntfs_inode *dir_ni, s64 *pos, u8 ivcn_bits,
dt_type = NTFS_DT_UNKNOWN;
else
dt_type = NTFS_DT_REG;
return filldir(dirent, fn->file_name, fn->file_name_length,
fn->file_name_type, *pos,
le64_to_cpu(ie->indexed_file), dt_type);
/* return metadata files and hidden files if requested */
mref = le64_to_cpu(ie->indexed_file);
metadata = (MREF(mref) != FILE_root) && (MREF(mref) < FILE_first_user);
if ((!metadata && (NVolShowHidFiles(dir_ni->vol)
|| !(fn->file_attributes & FILE_ATTR_HIDDEN)))
|| (NVolShowSysFiles(dir_ni->vol) && (NVolShowHidFiles(dir_ni->vol)
|| metadata))) {
res = filldir(dirent, fn->file_name, fn->file_name_length,
fn->file_name_type, *pos,
mref, dt_type);
} else
res = 0;
return (res);
}
/**
@ -1397,6 +1411,11 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
ni->flags = FILE_ATTR_SYSTEM;
}
ni->flags |= FILE_ATTR_ARCHIVE;
if (NVolHideDotFiles(dir_ni->vol)
&& (name_len > 1)
&& (name[0] == const_cpu_to_le16('.'))
&& (name[1] != const_cpu_to_le16('.')))
ni->flags |= FILE_ATTR_HIDDEN;
/*
* Set compression flag according to parent directory
* unless NTFS version < 3.0 or cluster size > 4K
@ -1536,6 +1555,7 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
else
fn->file_attributes |= ni->flags & FILE_ATTR_COMPRESSED;
fn->file_attributes |= FILE_ATTR_ARCHIVE;
fn->file_attributes |= ni->flags & FILE_ATTR_HIDDEN;
fn->creation_time = ni->creation_time;
fn->last_data_change_time = ni->last_data_change_time;
fn->last_mft_change_time = ni->last_mft_change_time;

View File

@ -489,6 +489,10 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
ntfs_upcase_table_build(vol->upcase,
vol->upcase_len * sizeof(ntfschar));
/* by default, all files are shown and not marked hidden */
NVolSetShowSysFiles(vol);
NVolSetShowHidFiles(vol);
NVolClearHideDotFiles(vol);
if (flags & MS_RDONLY)
NVolSetReadOnly(vol);
@ -1195,6 +1199,36 @@ error_exit:
return NULL;
}
/*
* Set appropriate flags for showing NTFS metafiles
* or files marked as hidden.
* Not set in ntfs_mount() to avoid breaking existing tools.
*/
int ntfs_set_shown_files(ntfs_volume *vol,
BOOL show_sys_files, BOOL show_hid_files,
BOOL hide_dot_files)
{
int res;
res = -1;
if (vol) {
NVolClearShowSysFiles(vol);
NVolClearShowHidFiles(vol);
NVolClearHideDotFiles(vol);
if (show_sys_files)
NVolSetShowSysFiles(vol);
if (show_hid_files)
NVolSetShowHidFiles(vol);
if (hide_dot_files)
NVolSetHideDotFiles(vol);
res = 0;
}
if (res)
ntfs_log_error("Failed to set file visibility\n");
return (res);
}
/**
* ntfs_mount - open ntfs volume
* @name: name of device/file to open

View File

@ -209,6 +209,8 @@ typedef struct {
ntfs_atime_t atime;
BOOL ro;
BOOL show_sys_files;
BOOL show_hid_files;
BOOL hide_dot_files;
BOOL silent;
BOOL recover;
BOOL hiberfile;
@ -374,6 +376,11 @@ static u64 ntfs_fuse_inode_lookup(fuse_ino_t parent, const char *name)
if (dir_ni) {
/* Lookup file */
inum = ntfs_inode_lookup_by_mbsname(dir_ni, name);
/* never return inodes 0 and 1 */
if (MREF(inum) <= 1) {
inum = (u64)-1;
errno = ENOENT;
}
if (ntfs_inode_close(dir_ni)
|| (inum == (u64)-1))
ino = (u64)-1;
@ -878,6 +885,11 @@ static void ntfs_fuse_lookup(fuse_req_t req, fuse_ino_t parent,
#endif
iref = ntfs_inode_lookup_by_mbsname(dir_ni,
name);
/* never return inodes 0 and 1 */
if (MREF(iref) <= 1) {
iref = (u64)-1;
errno = ENOENT;
}
ok = !ntfs_inode_close(dir_ni)
&& (iref != (u64)-1)
&& ntfs_fuse_fillstat(
@ -1002,9 +1014,8 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx,
(unsigned long long)MREF(mref));
return -1;
}
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user ||
ctx->show_sys_files) {
/* never return inodes 0 and 1 */
if (MREF(mref) > 1) {
struct stat st = { .st_ino = MREF(mref) };
if (dt_type == NTFS_DT_REG)
@ -3638,6 +3649,9 @@ static int ntfs_open(const char *device)
ntfs_log_perror("Failed to mount '%s'", device);
goto err_out;
}
if (ntfs_set_shown_files(ctx->vol, ctx->show_sys_files,
ctx->show_hid_files, ctx->hide_dot_files))
goto err_out;
ctx->vol->free_clusters = ntfs_attr_get_free_bits(ctx->vol->lcnbmp_na);
if (ctx->vol->free_clusters < 0) {
@ -3802,6 +3816,14 @@ static char *parse_mount_options(const char *orig_opts)
if (bogus_option_value(val, "show_sys_files"))
goto err_exit;
ctx->show_sys_files = TRUE;
} else if (!strcmp(opt, "show_hid_files")) {
if (bogus_option_value(val, "show_hid_files"))
goto err_exit;
ctx->show_hid_files = TRUE;
} else if (!strcmp(opt, "hide_dot_files")) {
if (bogus_option_value(val, "hide_dot_files"))
goto err_exit;
ctx->hide_dot_files = TRUE;
} else if (!strcmp(opt, "silent")) {
if (bogus_option_value(val, "silent"))
goto err_exit;
@ -3911,6 +3933,8 @@ static char *parse_mount_options(const char *orig_opts)
if (bogus_option_value(val, "efs_raw"))
goto err_exit;
ctx->efs_raw = TRUE;
/* show hidden files to archivers */
ctx->show_hid_files = 1;
#endif /* HAVE_SETXATTR */
} else { /* Probably FUSE option. */
if (strappend(&ret, opt))

View File

@ -184,14 +184,29 @@ if a file has been read since the last time it was modified.
This is the default behaviour.
.TP
.B show_sys_files
Show the system files in directory listings.
Otherwise the default behaviour is to hide the system files.
Please note that even when this option is specified, "$MFT"
may not be visible due to a glibc bug.
Furthermore, irrespectively of show_sys_files, all
files are accessible by name, for example you can always do
Show the metafiles in directory listings. Otherwise the default behaviour is
to hide the metafiles, which are special files used to store the NTFS
structure. Please note that even when this option is specified, "$MFT" may
not be visible due to a glibc bug. Furthermore, irrespectively of
show_sys_files, all files are accessible by name, for example you can always
do
"ls \-l '$UpCase'".
.TP
.B show_hid_files
Show the hidden files and directories in directory listings, the hidden files
and directories being the ones whose NTFS attribute have the hidden flag set.
This flag has no effect on files and directory whose first character of
the name is a dot. Furthermore, irrespectively of show_hid_files, all files
and directories are accessible by name, for example you can always display
the Windows trash bin directory by :
"ls \-ld '$RECYCLE.BIN'".
.TP
.B hide_dot_files
Set the hidden flag in the NTFS attribute for created files and directories
whose first character of the name is a dot. Such files and directories
normally do not appear in directory listings, and when the flag is set
they do not appear in Windows directory displays either.
.TP
.B allow_other
This option overrides the security measure restricting file access
to the user mounting the filesystem. This option is only

View File

@ -170,6 +170,8 @@ typedef struct {
ntfs_atime_t atime;
BOOL ro;
BOOL show_sys_files;
BOOL show_hid_files;
BOOL hide_dot_files;
BOOL silent;
BOOL recover;
BOOL hiberfile;
@ -1028,10 +1030,7 @@ static int ntfs_fuse_filler(ntfs_fuse_fill_context_t *fill_ctx,
filename, (unsigned long long)MREF(mref));
free(filename);
return 0;
}
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user ||
ctx->show_sys_files) {
} else {
struct stat st = { .st_ino = MREF(mref) };
if (dt_type == NTFS_DT_REG)
@ -3597,6 +3596,9 @@ static int ntfs_open(const char *device)
ntfs_log_perror("Failed to mount '%s'", device);
goto err_out;
}
if (ntfs_set_shown_files(ctx->vol, ctx->show_sys_files,
ctx->show_hid_files, ctx->hide_dot_files))
goto err_out;
ctx->vol->free_clusters = ntfs_attr_get_free_bits(ctx->vol->lcnbmp_na);
if (ctx->vol->free_clusters < 0) {
@ -3761,6 +3763,14 @@ static char *parse_mount_options(const char *orig_opts)
if (bogus_option_value(val, "show_sys_files"))
goto err_exit;
ctx->show_sys_files = TRUE;
} else if (!strcmp(opt, "show_hid_files")) {
if (bogus_option_value(val, "show_hid_files"))
goto err_exit;
ctx->show_hid_files = TRUE;
} else if (!strcmp(opt, "hide_dot_files")) {
if (bogus_option_value(val, "hide_dot_files"))
goto err_exit;
ctx->hide_dot_files = TRUE;
} else if (!strcmp(opt, "silent")) {
if (bogus_option_value(val, "silent"))
goto err_exit;
@ -3872,6 +3882,8 @@ static char *parse_mount_options(const char *orig_opts)
if (bogus_option_value(val, "efs_raw"))
goto err_exit;
ctx->efs_raw = TRUE;
/* show hidden files to archivers */
ctx->show_hid_files = 1;
#endif /* HAVE_SETXATTR */
} else { /* Probably FUSE option. */
if (strappend(&ret, opt))