mirror of
https://git.code.sf.net/p/ntfs-3g/ntfs-3g.git
synced 2024-12-04 15:34:28 +08:00
Adapted to ntfs-3g.1.2310
This commit is contained in:
parent
beb5e6ae48
commit
53fa335624
@ -57,7 +57,7 @@ extern int ntfs_file_values_compare(const FILE_NAME_ATTR *file_name_attr1,
|
|||||||
|
|
||||||
extern int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
|
extern int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
|
||||||
int outs_len);
|
int outs_len);
|
||||||
extern int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len);
|
extern int ntfs_mbstoucs(const char *ins, ntfschar **outs);
|
||||||
|
|
||||||
extern void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len);
|
extern void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len);
|
||||||
|
|
||||||
|
@ -2732,6 +2732,10 @@ int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||||||
goto put_err_out;
|
goto put_err_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (type == AT_DATA && name == AT_UNNAMED) {
|
||||||
|
ni->data_size = size;
|
||||||
|
ni->allocated_size = (size + 7) & ~7;
|
||||||
|
}
|
||||||
ntfs_inode_mark_dirty(ni);
|
ntfs_inode_mark_dirty(ni);
|
||||||
ntfs_attr_put_search_ctx(ctx);
|
ntfs_attr_put_search_ctx(ctx);
|
||||||
return offset;
|
return offset;
|
||||||
|
@ -496,9 +496,8 @@ ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
|
|||||||
|
|
||||||
ntfs_log_trace("path: '%s'\n", pathname);
|
ntfs_log_trace("path: '%s'\n", pathname);
|
||||||
|
|
||||||
unicode = ntfs_calloc(MAX_PATH);
|
|
||||||
ascii = strdup(pathname);
|
ascii = strdup(pathname);
|
||||||
if (!unicode || !ascii) {
|
if (!ascii) {
|
||||||
ntfs_log_debug("Out of memory.\n");
|
ntfs_log_debug("Out of memory.\n");
|
||||||
err = ENOMEM;
|
err = ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
@ -560,7 +559,7 @@ ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
|
|||||||
/* q++; JPA */
|
/* q++; JPA */
|
||||||
}
|
}
|
||||||
|
|
||||||
len = ntfs_mbstoucs(p, &unicode, MAX_PATH);
|
len = ntfs_mbstoucs(p, &unicode);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
ntfs_log_debug("Couldn't convert name to Unicode: %s.\n", p);
|
ntfs_log_debug("Couldn't convert name to Unicode: %s.\n", p);
|
||||||
err = errno;
|
err = errno;
|
||||||
@ -617,6 +616,9 @@ ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
|
|||||||
err = EIO;
|
err = EIO;
|
||||||
goto close;
|
goto close;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(unicode);
|
||||||
|
unicode = NULL;
|
||||||
|
|
||||||
if (q) *q++ = PATH_SEP; /* JPA */
|
if (q) *q++ = PATH_SEP; /* JPA */
|
||||||
p = q;
|
p = q;
|
||||||
@ -1338,6 +1340,8 @@ static ntfs_inode *__ntfs_create(ntfs_inode *dir_ni, le32 securid,
|
|||||||
fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
|
fn->last_data_change_time = utc2ntfs(ni->last_data_change_time);
|
||||||
fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
|
fn->last_mft_change_time = utc2ntfs(ni->last_mft_change_time);
|
||||||
fn->last_access_time = utc2ntfs(ni->last_access_time);
|
fn->last_access_time = utc2ntfs(ni->last_access_time);
|
||||||
|
fn->data_size = cpu_to_sle64(ni->data_size);
|
||||||
|
fn->allocated_size = cpu_to_sle64(ni->allocated_size);
|
||||||
memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
|
memcpy(fn->file_name, name, name_len * sizeof(ntfschar));
|
||||||
/* Add FILE_NAME attribute to inode. */
|
/* Add FILE_NAME attribute to inode. */
|
||||||
if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
|
if (ntfs_attr_add(ni, AT_FILE_NAME, AT_UNNAMED, 0, (u8*)fn, fn_len)) {
|
||||||
@ -1444,7 +1448,7 @@ int ntfs_check_empty_dir(ntfs_inode *ni)
|
|||||||
/* Non-empty directory? */
|
/* Non-empty directory? */
|
||||||
if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
|
if ((na->data_size != sizeof(INDEX_ROOT) + sizeof(INDEX_ENTRY_HEADER))){
|
||||||
/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
|
/* Both ENOTEMPTY and EEXIST are ok. We use the more common. */
|
||||||
errno = EEXIST;
|
errno = ENOTEMPTY;
|
||||||
ntfs_log_debug("Directory is not empty\n");
|
ntfs_log_debug("Directory is not empty\n");
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
@ -1459,7 +1463,7 @@ static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = ntfs_check_empty_dir(ni);
|
ret = ntfs_check_empty_dir(ni);
|
||||||
if (!ret || errno != EEXIST)
|
if (!ret || errno != ENOTEMPTY)
|
||||||
return ret;
|
return ret;
|
||||||
/*
|
/*
|
||||||
* Directory is non-empty, so we can unlink only if there is more than
|
* Directory is non-empty, so we can unlink only if there is more than
|
||||||
@ -1467,7 +1471,7 @@ static int ntfs_check_unlinkable_dir(ntfs_inode *ni, FILE_NAME_ATTR *fn)
|
|||||||
*/
|
*/
|
||||||
if ((link_count == 1) ||
|
if ((link_count == 1) ||
|
||||||
(link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
|
(link_count == 2 && fn->file_name_type == FILE_NAME_DOS)) {
|
||||||
errno = EEXIST;
|
errno = ENOTEMPTY;
|
||||||
ntfs_log_debug("Non-empty directory without hard links\n");
|
ntfs_log_debug("Non-empty directory without hard links\n");
|
||||||
goto no_hardlink;
|
goto no_hardlink;
|
||||||
}
|
}
|
||||||
|
@ -496,17 +496,16 @@ err_out:
|
|||||||
* ntfs_mbstoucs - convert a multibyte string to a little endian Unicode string
|
* ntfs_mbstoucs - convert a multibyte string to a little endian Unicode string
|
||||||
* @ins: input multibyte string buffer
|
* @ins: input multibyte string buffer
|
||||||
* @outs: on return contains the (allocated) output Unicode string
|
* @outs: on return contains the (allocated) output Unicode string
|
||||||
* @outs_len: length of output buffer in Unicode characters
|
|
||||||
*
|
*
|
||||||
* Convert the input multibyte string @ins, from the current locale into the
|
* Convert the input multibyte string @ins, from the current locale into the
|
||||||
* corresponding little endian, 2-byte Unicode string.
|
* corresponding little endian, 2-byte Unicode string.
|
||||||
*
|
*
|
||||||
* If *@outs is NULL, the function allocates the string and the caller is
|
* The function allocates the string and the caller is responsible for calling
|
||||||
* responsible for calling free(*@outs); when finished with it.
|
* free(*@outs); when finished with it.
|
||||||
*
|
*
|
||||||
* On success the function returns the number of Unicode characters written to
|
* On success the function returns the number of Unicode characters written to
|
||||||
* the output string *@outs (>= 0), not counting the terminating Unicode NULL
|
* the output string *@outs (>= 0), not counting the terminating Unicode NULL
|
||||||
* character. If the output string buffer was allocated, *@outs is set to it.
|
* character.
|
||||||
*
|
*
|
||||||
* On error, -1 is returned, and errno is set to the error code. The following
|
* On error, -1 is returned, and errno is set to the error code. The following
|
||||||
* error codes can be expected:
|
* error codes can be expected:
|
||||||
@ -516,7 +515,7 @@ err_out:
|
|||||||
* ENAMETOOLONG Destination buffer is too small for input string.
|
* ENAMETOOLONG Destination buffer is too small for input string.
|
||||||
* ENOMEM Not enough memory to allocate destination buffer.
|
* ENOMEM Not enough memory to allocate destination buffer.
|
||||||
*/
|
*/
|
||||||
int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
int ntfs_mbstoucs(const char *ins, ntfschar **outs)
|
||||||
{
|
{
|
||||||
ntfschar *ucs;
|
ntfschar *ucs;
|
||||||
const char *s;
|
const char *s;
|
||||||
@ -530,12 +529,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
|||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ucs = *outs;
|
|
||||||
ucs_len = outs_len;
|
|
||||||
if (ucs && !ucs_len) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* Determine the size of the multi-byte string in bytes. */
|
/* Determine the size of the multi-byte string in bytes. */
|
||||||
ins_size = strlen(ins);
|
ins_size = strlen(ins);
|
||||||
/* Determine the length of the multi-byte string. */
|
/* Determine the length of the multi-byte string. */
|
||||||
@ -567,31 +561,21 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
|||||||
}
|
}
|
||||||
/* Add the NULL terminator. */
|
/* Add the NULL terminator. */
|
||||||
ins_len++;
|
ins_len++;
|
||||||
if (!ucs) {
|
ucs_len = ins_len;
|
||||||
ucs_len = ins_len;
|
ucs = ntfs_malloc(ucs_len * sizeof(ntfschar));
|
||||||
ucs = ntfs_malloc(ucs_len * sizeof(ntfschar));
|
if (!ucs)
|
||||||
if (!ucs)
|
return -1;
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#ifdef HAVE_MBSINIT
|
#ifdef HAVE_MBSINIT
|
||||||
memset(&mbstate, 0, sizeof(mbstate));
|
memset(&mbstate, 0, sizeof(mbstate));
|
||||||
#else
|
#else
|
||||||
mbtowc(NULL, NULL, 0);
|
mbtowc(NULL, NULL, 0);
|
||||||
#endif
|
#endif
|
||||||
for (i = o = cnt = 0; i < ins_size; i += cnt, o++) {
|
for (i = o = cnt = 0; i < ins_size; i += cnt, o++) {
|
||||||
/* Reallocate memory if necessary or abort. */
|
/* Reallocate memory if necessary. */
|
||||||
if (o >= ucs_len) {
|
if (o >= ucs_len) {
|
||||||
ntfschar *tc;
|
ntfschar *tc;
|
||||||
if (ucs == *outs) {
|
|
||||||
errno = ENAMETOOLONG;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* We will never get here but hey, it's only a bit of
|
|
||||||
* extra code...
|
|
||||||
*/
|
|
||||||
ucs_len = (ucs_len * sizeof(ntfschar) + 64) & ~63;
|
ucs_len = (ucs_len * sizeof(ntfschar) + 64) & ~63;
|
||||||
tc = (ntfschar*)realloc(ucs, ucs_len);
|
tc = realloc(ucs, ucs_len);
|
||||||
if (!tc)
|
if (!tc)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
ucs = tc;
|
ucs = tc;
|
||||||
@ -631,15 +615,10 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs, int outs_len)
|
|||||||
#endif
|
#endif
|
||||||
/* Now write the NULL character. */
|
/* Now write the NULL character. */
|
||||||
ucs[o] = cpu_to_le16(L'\0');
|
ucs[o] = cpu_to_le16(L'\0');
|
||||||
if (*outs != ucs)
|
*outs = ucs;
|
||||||
*outs = ucs;
|
|
||||||
return o;
|
return o;
|
||||||
err_out:
|
err_out:
|
||||||
if (ucs != *outs) {
|
free(ucs);
|
||||||
int eo = errno;
|
|
||||||
free(ucs);
|
|
||||||
errno = eo;
|
|
||||||
}
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -730,7 +709,7 @@ ntfschar *ntfs_str2ucs(const char *s, int *len)
|
|||||||
{
|
{
|
||||||
ntfschar *ucs = NULL;
|
ntfschar *ucs = NULL;
|
||||||
|
|
||||||
if (s && ((*len = ntfs_mbstoucs(s, &ucs, 0)) == -1)) {
|
if (s && ((*len = ntfs_mbstoucs(s, &ucs)) == -1)) {
|
||||||
ntfs_log_perror("Couldn't convert '%s' to Unicode", s);
|
ntfs_log_perror("Couldn't convert '%s' to Unicode", s);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -427,10 +427,6 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
|
|||||||
ntfs_volume *vol;
|
ntfs_volume *vol;
|
||||||
NTFS_BOOT_SECTOR *bs;
|
NTFS_BOOT_SECTOR *bs;
|
||||||
int eo;
|
int eo;
|
||||||
#ifdef DEBUG
|
|
||||||
const char *OK = "OK\n";
|
|
||||||
const char *FAILED = "FAILED\n";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!dev || !dev->d_ops || !dev->d_name) {
|
if (!dev || !dev->d_ops || !dev->d_name) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -461,7 +457,7 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
|
|||||||
|
|
||||||
/* ...->open needs bracketing to compile with glibc 2.7 */
|
/* ...->open needs bracketing to compile with glibc 2.7 */
|
||||||
if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
|
if ((dev->d_ops->open)(dev, NVolReadOnly(vol) ? O_RDONLY: O_RDWR)) {
|
||||||
ntfs_log_perror("Error opening partition device");
|
ntfs_log_perror("Error opening '%s'", dev->d_name);
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Attach the device to the volume. */
|
/* Attach the device to the volume. */
|
||||||
@ -470,7 +466,6 @@ ntfs_volume *ntfs_volume_startup(struct ntfs_device *dev, unsigned long flags)
|
|||||||
/* Now read the bootsector. */
|
/* Now read the bootsector. */
|
||||||
br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
|
br = ntfs_pread(dev, 0, sizeof(NTFS_BOOT_SECTOR), bs);
|
||||||
if (br != sizeof(NTFS_BOOT_SECTOR)) {
|
if (br != sizeof(NTFS_BOOT_SECTOR)) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
if (br != -1)
|
if (br != -1)
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
if (!br)
|
if (!br)
|
||||||
@ -638,7 +633,7 @@ static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unicode_len = ntfs_mbstoucs(hiberfile, &unicode, 0);
|
unicode_len = ntfs_mbstoucs(hiberfile, &unicode);
|
||||||
if (unicode_len < 0) {
|
if (unicode_len < 0) {
|
||||||
ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");
|
ntfs_log_perror("Couldn't convert 'hiberfil.sys' to Unicode");
|
||||||
goto out;
|
goto out;
|
||||||
@ -756,10 +751,6 @@ out:
|
|||||||
ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
||||||
{
|
{
|
||||||
s64 l;
|
s64 l;
|
||||||
#ifdef DEBUG
|
|
||||||
const char *OK = "OK\n";
|
|
||||||
const char *FAILED = "FAILED\n";
|
|
||||||
#endif
|
|
||||||
ntfs_volume *vol;
|
ntfs_volume *vol;
|
||||||
u8 *m = NULL, *m2 = NULL;
|
u8 *m = NULL, *m2 = NULL;
|
||||||
ntfs_attr_search_ctx *ctx = NULL;
|
ntfs_attr_search_ctx *ctx = NULL;
|
||||||
@ -803,7 +794,7 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
}
|
}
|
||||||
vol->mftmirr_size = l;
|
vol->mftmirr_size = l;
|
||||||
}
|
}
|
||||||
ntfs_log_debug("Comparing $MFTMirr to $MFT... ");
|
ntfs_log_debug("Comparing $MFTMirr to $MFT...\n");
|
||||||
for (i = 0; i < vol->mftmirr_size; ++i) {
|
for (i = 0; i < vol->mftmirr_size; ++i) {
|
||||||
MFT_RECORD *mrec, *mrec2;
|
MFT_RECORD *mrec, *mrec2;
|
||||||
const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
|
const char *ESTR[12] = { "$MFT", "$MFTMirr", "$LogFile",
|
||||||
@ -821,14 +812,12 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
|
mrec = (MFT_RECORD*)(m + i * vol->mft_record_size);
|
||||||
if (mrec->flags & MFT_RECORD_IN_USE) {
|
if (mrec->flags & MFT_RECORD_IN_USE) {
|
||||||
if (ntfs_is_baad_recordp(mrec)) {
|
if (ntfs_is_baad_recordp(mrec)) {
|
||||||
ntfs_log_debug("FAILED\n");
|
|
||||||
ntfs_log_error("$MFT error: Incomplete multi "
|
ntfs_log_error("$MFT error: Incomplete multi "
|
||||||
"sector transfer detected in "
|
"sector transfer detected in "
|
||||||
"'%s'.\n", s);
|
"'%s'.\n", s);
|
||||||
goto io_error_exit;
|
goto io_error_exit;
|
||||||
}
|
}
|
||||||
if (!ntfs_is_mft_recordp(mrec)) {
|
if (!ntfs_is_mft_recordp(mrec)) {
|
||||||
ntfs_log_debug("FAILED\n");
|
|
||||||
ntfs_log_error("$MFT error: Invalid mft "
|
ntfs_log_error("$MFT error: Invalid mft "
|
||||||
"record for '%s'.\n", s);
|
"record for '%s'.\n", s);
|
||||||
goto io_error_exit;
|
goto io_error_exit;
|
||||||
@ -837,62 +826,53 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
|
mrec2 = (MFT_RECORD*)(m2 + i * vol->mft_record_size);
|
||||||
if (mrec2->flags & MFT_RECORD_IN_USE) {
|
if (mrec2->flags & MFT_RECORD_IN_USE) {
|
||||||
if (ntfs_is_baad_recordp(mrec2)) {
|
if (ntfs_is_baad_recordp(mrec2)) {
|
||||||
ntfs_log_debug("FAILED\n");
|
|
||||||
ntfs_log_error("$MFTMirr error: Incomplete "
|
ntfs_log_error("$MFTMirr error: Incomplete "
|
||||||
"multi sector transfer "
|
"multi sector transfer "
|
||||||
"detected in '%s'.\n", s);
|
"detected in '%s'.\n", s);
|
||||||
goto io_error_exit;
|
goto io_error_exit;
|
||||||
}
|
}
|
||||||
if (!ntfs_is_mft_recordp(mrec2)) {
|
if (!ntfs_is_mft_recordp(mrec2)) {
|
||||||
ntfs_log_debug("FAILED\n");
|
|
||||||
ntfs_log_error("$MFTMirr error: Invalid mft "
|
ntfs_log_error("$MFTMirr error: Invalid mft "
|
||||||
"record for '%s'.\n", s);
|
"record for '%s'.\n", s);
|
||||||
goto io_error_exit;
|
goto io_error_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {
|
if (memcmp(mrec, mrec2, ntfs_mft_record_get_data_size(mrec))) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("$MFTMirr does not match $MFT (record "
|
ntfs_log_error("$MFTMirr does not match $MFT (record "
|
||||||
"%d).\n", i);
|
"%d).\n", i);
|
||||||
goto io_error_exit;
|
goto io_error_exit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ntfs_log_debug(OK);
|
|
||||||
|
|
||||||
free(m2);
|
free(m2);
|
||||||
free(m);
|
free(m);
|
||||||
m = m2 = NULL;
|
m = m2 = NULL;
|
||||||
|
|
||||||
/* Now load the bitmap from $Bitmap. */
|
/* Now load the bitmap from $Bitmap. */
|
||||||
ntfs_log_debug("Loading $Bitmap... ");
|
ntfs_log_debug("Loading $Bitmap...\n");
|
||||||
vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
|
vol->lcnbmp_ni = ntfs_inode_open(vol, FILE_Bitmap);
|
||||||
if (!vol->lcnbmp_ni) {
|
if (!vol->lcnbmp_ni) {
|
||||||
ntfs_log_debug(FAILED);
|
ntfs_log_perror("Failed to open inode FILE_Bitmap");
|
||||||
ntfs_log_perror("Failed to open inode");
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Get an ntfs attribute for $Bitmap/$DATA. */
|
/* Get an ntfs attribute for $Bitmap/$DATA. */
|
||||||
vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
|
vol->lcnbmp_na = ntfs_attr_open(vol->lcnbmp_ni, AT_DATA, AT_UNNAMED, 0);
|
||||||
if (!vol->lcnbmp_na) {
|
if (!vol->lcnbmp_na) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("Failed to open ntfs attribute");
|
ntfs_log_perror("Failed to open ntfs attribute");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Done with the $Bitmap mft record. */
|
/* Done with the $Bitmap mft record. */
|
||||||
ntfs_log_debug(OK);
|
|
||||||
|
|
||||||
/* Now load the upcase table from $UpCase. */
|
/* Now load the upcase table from $UpCase. */
|
||||||
ntfs_log_debug("Loading $UpCase... ");
|
ntfs_log_debug("Loading $UpCase...\n");
|
||||||
ni = ntfs_inode_open(vol, FILE_UpCase);
|
ni = ntfs_inode_open(vol, FILE_UpCase);
|
||||||
if (!ni) {
|
if (!ni) {
|
||||||
ntfs_log_debug(FAILED);
|
ntfs_log_perror("Failed to open inode FILE_UpCase");
|
||||||
ntfs_log_perror("Failed to open inode");
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Get an ntfs attribute for $UpCase/$DATA. */
|
/* Get an ntfs attribute for $UpCase/$DATA. */
|
||||||
na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
|
na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
|
||||||
if (!na) {
|
if (!na) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("Failed to open ntfs attribute");
|
ntfs_log_perror("Failed to open ntfs attribute");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
@ -903,7 +883,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
* characters.
|
* characters.
|
||||||
*/
|
*/
|
||||||
if (na->data_size & ~0x1ffffffffULL) {
|
if (na->data_size & ~0x1ffffffffULL) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("Error: Upcase table is too big (max 32-bit "
|
ntfs_log_error("Error: Upcase table is too big (max 32-bit "
|
||||||
"allowed).\n");
|
"allowed).\n");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -914,15 +893,12 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
/* Throw away default table. */
|
/* Throw away default table. */
|
||||||
free(vol->upcase);
|
free(vol->upcase);
|
||||||
vol->upcase = ntfs_malloc(na->data_size);
|
vol->upcase = ntfs_malloc(na->data_size);
|
||||||
if (!vol->upcase) {
|
if (!vol->upcase)
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Read in the $DATA attribute value into the buffer. */
|
/* Read in the $DATA attribute value into the buffer. */
|
||||||
l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
|
l = ntfs_attr_pread(na, 0, na->data_size, vol->upcase);
|
||||||
if (l != na->data_size) {
|
if (l != na->data_size) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("Failed to read $UpCase, unexpected length "
|
ntfs_log_error("Failed to read $UpCase, unexpected length "
|
||||||
"(%lld != %lld).\n", (long long)l,
|
"(%lld != %lld).\n", (long long)l,
|
||||||
(long long)na->data_size);
|
(long long)na->data_size);
|
||||||
@ -930,7 +906,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Done with the $UpCase mft record. */
|
/* Done with the $UpCase mft record. */
|
||||||
ntfs_log_debug(OK);
|
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
if (ntfs_inode_close(ni)) {
|
if (ntfs_inode_close(ni)) {
|
||||||
ntfs_log_perror("Failed to close $UpCase");
|
ntfs_log_perror("Failed to close $UpCase");
|
||||||
@ -941,11 +916,10 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
* Now load $Volume and set the version information and flags in the
|
* Now load $Volume and set the version information and flags in the
|
||||||
* vol structure accordingly.
|
* vol structure accordingly.
|
||||||
*/
|
*/
|
||||||
ntfs_log_debug("Loading $Volume... ");
|
ntfs_log_debug("Loading $Volume...\n");
|
||||||
vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
|
vol->vol_ni = ntfs_inode_open(vol, FILE_Volume);
|
||||||
if (!vol->vol_ni) {
|
if (!vol->vol_ni) {
|
||||||
ntfs_log_debug(FAILED);
|
ntfs_log_perror("Failed to open inode FILE_Volume");
|
||||||
ntfs_log_perror("Failed to open inode");
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
|
/* Get a search context for the $Volume/$VOLUME_INFORMATION lookup. */
|
||||||
@ -956,7 +930,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
/* Find the $VOLUME_INFORMATION attribute. */
|
/* Find the $VOLUME_INFORMATION attribute. */
|
||||||
if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
|
if (ntfs_attr_lookup(AT_VOLUME_INFORMATION, AT_UNNAMED, 0, 0, 0, NULL,
|
||||||
0, ctx)) {
|
0, ctx)) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
|
ntfs_log_perror("$VOLUME_INFORMATION attribute not found in "
|
||||||
"$Volume");
|
"$Volume");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
@ -964,7 +937,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
a = ctx->attr;
|
a = ctx->attr;
|
||||||
/* Has to be resident. */
|
/* Has to be resident. */
|
||||||
if (a->non_resident) {
|
if (a->non_resident) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
|
ntfs_log_error("Attribute $VOLUME_INFORMATION must be "
|
||||||
"resident but it isn't.\n");
|
"resident but it isn't.\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
@ -977,7 +949,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
le32_to_cpu(ctx->mrec->bytes_in_use) ||
|
le32_to_cpu(ctx->mrec->bytes_in_use) ||
|
||||||
le16_to_cpu(a->value_offset) + le32_to_cpu(
|
le16_to_cpu(a->value_offset) + le32_to_cpu(
|
||||||
a->value_length) > le32_to_cpu(a->length)) {
|
a->value_length) > le32_to_cpu(a->length)) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
|
ntfs_log_error("$VOLUME_INFORMATION in $Volume is corrupt.\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
@ -995,7 +966,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
|
if (ntfs_attr_lookup(AT_VOLUME_NAME, AT_UNNAMED, 0, 0, 0, NULL, 0,
|
||||||
ctx)) {
|
ctx)) {
|
||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
|
ntfs_log_perror("Failed to lookup of $VOLUME_NAME in "
|
||||||
"$Volume failed");
|
"$Volume failed");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
@ -1006,16 +976,13 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
* had zero length.
|
* had zero length.
|
||||||
*/
|
*/
|
||||||
vol->vol_name = ntfs_malloc(1);
|
vol->vol_name = ntfs_malloc(1);
|
||||||
if (!vol->vol_name) {
|
if (!vol->vol_name)
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
|
||||||
vol->vol_name[0] = '\0';
|
vol->vol_name[0] = '\0';
|
||||||
} else {
|
} else {
|
||||||
a = ctx->attr;
|
a = ctx->attr;
|
||||||
/* Has to be resident. */
|
/* Has to be resident. */
|
||||||
if (a->non_resident) {
|
if (a->non_resident) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("$VOLUME_NAME must be resident.\n");
|
ntfs_log_error("$VOLUME_NAME must be resident.\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
@ -1034,10 +1001,9 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
ntfs_log_debug("Forcing name into ASCII by replacing "
|
ntfs_log_debug("Forcing name into ASCII by replacing "
|
||||||
"non-ASCII characters with underscores.\n");
|
"non-ASCII characters with underscores.\n");
|
||||||
vol->vol_name = ntfs_malloc(u + 1);
|
vol->vol_name = ntfs_malloc(u + 1);
|
||||||
if (!vol->vol_name) {
|
if (!vol->vol_name)
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
|
||||||
for (j = 0; j < (s32)u; j++) {
|
for (j = 0; j < (s32)u; j++) {
|
||||||
ntfschar uc = le16_to_cpu(vname[j]);
|
ntfschar uc = le16_to_cpu(vname[j]);
|
||||||
if (uc > 0xff)
|
if (uc > 0xff)
|
||||||
@ -1047,27 +1013,23 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
vol->vol_name[u] = '\0';
|
vol->vol_name[u] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ntfs_log_debug(OK);
|
|
||||||
ntfs_attr_put_search_ctx(ctx);
|
ntfs_attr_put_search_ctx(ctx);
|
||||||
ctx = NULL;
|
ctx = NULL;
|
||||||
/* Now load the attribute definitions from $AttrDef. */
|
/* Now load the attribute definitions from $AttrDef. */
|
||||||
ntfs_log_debug("Loading $AttrDef... ");
|
ntfs_log_debug("Loading $AttrDef...\n");
|
||||||
ni = ntfs_inode_open(vol, FILE_AttrDef);
|
ni = ntfs_inode_open(vol, FILE_AttrDef);
|
||||||
if (!ni) {
|
if (!ni) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("Failed to open $AttrDef");
|
ntfs_log_perror("Failed to open $AttrDef");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Get an ntfs attribute for $AttrDef/$DATA. */
|
/* Get an ntfs attribute for $AttrDef/$DATA. */
|
||||||
na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
|
na = ntfs_attr_open(ni, AT_DATA, AT_UNNAMED, 0);
|
||||||
if (!na) {
|
if (!na) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_perror("Failed to open ntfs attribute");
|
ntfs_log_perror("Failed to open ntfs attribute");
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Check we don't overflow 32-bits. */
|
/* Check we don't overflow 32-bits. */
|
||||||
if (na->data_size > 0xffffffffLL) {
|
if (na->data_size > 0xffffffffLL) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("Attribute definition table is too big (max "
|
ntfs_log_error("Attribute definition table is too big (max "
|
||||||
"32-bit allowed).\n");
|
"32-bit allowed).\n");
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -1075,14 +1037,11 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
}
|
}
|
||||||
vol->attrdef_len = na->data_size;
|
vol->attrdef_len = na->data_size;
|
||||||
vol->attrdef = ntfs_malloc(na->data_size);
|
vol->attrdef = ntfs_malloc(na->data_size);
|
||||||
if (!vol->attrdef) {
|
if (!vol->attrdef)
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
|
||||||
/* Read in the $DATA attribute value into the buffer. */
|
/* Read in the $DATA attribute value into the buffer. */
|
||||||
l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
|
l = ntfs_attr_pread(na, 0, na->data_size, vol->attrdef);
|
||||||
if (l != na->data_size) {
|
if (l != na->data_size) {
|
||||||
ntfs_log_debug(FAILED);
|
|
||||||
ntfs_log_error("Failed to read $AttrDef, unexpected length "
|
ntfs_log_error("Failed to read $AttrDef, unexpected length "
|
||||||
"(%lld != %lld).\n", (long long)l,
|
"(%lld != %lld).\n", (long long)l,
|
||||||
(long long)na->data_size);
|
(long long)na->data_size);
|
||||||
@ -1090,7 +1049,6 @@ ntfs_volume *ntfs_device_mount(struct ntfs_device *dev, unsigned long flags)
|
|||||||
goto error_exit;
|
goto error_exit;
|
||||||
}
|
}
|
||||||
/* Done with the $AttrDef mft record. */
|
/* Done with the $AttrDef mft record. */
|
||||||
ntfs_log_debug(OK);
|
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
if (ntfs_inode_close(ni)) {
|
if (ntfs_inode_close(ni)) {
|
||||||
ntfs_log_perror("Failed to close $AttrDef");
|
ntfs_log_perror("Failed to close $AttrDef");
|
||||||
|
@ -352,7 +352,7 @@ static int ntfs_fuse_parse_path(const char *org_path, char **path,
|
|||||||
*path = strsep(&stream_name_mbs, ":");
|
*path = strsep(&stream_name_mbs, ":");
|
||||||
if (stream_name_mbs) {
|
if (stream_name_mbs) {
|
||||||
*stream_name = NULL;
|
*stream_name = NULL;
|
||||||
res = ntfs_mbstoucs(stream_name_mbs, stream_name, 0);
|
res = ntfs_mbstoucs(stream_name_mbs, stream_name);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return res;
|
return res;
|
||||||
@ -1028,7 +1028,7 @@ static int ntfs_fuse_create(const char *org_path, dev_t typemode, dev_t dev,
|
|||||||
/* Generate unicode filename. */
|
/* Generate unicode filename. */
|
||||||
name = strrchr(dir_path, '/');
|
name = strrchr(dir_path, '/');
|
||||||
name++;
|
name++;
|
||||||
uname_len = ntfs_mbstoucs(name, &uname, 0);
|
uname_len = ntfs_mbstoucs(name, &uname);
|
||||||
if (uname_len < 0) {
|
if (uname_len < 0) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1078,7 +1078,7 @@ static int ntfs_fuse_create(const char *org_path, dev_t typemode, dev_t dev,
|
|||||||
uname, uname_len, type, dev);
|
uname, uname_len, type, dev);
|
||||||
break;
|
break;
|
||||||
case S_IFLNK:
|
case S_IFLNK:
|
||||||
utarget_len = ntfs_mbstoucs(target, &utarget, 0);
|
utarget_len = ntfs_mbstoucs(target, &utarget);
|
||||||
if (utarget_len < 0) {
|
if (utarget_len < 0) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1242,7 +1242,7 @@ static int ntfs_fuse_link(const char *old_path, const char *new_path)
|
|||||||
/* Generate unicode filename. */
|
/* Generate unicode filename. */
|
||||||
name = strrchr(path, '/');
|
name = strrchr(path, '/');
|
||||||
name++;
|
name++;
|
||||||
uname_len = ntfs_mbstoucs(name, &uname, 0);
|
uname_len = ntfs_mbstoucs(name, &uname);
|
||||||
if (uname_len < 0) {
|
if (uname_len < 0) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1304,7 +1304,7 @@ static int ntfs_fuse_rm(const char *org_path)
|
|||||||
/* Generate unicode filename. */
|
/* Generate unicode filename. */
|
||||||
name = strrchr(path, '/');
|
name = strrchr(path, '/');
|
||||||
name++;
|
name++;
|
||||||
uname_len = ntfs_mbstoucs(name, &uname, 0);
|
uname_len = ntfs_mbstoucs(name, &uname);
|
||||||
if (uname_len < 0) {
|
if (uname_len < 0) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1739,7 +1739,7 @@ static int ntfs_fuse_getxattr(const char *path, const char *name,
|
|||||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||||
if (!ni)
|
if (!ni)
|
||||||
return -errno;
|
return -errno;
|
||||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename, 0);
|
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||||
if (lename_len == -1) {
|
if (lename_len == -1) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1787,7 +1787,7 @@ static int ntfs_fuse_setxattr(const char *path, const char *name,
|
|||||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||||
if (!ni)
|
if (!ni)
|
||||||
return -errno;
|
return -errno;
|
||||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename, 0);
|
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||||
if (lename_len == -1) {
|
if (lename_len == -1) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -1845,7 +1845,7 @@ static int ntfs_fuse_removexattr(const char *path, const char *name)
|
|||||||
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
ni = ntfs_pathname_to_inode(vol, NULL, path);
|
||||||
if (!ni)
|
if (!ni)
|
||||||
return -errno;
|
return -errno;
|
||||||
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename, 0);
|
lename_len = ntfs_mbstoucs(name + nf_ns_xattr_preffix_len, &lename);
|
||||||
if (lename_len == -1) {
|
if (lename_len == -1) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -2497,10 +2497,6 @@ static struct fuse *mount_fuse(char *parsed_options)
|
|||||||
struct fuse *fh = NULL;
|
struct fuse *fh = NULL;
|
||||||
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
|
struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
|
||||||
|
|
||||||
/* Libfuse can't always find fusermount, so let's help it. */
|
|
||||||
if (setenv("PATH", ":/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin", 0))
|
|
||||||
ntfs_log_perror("WARNING: Failed to set $PATH\n");
|
|
||||||
|
|
||||||
ctx->fc = try_fuse_mount(parsed_options);
|
ctx->fc = try_fuse_mount(parsed_options);
|
||||||
if (!ctx->fc)
|
if (!ctx->fc)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -90,7 +90,7 @@ static const char *fakeraid_msg =
|
|||||||
"to mount NTFS. Please see the 'dmraid' documentation for help.\n";
|
"to mount NTFS. Please see the 'dmraid' documentation for help.\n";
|
||||||
|
|
||||||
static const char *access_denied_msg =
|
static const char *access_denied_msg =
|
||||||
"Please check the volume and the ntfs-3g binary permissions,\n"
|
"Please check '%s' and the ntfs-3g binary permissions,\n"
|
||||||
"and the mounting user ID. More explanation is provided at\n"
|
"and the mounting user ID. More explanation is provided at\n"
|
||||||
"http://ntfs-3g.org/support.html#unprivileged\n";
|
"http://ntfs-3g.org/support.html#unprivileged\n";
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user