mirror of
https://github.com/wiidev/usbloadergx.git
synced 2024-11-15 16:05:10 +01:00
*Moved every allocation of libntfs now to MEM2 (in mem1 it gets overwritten and so the games didn't work in last rev)
Forwarder change: *Ignore MBR partition type and read partition type from boot record sector (Channel will follow later)
This commit is contained in:
parent
9bcb476262
commit
85eb0a7ed2
@ -880,7 +880,7 @@ BOOL ntfs_valid_posix(const struct POSIX_SECURITY *pxdesc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((pxdesc->acccnt > 0)
|
if ((pxdesc->acccnt > 0)
|
||||||
&& ((checks[0].owners != 1) || (checks[0].groups != 1)
|
&& ((checks[0].owners != 1) || (checks[0].groups != 1)
|
||||||
|| (checks[0].others != 1)))
|
|| (checks[0].others != 1)))
|
||||||
ok = FALSE;
|
ok = FALSE;
|
||||||
/* do not check owner, group or other are present in */
|
/* do not check owner, group or other are present in */
|
||||||
@ -1082,7 +1082,7 @@ struct POSIX_SECURITY *ntfs_replace_acl(const struct POSIX_SECURITY *oldpxdesc,
|
|||||||
else
|
else
|
||||||
newsize = sizeof(struct POSIX_SECURITY)
|
newsize = sizeof(struct POSIX_SECURITY)
|
||||||
+ (oldpxdesc->defcnt + count)*sizeof(struct POSIX_ACE);
|
+ (oldpxdesc->defcnt + count)*sizeof(struct POSIX_ACE);
|
||||||
newpxdesc = (struct POSIX_SECURITY*)malloc(newsize);
|
newpxdesc = (struct POSIX_SECURITY*)ntfs_malloc(newsize);
|
||||||
if (newpxdesc) {
|
if (newpxdesc) {
|
||||||
if (deflt) {
|
if (deflt) {
|
||||||
offset = oldpxdesc->acccnt;
|
offset = oldpxdesc->acccnt;
|
||||||
@ -1147,7 +1147,7 @@ struct POSIX_SECURITY *ntfs_build_inherited_posix(
|
|||||||
count = pxdesc->defcnt + 3;
|
count = pxdesc->defcnt + 3;
|
||||||
} else
|
} else
|
||||||
count = 3;
|
count = 3;
|
||||||
pydesc = (struct POSIX_SECURITY*)malloc(
|
pydesc = (struct POSIX_SECURITY*)ntfs_malloc(
|
||||||
sizeof(struct POSIX_SECURITY) + count*sizeof(struct POSIX_ACE));
|
sizeof(struct POSIX_SECURITY) + count*sizeof(struct POSIX_ACE));
|
||||||
if (pydesc) {
|
if (pydesc) {
|
||||||
/*
|
/*
|
||||||
@ -1330,7 +1330,7 @@ struct POSIX_SECURITY *ntfs_merge_descr_posix(const struct POSIX_SECURITY *first
|
|||||||
size = sizeof(struct POSIX_SECURITY)
|
size = sizeof(struct POSIX_SECURITY)
|
||||||
+ (first->acccnt + first->defcnt
|
+ (first->acccnt + first->defcnt
|
||||||
+ second->acccnt + second->defcnt)*sizeof(struct POSIX_ACE);
|
+ second->acccnt + second->defcnt)*sizeof(struct POSIX_ACE);
|
||||||
pxdesc = (struct POSIX_SECURITY*)malloc(size);
|
pxdesc = (struct POSIX_SECURITY*)ntfs_malloc(size);
|
||||||
if (pxdesc) {
|
if (pxdesc) {
|
||||||
/*
|
/*
|
||||||
* merge access ACEs
|
* merge access ACEs
|
||||||
@ -1806,7 +1806,7 @@ static BOOL build_group_denials_grant(ACL *pacl,
|
|||||||
* - grants to owner (always present - first grant)
|
* - grants to owner (always present - first grant)
|
||||||
* + grants to designated user
|
* + grants to designated user
|
||||||
* + mask denial to group (unless mask allows all)
|
* + mask denial to group (unless mask allows all)
|
||||||
* - denials to group (preventing grants to world to apply)
|
* - denials to group (preventing grants to world to apply)
|
||||||
* - grants to group (unless group has no more than world rights)
|
* - grants to group (unless group has no more than world rights)
|
||||||
* + mask denials to designated group (unless mask allows all)
|
* + mask denials to designated group (unless mask allows all)
|
||||||
* + grants to designated group
|
* + grants to designated group
|
||||||
@ -3490,7 +3490,7 @@ struct POSIX_SECURITY *ntfs_build_permissions_posix(
|
|||||||
* and 2 more for other
|
* and 2 more for other
|
||||||
*/
|
*/
|
||||||
alloccnt = acecnt + 6;
|
alloccnt = acecnt + 6;
|
||||||
pxdesc = (struct POSIX_SECURITY*)malloc(
|
pxdesc = (struct POSIX_SECURITY*)ntfs_malloc(
|
||||||
sizeof(struct POSIX_SECURITY)
|
sizeof(struct POSIX_SECURITY)
|
||||||
+ alloccnt*sizeof(struct POSIX_ACE));
|
+ alloccnt*sizeof(struct POSIX_ACE));
|
||||||
k = 0;
|
k = 0;
|
||||||
|
@ -280,7 +280,7 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
|
|||||||
cache->oldest_entry = current->previous;
|
cache->oldest_entry = current->previous;
|
||||||
if (item->varsize) {
|
if (item->varsize) {
|
||||||
if (current->varsize)
|
if (current->varsize)
|
||||||
current->variable = realloc(
|
current->variable = MEM2_realloc(
|
||||||
current->variable,
|
current->variable,
|
||||||
item->varsize);
|
item->varsize);
|
||||||
else
|
else
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
* this was put into public domain in 1988 by Haruhiko OKUMURA).
|
* this was put into public domain in 1988 by Haruhiko OKUMURA).
|
||||||
*
|
*
|
||||||
* LZHUF.C English version 1.0
|
* LZHUF.C English version 1.0
|
||||||
* Based on Japanese version 29-NOV-1988
|
* Based on Japanese version 29-NOV-1988
|
||||||
* LZSS coded by Haruhiko OKUMURA
|
* LZSS coded by Haruhiko OKUMURA
|
||||||
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
|
* Adaptive Huffman Coding coded by Haruyasu YOSHIZAKI
|
||||||
* Edited and translated to English by Kenji RIKITAKE
|
* Edited and translated to English by Kenji RIKITAKE
|
||||||
@ -164,7 +164,7 @@ static void ntfs_new_node (struct COMPRESS_CONTEXT *pctx,
|
|||||||
}
|
}
|
||||||
if (i >= THRESHOLD) {
|
if (i >= THRESHOLD) {
|
||||||
if (i > pctx->match_length) {
|
if (i > pctx->match_length) {
|
||||||
pctx->match_position =
|
pctx->match_position =
|
||||||
r - pp + 2*NTFS_SB_SIZE - 1;
|
r - pp + 2*NTFS_SB_SIZE - 1;
|
||||||
if ((pctx->match_length = i) > mxl) {
|
if ((pctx->match_length = i) > mxl) {
|
||||||
i = pctx->rson[pp];
|
i = pctx->rson[pp];
|
||||||
@ -267,7 +267,7 @@ static unsigned int ntfs_compress_block(const char *inbuf,
|
|||||||
unsigned int xout;
|
unsigned int xout;
|
||||||
unsigned int ntag;
|
unsigned int ntag;
|
||||||
|
|
||||||
pctx = (struct COMPRESS_CONTEXT*)malloc(sizeof(struct COMPRESS_CONTEXT));
|
pctx = (struct COMPRESS_CONTEXT*)ntfs_malloc(sizeof(struct COMPRESS_CONTEXT));
|
||||||
if (pctx) {
|
if (pctx) {
|
||||||
pctx->inbuf = (const unsigned char*)inbuf;
|
pctx->inbuf = (const unsigned char*)inbuf;
|
||||||
ntfs_init_compress_tree(pctx);
|
ntfs_init_compress_tree(pctx);
|
||||||
@ -543,7 +543,7 @@ return_overflow:
|
|||||||
* code. Might be a bit confusing to debug but there really should never be
|
* code. Might be a bit confusing to debug but there really should never be
|
||||||
* errors coming from here.
|
* errors coming from here.
|
||||||
*/
|
*/
|
||||||
static BOOL ntfs_is_cb_compressed(ntfs_attr *na, runlist_element *rl,
|
static BOOL ntfs_is_cb_compressed(ntfs_attr *na, runlist_element *rl,
|
||||||
VCN cb_start_vcn, int cb_clusters)
|
VCN cb_start_vcn, int cb_clusters)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -663,12 +663,12 @@ s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b)
|
|||||||
cb_size = na->compression_block_size;
|
cb_size = na->compression_block_size;
|
||||||
cb_size_mask = cb_size - 1UL;
|
cb_size_mask = cb_size - 1UL;
|
||||||
cb_clusters = na->compression_block_clusters;
|
cb_clusters = na->compression_block_clusters;
|
||||||
|
|
||||||
/* Need a temporary buffer for each loaded compression block. */
|
/* Need a temporary buffer for each loaded compression block. */
|
||||||
cb = (u8*)ntfs_malloc(cb_size);
|
cb = (u8*)ntfs_malloc(cb_size);
|
||||||
if (!cb)
|
if (!cb)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
/* Need a temporary buffer for each uncompressed block. */
|
/* Need a temporary buffer for each uncompressed block. */
|
||||||
dest = (u8*)ntfs_malloc(cb_size);
|
dest = (u8*)ntfs_malloc(cb_size);
|
||||||
if (!dest) {
|
if (!dest) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -124,7 +124,7 @@ ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol)
|
|||||||
static void __ntfs_inode_release(ntfs_inode *ni)
|
static void __ntfs_inode_release(ntfs_inode *ni)
|
||||||
{
|
{
|
||||||
if (NInoDirty(ni))
|
if (NInoDirty(ni))
|
||||||
ntfs_log_error("Releasing dirty inode %lld!\n",
|
ntfs_log_error("Releasing dirty inode %lld!\n",
|
||||||
(long long)ni->mft_no);
|
(long long)ni->mft_no);
|
||||||
if (NInoAttrList(ni) && ni->attr_list)
|
if (NInoAttrList(ni) && ni->attr_list)
|
||||||
free(ni->attr_list);
|
free(ni->attr_list);
|
||||||
@ -243,7 +243,7 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
|
|||||||
if (l != ni->attr_list_size) {
|
if (l != ni->attr_list_size) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode "
|
ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode "
|
||||||
"%lld", (long long)l, ni->attr_list_size,
|
"%lld", (long long)l, ni->attr_list_size,
|
||||||
(long long)MREF(mref));
|
(long long)MREF(mref));
|
||||||
goto put_err_out;
|
goto put_err_out;
|
||||||
}
|
}
|
||||||
@ -273,7 +273,7 @@ get_size:
|
|||||||
set_nino_flag(ni,KnownSize);
|
set_nino_flag(ni,KnownSize);
|
||||||
}
|
}
|
||||||
ntfs_attr_put_search_ctx(ctx);
|
ntfs_attr_put_search_ctx(ctx);
|
||||||
out:
|
out:
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
return ni;
|
return ni;
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ err_out:
|
|||||||
int ntfs_inode_real_close(ntfs_inode *ni)
|
int ntfs_inode_real_close(ntfs_inode *ni)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
if (!ni)
|
if (!ni)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ int ntfs_inode_real_close(ntfs_inode *ni)
|
|||||||
*/
|
*/
|
||||||
if (base_ni->nr_extents) {
|
if (base_ni->nr_extents) {
|
||||||
/* Resize the memory buffer. */
|
/* Resize the memory buffer. */
|
||||||
tmp_nis = realloc(tmp_nis, base_ni->nr_extents *
|
tmp_nis = MEM2_realloc(tmp_nis, base_ni->nr_extents *
|
||||||
sizeof(ntfs_inode *));
|
sizeof(ntfs_inode *));
|
||||||
/* Ignore errors, they don't really matter. */
|
/* Ignore errors, they don't really matter. */
|
||||||
if (tmp_nis)
|
if (tmp_nis)
|
||||||
@ -378,8 +378,8 @@ int ntfs_inode_real_close(ntfs_inode *ni)
|
|||||||
i = -1;
|
i = -1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We could successfully sync, so only log this error
|
* We could successfully sync, so only log this error
|
||||||
* and try to sync other inode extents too.
|
* and try to sync other inode extents too.
|
||||||
*/
|
*/
|
||||||
@ -387,7 +387,7 @@ int ntfs_inode_real_close(ntfs_inode *ni)
|
|||||||
ntfs_log_error("Extent inode %lld was not found\n",
|
ntfs_log_error("Extent inode %lld was not found\n",
|
||||||
(long long)ni->mft_no);
|
(long long)ni->mft_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
__ntfs_inode_release(ni);
|
__ntfs_inode_release(ni);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
err:
|
err:
|
||||||
@ -580,11 +580,11 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
|
|||||||
ntfs_log_perror("%s", __FUNCTION__);
|
ntfs_log_perror("%s", __FUNCTION__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n",
|
ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n",
|
||||||
(unsigned long long)mft_no,
|
(unsigned long long)mft_no,
|
||||||
(unsigned long long)base_ni->mft_no);
|
(unsigned long long)base_ni->mft_no);
|
||||||
|
|
||||||
/* Is the extent inode already open and attached to the base inode? */
|
/* Is the extent inode already open and attached to the base inode? */
|
||||||
if (base_ni->nr_extents > 0) {
|
if (base_ni->nr_extents > 0) {
|
||||||
extent_nis = base_ni->extent_nis;
|
extent_nis = base_ni->extent_nis;
|
||||||
@ -797,7 +797,7 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
|
|||||||
if (dir_ni)
|
if (dir_ni)
|
||||||
index_ni = dir_ni;
|
index_ni = dir_ni;
|
||||||
else
|
else
|
||||||
index_ni = ntfs_inode_open(ni->vol,
|
index_ni = ntfs_inode_open(ni->vol,
|
||||||
le64_to_cpu(fn->parent_directory));
|
le64_to_cpu(fn->parent_directory));
|
||||||
if (!index_ni) {
|
if (!index_ni) {
|
||||||
if (!err)
|
if (!err)
|
||||||
@ -954,8 +954,8 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
|
|||||||
}
|
}
|
||||||
NInoAttrListSetDirty(ni);
|
NInoAttrListSetDirty(ni);
|
||||||
goto sync_inode;
|
goto sync_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (na->data_size == ni->attr_list_size) {
|
if (na->data_size == ni->attr_list_size) {
|
||||||
if (ntfs_attr_pwrite(na, 0, ni->attr_list_size,
|
if (ntfs_attr_pwrite(na, 0, ni->attr_list_size,
|
||||||
ni->attr_list) != ni->attr_list_size) {
|
ni->attr_list) != ni->attr_list_size) {
|
||||||
@ -977,7 +977,7 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
|
|||||||
}
|
}
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_inode:
|
sync_inode:
|
||||||
/* Write this inode out to the $MFT (and $MFTMirr if applicable). */
|
/* Write this inode out to the $MFT (and $MFTMirr if applicable). */
|
||||||
if (NInoTestAndClearDirty(ni)) {
|
if (NInoTestAndClearDirty(ni)) {
|
||||||
@ -1003,8 +1003,8 @@ sync_inode:
|
|||||||
eni = ni->extent_nis[i];
|
eni = ni->extent_nis[i];
|
||||||
if (!NInoTestAndClearDirty(eni))
|
if (!NInoTestAndClearDirty(eni))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ntfs_mft_record_write(eni->vol, eni->mft_no,
|
if (ntfs_mft_record_write(eni->vol, eni->mft_no,
|
||||||
eni->mrec)) {
|
eni->mrec)) {
|
||||||
if (!err || errno == EIO) {
|
if (!err || errno == EIO) {
|
||||||
err = errno;
|
err = errno;
|
||||||
@ -1024,7 +1024,7 @@ sync_inode:
|
|||||||
errno = err;
|
errno = err;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -1093,20 +1093,20 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||||||
}
|
}
|
||||||
/* Walk through all attributes. */
|
/* Walk through all attributes. */
|
||||||
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
|
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
|
||||||
|
|
||||||
int ale_size;
|
int ale_size;
|
||||||
|
|
||||||
if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
|
if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
|
||||||
err = EIO;
|
err = EIO;
|
||||||
ntfs_log_perror("Attribute list already present");
|
ntfs_log_perror("Attribute list already present");
|
||||||
goto put_err_out;
|
goto put_err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
|
ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
|
||||||
ctx->attr->name_length + 7) & ~7;
|
ctx->attr->name_length + 7) & ~7;
|
||||||
al_len += ale_size;
|
al_len += ale_size;
|
||||||
|
|
||||||
aln = realloc(al, al_len);
|
aln = MEM2_realloc(al, al_len);
|
||||||
if (!aln) {
|
if (!aln) {
|
||||||
err = errno;
|
err = errno;
|
||||||
ntfs_log_perror("Failed to realloc %d bytes", al_len);
|
ntfs_log_perror("Failed to realloc %d bytes", al_len);
|
||||||
@ -1114,9 +1114,9 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||||||
}
|
}
|
||||||
ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al));
|
ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al));
|
||||||
al = aln;
|
al = aln;
|
||||||
|
|
||||||
memset(ale, 0, ale_size);
|
memset(ale, 0, ale_size);
|
||||||
|
|
||||||
/* Add attribute to attribute list. */
|
/* Add attribute to attribute list. */
|
||||||
ale->type = ctx->attr->type;
|
ale->type = ctx->attr->type;
|
||||||
ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) +
|
ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) +
|
||||||
@ -1183,7 +1183,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
goto remove_attrlist_record;;
|
goto remove_attrlist_record;;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_attr_put_search_ctx(ctx);
|
ntfs_attr_put_search_ctx(ctx);
|
||||||
ntfs_attr_close(na);
|
ntfs_attr_close(na);
|
||||||
return 0;
|
return 0;
|
||||||
@ -1284,12 +1284,12 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||||||
* find next, because we don't need such.
|
* find next, because we don't need such.
|
||||||
*/
|
*/
|
||||||
while (ctx->ntfs_ino->mft_no != ni->mft_no) {
|
while (ctx->ntfs_ino->mft_no != ni->mft_no) {
|
||||||
retry:
|
retry:
|
||||||
if (ntfs_attr_position(AT_UNUSED, ctx))
|
if (ntfs_attr_position(AT_UNUSED, ctx))
|
||||||
goto put_err_out;
|
goto put_err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT &&
|
if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT &&
|
||||||
ctx->attr->type == AT_DATA)
|
ctx->attr->type == AT_DATA)
|
||||||
goto retry;
|
goto retry;
|
||||||
|
|
||||||
@ -1310,10 +1310,10 @@ retry:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Reposition to first attribute after $STANDARD_INFORMATION
|
* Reposition to first attribute after $STANDARD_INFORMATION
|
||||||
* and $ATTRIBUTE_LIST instead of simply skipping this attribute
|
* and $ATTRIBUTE_LIST instead of simply skipping this attribute
|
||||||
* because in the case when we have got only in-memory attribute
|
* because in the case when we have got only in-memory attribute
|
||||||
* list then ntfs_attr_lookup will fail when it tries to find
|
* list then ntfs_attr_lookup will fail when it tries to find
|
||||||
* $ATTRIBUTE_LIST.
|
* $ATTRIBUTE_LIST.
|
||||||
*/
|
*/
|
||||||
ntfs_attr_reinit_search_ctx(ctx);
|
ntfs_attr_reinit_search_ctx(ctx);
|
||||||
@ -1355,7 +1355,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
|
|||||||
ni->last_data_change_time = now;
|
ni->last_data_change_time = now;
|
||||||
if (mask & NTFS_UPDATE_CTIME)
|
if (mask & NTFS_UPDATE_CTIME)
|
||||||
ni->last_mft_change_time = now;
|
ni->last_mft_change_time = now;
|
||||||
|
|
||||||
NInoFileNameSetDirty(ni);
|
NInoFileNameSetDirty(ni);
|
||||||
NInoSetDirty(ni);
|
NInoSetDirty(ni);
|
||||||
}
|
}
|
||||||
@ -1368,7 +1368,7 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
|
|||||||
* Check if the mft record given by @mft_no and @attr contains the bad sector
|
* Check if the mft record given by @mft_no and @attr contains the bad sector
|
||||||
* list. Please note that mft record numbers describing $Badclus extent inodes
|
* list. Please note that mft record numbers describing $Badclus extent inodes
|
||||||
* will not match the current $Badclus:$Bad check.
|
* will not match the current $Badclus:$Bad check.
|
||||||
*
|
*
|
||||||
* On success return 1 if the file is $Badclus:$Bad, otherwise return 0.
|
* On success return 1 if the file is $Badclus:$Bad, otherwise return 0.
|
||||||
* On error return -1 with errno set to the error code.
|
* On error return -1 with errno set to the error code.
|
||||||
*/
|
*/
|
||||||
@ -1382,7 +1382,7 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
|
|||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mft_no != FILE_BadClus)
|
if (mft_no != FILE_BadClus)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1456,7 +1456,7 @@ int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size)
|
|||||||
ret = -ERANGE;
|
ret = -ERANGE;
|
||||||
}
|
}
|
||||||
ntfs_attr_put_search_ctx(ctx);
|
ntfs_attr_put_search_ctx(ctx);
|
||||||
}
|
}
|
||||||
return (ret ? ret : -errno);
|
return (ret ? ret : -errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Plenty possibilities for big optimizations all over in the cluster
|
* Plenty possibilities for big optimizations all over in the cluster
|
||||||
* allocation, however at the moment the dominant bottleneck (~ 90%) is
|
* allocation, however at the moment the dominant bottleneck (~ 90%) is
|
||||||
* the update of the mapping pairs which converges to the cubic Faulhaber's
|
* the update of the mapping pairs which converges to the cubic Faulhaber's
|
||||||
* formula as the function of the number of extents (fragments, runs).
|
* formula as the function of the number of extents (fragments, runs).
|
||||||
*/
|
*/
|
||||||
@ -74,7 +74,7 @@ static void ntfs_cluster_set_zone_pos(LCN start, LCN end, LCN *pos, LCN tc)
|
|||||||
static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
|
static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
|
||||||
{
|
{
|
||||||
ntfs_log_trace("tc = %lld, zone = %d\n", (long long)tc, zone);
|
ntfs_log_trace("tc = %lld, zone = %d\n", (long long)tc, zone);
|
||||||
|
|
||||||
if (zone == ZONE_MFT)
|
if (zone == ZONE_MFT)
|
||||||
ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end,
|
ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end,
|
||||||
&vol->mft_zone_pos, tc);
|
&vol->mft_zone_pos, tc);
|
||||||
@ -82,7 +82,7 @@ static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
|
|||||||
ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters,
|
ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters,
|
||||||
&vol->data1_zone_pos, tc);
|
&vol->data1_zone_pos, tc);
|
||||||
else /* zone == ZONE_DATA2 */
|
else /* zone == ZONE_DATA2 */
|
||||||
ntfs_cluster_set_zone_pos(0, vol->mft_zone_start,
|
ntfs_cluster_set_zone_pos(0, vol->mft_zone_start,
|
||||||
&vol->data2_zone_pos, tc);
|
&vol->data2_zone_pos, tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,15 +112,15 @@ static void update_full_status(ntfs_volume *vol, LCN lcn)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static s64 max_empty_bit_range(unsigned char *buf, int size)
|
static s64 max_empty_bit_range(unsigned char *buf, int size)
|
||||||
{
|
{
|
||||||
int i, j, run = 0;
|
int i, j, run = 0;
|
||||||
int max_range = 0;
|
int max_range = 0;
|
||||||
s64 start_pos = -1;
|
s64 start_pos = -1;
|
||||||
|
|
||||||
ntfs_log_trace("Entering\n");
|
ntfs_log_trace("Entering\n");
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i < size) {
|
while (i < size) {
|
||||||
switch (*buf) {
|
switch (*buf) {
|
||||||
@ -144,42 +144,42 @@ static s64 max_empty_bit_range(unsigned char *buf, int size)
|
|||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
for (j = 0; j < 8; j++) {
|
for (j = 0; j < 8; j++) {
|
||||||
|
|
||||||
int bit = *buf & (1 << j);
|
int bit = *buf & (1 << j);
|
||||||
|
|
||||||
if (bit) {
|
if (bit) {
|
||||||
if (run > max_range) {
|
if (run > max_range) {
|
||||||
max_range = run;
|
max_range = run;
|
||||||
start_pos = (s64)i * 8 + (j - run);
|
start_pos = (s64)i * 8 + (j - run);
|
||||||
}
|
}
|
||||||
run = 0;
|
run = 0;
|
||||||
} else
|
} else
|
||||||
run++;
|
run++;
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
buf++;
|
buf++;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (run > max_range)
|
if (run > max_range)
|
||||||
start_pos = (s64)i * 8 - run;
|
start_pos = (s64)i * 8 - run;
|
||||||
|
|
||||||
return start_pos;
|
return start_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
|
static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
|
||||||
u8 *writeback)
|
u8 *writeback)
|
||||||
{
|
{
|
||||||
s64 written;
|
s64 written;
|
||||||
|
|
||||||
ntfs_log_trace("Entering\n");
|
ntfs_log_trace("Entering\n");
|
||||||
|
|
||||||
if (!*writeback)
|
if (!*writeback)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
*writeback = 0;
|
*writeback = 0;
|
||||||
|
|
||||||
written = ntfs_attr_pwrite(vol->lcnbmp_na, pos, size, b);
|
written = ntfs_attr_pwrite(vol->lcnbmp_na, pos, size, b);
|
||||||
if (written != size) {
|
if (written != size) {
|
||||||
if (!written)
|
if (!written)
|
||||||
@ -220,16 +220,16 @@ static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
|
|||||||
* expanded to cover the start of the volume in order to reserve space for the
|
* expanded to cover the start of the volume in order to reserve space for the
|
||||||
* mft bitmap attribute.
|
* mft bitmap attribute.
|
||||||
*
|
*
|
||||||
* The complexity stems from the need of implementing the mft vs data zoned
|
* The complexity stems from the need of implementing the mft vs data zoned
|
||||||
* approach and from the fact that we have access to the lcn bitmap via up to
|
* approach and from the fact that we have access to the lcn bitmap via up to
|
||||||
* NTFS_LCNALLOC_BSIZE bytes at a time, so we need to cope with crossing over
|
* NTFS_LCNALLOC_BSIZE bytes at a time, so we need to cope with crossing over
|
||||||
* boundaries of two buffers. Further, the fact that the allocator allows for
|
* boundaries of two buffers. Further, the fact that the allocator allows for
|
||||||
* caller supplied hints as to the location of where allocation should begin
|
* caller supplied hints as to the location of where allocation should begin
|
||||||
* and the fact that the allocator keeps track of where in the data zones the
|
* and the fact that the allocator keeps track of where in the data zones the
|
||||||
* next natural allocation should occur, contribute to the complexity of the
|
* next natural allocation should occur, contribute to the complexity of the
|
||||||
* function. But it should all be worthwhile, because this allocator:
|
* function. But it should all be worthwhile, because this allocator:
|
||||||
* 1) implements MFT zone reservation
|
* 1) implements MFT zone reservation
|
||||||
* 2) causes reduction in fragmentation.
|
* 2) causes reduction in fragmentation.
|
||||||
* The code is not optimized for speed.
|
* The code is not optimized for speed.
|
||||||
*/
|
*/
|
||||||
runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
||||||
@ -251,12 +251,12 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
ntfs_log_enter("Entering with count = 0x%llx, start_lcn = 0x%llx, "
|
ntfs_log_enter("Entering with count = 0x%llx, start_lcn = 0x%llx, "
|
||||||
"zone = %s_ZONE.\n", (long long)count, (long long)
|
"zone = %s_ZONE.\n", (long long)count, (long long)
|
||||||
start_lcn, zone == MFT_ZONE ? "MFT" : "DATA");
|
start_lcn, zone == MFT_ZONE ? "MFT" : "DATA");
|
||||||
|
|
||||||
if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
|
if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
|
||||||
(s8)zone < FIRST_ZONE || zone > LAST_ZONE) {
|
(s8)zone < FIRST_ZONE || zone > LAST_ZONE) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
ntfs_log_perror("%s: vcn: %lld, count: %lld, lcn: %lld",
|
ntfs_log_perror("%s: vcn: %lld, count: %lld, lcn: %lld",
|
||||||
__FUNCTION__, (long long)start_vcn,
|
__FUNCTION__, (long long)start_vcn,
|
||||||
(long long)count, (long long)start_lcn);
|
(long long)count, (long long)start_lcn);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -281,7 +281,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
*/
|
*/
|
||||||
has_guess = 1;
|
has_guess = 1;
|
||||||
zone_start = start_lcn;
|
zone_start = start_lcn;
|
||||||
|
|
||||||
if (zone_start < 0) {
|
if (zone_start < 0) {
|
||||||
if (zone == DATA_ZONE)
|
if (zone == DATA_ZONE)
|
||||||
zone_start = vol->data1_zone_pos;
|
zone_start = vol->data1_zone_pos;
|
||||||
@ -289,13 +289,13 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
zone_start = vol->mft_zone_pos;
|
zone_start = vol->mft_zone_pos;
|
||||||
has_guess = 0;
|
has_guess = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
used_zone_pos = has_guess ? 0 : 1;
|
used_zone_pos = has_guess ? 0 : 1;
|
||||||
|
|
||||||
if (!zone_start || zone_start == vol->mft_zone_start ||
|
if (!zone_start || zone_start == vol->mft_zone_start ||
|
||||||
zone_start == vol->mft_zone_end)
|
zone_start == vol->mft_zone_end)
|
||||||
pass = 2;
|
pass = 2;
|
||||||
|
|
||||||
if (zone_start < vol->mft_zone_start) {
|
if (zone_start < vol->mft_zone_start) {
|
||||||
zone_end = vol->mft_zone_start;
|
zone_end = vol->mft_zone_start;
|
||||||
search_zone = ZONE_DATA2;
|
search_zone = ZONE_DATA2;
|
||||||
@ -306,7 +306,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
zone_end = vol->nr_clusters;
|
zone_end = vol->nr_clusters;
|
||||||
search_zone = ZONE_DATA1;
|
search_zone = ZONE_DATA1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmp_pos = zone_start;
|
bmp_pos = zone_start;
|
||||||
|
|
||||||
/* Loop until all clusters are allocated. */
|
/* Loop until all clusters are allocated. */
|
||||||
@ -317,7 +317,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
if (search_zone & vol->full_zones)
|
if (search_zone & vol->full_zones)
|
||||||
goto zone_pass_done;
|
goto zone_pass_done;
|
||||||
last_read_pos = bmp_pos >> 3;
|
last_read_pos = bmp_pos >> 3;
|
||||||
br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos,
|
br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos,
|
||||||
NTFS_LCNALLOC_BSIZE, buf);
|
NTFS_LCNALLOC_BSIZE, buf);
|
||||||
if (br <= 0) {
|
if (br <= 0) {
|
||||||
if (!br)
|
if (!br)
|
||||||
@ -334,7 +334,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
lcn = bmp_pos & 7;
|
lcn = bmp_pos & 7;
|
||||||
bmp_pos &= ~7;
|
bmp_pos &= ~7;
|
||||||
writeback = 0;
|
writeback = 0;
|
||||||
|
|
||||||
while (lcn < buf_size) {
|
while (lcn < buf_size) {
|
||||||
byte = buf + (lcn >> 3);
|
byte = buf + (lcn >> 3);
|
||||||
bit = 1 << (lcn & 7);
|
bit = 1 << (lcn & 7);
|
||||||
@ -352,11 +352,11 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* First free bit is at lcn + bmp_pos. */
|
/* First free bit is at lcn + bmp_pos. */
|
||||||
|
|
||||||
/* Reallocate memory if necessary. */
|
/* Reallocate memory if necessary. */
|
||||||
if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) {
|
if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) {
|
||||||
rlsize += 4096;
|
rlsize += 4096;
|
||||||
trl = realloc(rl, rlsize);
|
trl = MEM2_realloc(rl, rlsize);
|
||||||
if (!trl) {
|
if (!trl) {
|
||||||
err = ENOMEM;
|
err = ENOMEM;
|
||||||
ntfs_log_perror("realloc() failed");
|
ntfs_log_perror("realloc() failed");
|
||||||
@ -364,17 +364,17 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
}
|
}
|
||||||
rl = trl;
|
rl = trl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Allocate the bitmap bit. */
|
/* Allocate the bitmap bit. */
|
||||||
*byte |= bit;
|
*byte |= bit;
|
||||||
writeback = 1;
|
writeback = 1;
|
||||||
if (vol->free_clusters <= 0)
|
if (vol->free_clusters <= 0)
|
||||||
ntfs_log_error("Non-positive free clusters "
|
ntfs_log_error("Non-positive free clusters "
|
||||||
"(%lld)!\n",
|
"(%lld)!\n",
|
||||||
(long long)vol->free_clusters);
|
(long long)vol->free_clusters);
|
||||||
else
|
else
|
||||||
vol->free_clusters--;
|
vol->free_clusters--;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Coalesce with previous run if adjacent LCNs.
|
* Coalesce with previous run if adjacent LCNs.
|
||||||
* Otherwise, append a new run.
|
* Otherwise, append a new run.
|
||||||
@ -382,9 +382,9 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) {
|
if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) {
|
||||||
ntfs_log_debug("Cluster coalesce: prev_lcn: "
|
ntfs_log_debug("Cluster coalesce: prev_lcn: "
|
||||||
"%lld lcn: %lld bmp_pos: %lld "
|
"%lld lcn: %lld bmp_pos: %lld "
|
||||||
"prev_run_len: %lld\n",
|
"prev_run_len: %lld\n",
|
||||||
(long long)prev_lcn,
|
(long long)prev_lcn,
|
||||||
(long long)lcn, (long long)bmp_pos,
|
(long long)lcn, (long long)bmp_pos,
|
||||||
(long long)prev_run_len);
|
(long long)prev_run_len);
|
||||||
rl[rlpos - 1].length = ++prev_run_len;
|
rl[rlpos - 1].length = ++prev_run_len;
|
||||||
} else {
|
} else {
|
||||||
@ -393,54 +393,54 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||||||
prev_run_len;
|
prev_run_len;
|
||||||
else {
|
else {
|
||||||
rl[rlpos].vcn = start_vcn;
|
rl[rlpos].vcn = start_vcn;
|
||||||
ntfs_log_debug("Start_vcn: %lld\n",
|
ntfs_log_debug("Start_vcn: %lld\n",
|
||||||
(long long)start_vcn);
|
(long long)start_vcn);
|
||||||
}
|
}
|
||||||
|
|
||||||
rl[rlpos].lcn = prev_lcn = lcn + bmp_pos;
|
rl[rlpos].lcn = prev_lcn = lcn + bmp_pos;
|
||||||
rl[rlpos].length = prev_run_len = 1;
|
rl[rlpos].length = prev_run_len = 1;
|
||||||
rlpos++;
|
rlpos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n",
|
ntfs_log_debug("RUN: %-16lld %-16lld %-16lld\n",
|
||||||
(long long)rl[rlpos - 1].vcn,
|
(long long)rl[rlpos - 1].vcn,
|
||||||
(long long)rl[rlpos - 1].lcn,
|
(long long)rl[rlpos - 1].lcn,
|
||||||
(long long)rl[rlpos - 1].length);
|
(long long)rl[rlpos - 1].length);
|
||||||
/* Done? */
|
/* Done? */
|
||||||
if (!--clusters) {
|
if (!--clusters) {
|
||||||
if (used_zone_pos)
|
if (used_zone_pos)
|
||||||
ntfs_cluster_update_zone_pos(vol,
|
ntfs_cluster_update_zone_pos(vol,
|
||||||
search_zone, lcn + bmp_pos + 1 +
|
search_zone, lcn + bmp_pos + 1 +
|
||||||
NTFS_LCNALLOC_SKIP);
|
NTFS_LCNALLOC_SKIP);
|
||||||
goto done_ret;
|
goto done_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
lcn++;
|
lcn++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) {
|
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) {
|
||||||
err = errno;
|
err = errno;
|
||||||
goto err_ret;
|
goto err_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!used_zone_pos) {
|
if (!used_zone_pos) {
|
||||||
|
|
||||||
used_zone_pos = 1;
|
used_zone_pos = 1;
|
||||||
|
|
||||||
if (search_zone == ZONE_MFT)
|
if (search_zone == ZONE_MFT)
|
||||||
zone_start = vol->mft_zone_pos;
|
zone_start = vol->mft_zone_pos;
|
||||||
else if (search_zone == ZONE_DATA1)
|
else if (search_zone == ZONE_DATA1)
|
||||||
zone_start = vol->data1_zone_pos;
|
zone_start = vol->data1_zone_pos;
|
||||||
else
|
else
|
||||||
zone_start = vol->data2_zone_pos;
|
zone_start = vol->data2_zone_pos;
|
||||||
|
|
||||||
if (!zone_start || zone_start == vol->mft_zone_start ||
|
if (!zone_start || zone_start == vol->mft_zone_start ||
|
||||||
zone_start == vol->mft_zone_end)
|
zone_start == vol->mft_zone_end)
|
||||||
pass = 2;
|
pass = 2;
|
||||||
bmp_pos = zone_start;
|
bmp_pos = zone_start;
|
||||||
} else
|
} else
|
||||||
bmp_pos += buf_size;
|
bmp_pos += buf_size;
|
||||||
|
|
||||||
if (bmp_pos < zone_end)
|
if (bmp_pos < zone_end)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -449,22 +449,22 @@ zone_pass_done:
|
|||||||
if (pass == 1) {
|
if (pass == 1) {
|
||||||
pass = 2;
|
pass = 2;
|
||||||
zone_end = zone_start;
|
zone_end = zone_start;
|
||||||
|
|
||||||
if (search_zone == ZONE_MFT)
|
if (search_zone == ZONE_MFT)
|
||||||
zone_start = vol->mft_zone_start;
|
zone_start = vol->mft_zone_start;
|
||||||
else if (search_zone == ZONE_DATA1)
|
else if (search_zone == ZONE_DATA1)
|
||||||
zone_start = vol->mft_zone_end;
|
zone_start = vol->mft_zone_end;
|
||||||
else
|
else
|
||||||
zone_start = 0;
|
zone_start = 0;
|
||||||
|
|
||||||
/* Sanity check. */
|
/* Sanity check. */
|
||||||
if (zone_end < zone_start)
|
if (zone_end < zone_start)
|
||||||
zone_end = zone_start;
|
zone_end = zone_start;
|
||||||
|
|
||||||
bmp_pos = zone_start;
|
bmp_pos = zone_start;
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
/* pass == 2 */
|
/* pass == 2 */
|
||||||
done_zones_check:
|
done_zones_check:
|
||||||
done_zones |= search_zone;
|
done_zones |= search_zone;
|
||||||
@ -473,14 +473,14 @@ done_zones_check:
|
|||||||
ntfs_log_trace("Switching zone.\n");
|
ntfs_log_trace("Switching zone.\n");
|
||||||
pass = 1;
|
pass = 1;
|
||||||
if (rlpos) {
|
if (rlpos) {
|
||||||
LCN tc = rl[rlpos - 1].lcn +
|
LCN tc = rl[rlpos - 1].lcn +
|
||||||
rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP;
|
rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP;
|
||||||
|
|
||||||
if (used_zone_pos)
|
if (used_zone_pos)
|
||||||
ntfs_cluster_update_zone_pos(vol,
|
ntfs_cluster_update_zone_pos(vol,
|
||||||
search_zone, tc);
|
search_zone, tc);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (search_zone) {
|
switch (search_zone) {
|
||||||
case ZONE_MFT:
|
case ZONE_MFT:
|
||||||
ntfs_log_trace("Zone switch: mft -> data1\n");
|
ntfs_log_trace("Zone switch: mft -> data1\n");
|
||||||
@ -511,17 +511,17 @@ switch_to_data1_zone: search_zone = ZONE_DATA1;
|
|||||||
pass = 2;
|
pass = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bmp_pos = zone_start;
|
bmp_pos = zone_start;
|
||||||
|
|
||||||
if (zone_start == zone_end) {
|
if (zone_start == zone_end) {
|
||||||
ntfs_log_trace("Empty zone, skipped.\n");
|
ntfs_log_trace("Empty zone, skipped.\n");
|
||||||
goto done_zones_check;
|
goto done_zones_check;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_log_trace("All zones are finished, no space on device.\n");
|
ntfs_log_trace("All zones are finished, no space on device.\n");
|
||||||
err = ENOSPC;
|
err = ENOSPC;
|
||||||
goto err_ret;
|
goto err_ret;
|
||||||
@ -543,7 +543,7 @@ done_err_ret:
|
|||||||
ntfs_log_perror("Failed to allocate clusters");
|
ntfs_log_perror("Failed to allocate clusters");
|
||||||
rl = NULL;
|
rl = NULL;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
return rl;
|
return rl;
|
||||||
|
|
||||||
@ -585,26 +585,26 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl)
|
|||||||
ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n",
|
ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n",
|
||||||
(long long)rl->lcn, (long long)rl->length);
|
(long long)rl->lcn, (long long)rl->length);
|
||||||
|
|
||||||
if (rl->lcn >= 0) {
|
if (rl->lcn >= 0) {
|
||||||
update_full_status(vol,rl->lcn);
|
update_full_status(vol,rl->lcn);
|
||||||
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn,
|
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn,
|
||||||
rl->length)) {
|
rl->length)) {
|
||||||
ntfs_log_perror("Cluster deallocation failed "
|
ntfs_log_perror("Cluster deallocation failed "
|
||||||
"(%lld, %lld)",
|
"(%lld, %lld)",
|
||||||
(long long)rl->lcn,
|
(long long)rl->lcn,
|
||||||
(long long)rl->length);
|
(long long)rl->length);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nr_freed += rl->length ;
|
nr_freed += rl->length ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
vol->free_clusters += nr_freed;
|
vol->free_clusters += nr_freed;
|
||||||
if (vol->free_clusters > vol->nr_clusters)
|
if (vol->free_clusters > vol->nr_clusters)
|
||||||
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
||||||
(long long)vol->free_clusters,
|
(long long)vol->free_clusters,
|
||||||
(long long)vol->nr_clusters);
|
(long long)vol->nr_clusters);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -623,24 +623,24 @@ int ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count)
|
|||||||
ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n",
|
ntfs_log_trace("Dealloc lcn 0x%llx, len 0x%llx.\n",
|
||||||
(long long)lcn, (long long)count);
|
(long long)lcn, (long long)count);
|
||||||
|
|
||||||
if (lcn >= 0) {
|
if (lcn >= 0) {
|
||||||
update_full_status(vol,lcn);
|
update_full_status(vol,lcn);
|
||||||
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn,
|
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn,
|
||||||
count)) {
|
count)) {
|
||||||
ntfs_log_perror("Cluster deallocation failed "
|
ntfs_log_perror("Cluster deallocation failed "
|
||||||
"(%lld, %lld)",
|
"(%lld, %lld)",
|
||||||
(long long)lcn,
|
(long long)lcn,
|
||||||
(long long)count);
|
(long long)count);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nr_freed += count;
|
nr_freed += count;
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
out:
|
out:
|
||||||
vol->free_clusters += nr_freed;
|
vol->free_clusters += nr_freed;
|
||||||
if (vol->free_clusters > vol->nr_clusters)
|
if (vol->free_clusters > vol->nr_clusters)
|
||||||
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
||||||
(long long)vol->free_clusters,
|
(long long)vol->free_clusters,
|
||||||
(long long)vol->nr_clusters);
|
(long long)vol->nr_clusters);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -673,7 +673,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x, count 0x%llx, "
|
ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x, count 0x%llx, "
|
||||||
"vcn 0x%llx.\n", (unsigned long long)na->ni->mft_no,
|
"vcn 0x%llx.\n", (unsigned long long)na->ni->mft_no,
|
||||||
na->type, (long long)count, (long long)start_vcn);
|
na->type, (long long)count, (long long)start_vcn);
|
||||||
@ -687,7 +687,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||||||
|
|
||||||
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
|
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__,
|
ntfs_log_perror("%s: Unexpected lcn (%lld)", __FUNCTION__,
|
||||||
(long long)rl->lcn);
|
(long long)rl->lcn);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
@ -707,7 +707,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||||||
to_free))
|
to_free))
|
||||||
goto leave;
|
goto leave;
|
||||||
nr_freed = to_free;
|
nr_freed = to_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Go to the next run and adjust the number of clusters left to free. */
|
/* Go to the next run and adjust the number of clusters left to free. */
|
||||||
++rl;
|
++rl;
|
||||||
@ -724,7 +724,7 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||||||
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
|
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
|
||||||
// FIXME: Eeek! We need rollback! (AIA)
|
// FIXME: Eeek! We need rollback! (AIA)
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
ntfs_log_perror("%s: Invalid lcn (%lli)",
|
ntfs_log_perror("%s: Invalid lcn (%lli)",
|
||||||
__FUNCTION__, (long long)rl->lcn);
|
__FUNCTION__, (long long)rl->lcn);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -760,12 +760,12 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
|
|||||||
|
|
||||||
ret = nr_freed;
|
ret = nr_freed;
|
||||||
out:
|
out:
|
||||||
vol->free_clusters += nr_freed ;
|
vol->free_clusters += nr_freed ;
|
||||||
if (vol->free_clusters > vol->nr_clusters)
|
if (vol->free_clusters > vol->nr_clusters)
|
||||||
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
ntfs_log_error("Too many free clusters (%lld > %lld)!",
|
||||||
(long long)vol->free_clusters,
|
(long long)vol->free_clusters,
|
||||||
(long long)vol->nr_clusters);
|
(long long)vol->nr_clusters);
|
||||||
leave:
|
leave:
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -34,17 +34,21 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
#include "mem2.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ntfs_calloc
|
* ntfs_calloc
|
||||||
*
|
*
|
||||||
* Return a pointer to the allocated memory or NULL if the request fails.
|
* Return a pointer to the allocated memory or NULL if the request fails.
|
||||||
*/
|
*/
|
||||||
void *ntfs_calloc(size_t size)
|
void *ntfs_calloc(size_t size)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
p = calloc(1, size);
|
p = MEM2_alloc(size);
|
||||||
|
if(p)
|
||||||
|
memset(p, 0, size);
|
||||||
|
|
||||||
if (!p)
|
if (!p)
|
||||||
ntfs_log_perror("Failed to calloc %lld bytes", (long long)size);
|
ntfs_log_perror("Failed to calloc %lld bytes", (long long)size);
|
||||||
return p;
|
return p;
|
||||||
@ -53,8 +57,8 @@ void *ntfs_calloc(size_t size)
|
|||||||
void *ntfs_malloc(size_t size)
|
void *ntfs_malloc(size_t size)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
p = malloc(size);
|
p = MEM2_alloc(size);
|
||||||
if (!p)
|
if (!p)
|
||||||
ntfs_log_perror("Failed to malloc %lld bytes", (long long)size);
|
ntfs_log_perror("Failed to malloc %lld bytes", (long long)size);
|
||||||
return p;
|
return p;
|
||||||
|
@ -101,14 +101,15 @@ static void ntfs_rl_mc(runlist_element *dstbase, int dst,
|
|||||||
* On success, return a pointer to the newly allocated, or recycled, memory.
|
* On success, return a pointer to the newly allocated, or recycled, memory.
|
||||||
* On error, return NULL with errno set to the error code.
|
* On error, return NULL with errno set to the error code.
|
||||||
*/
|
*/
|
||||||
static runlist_element *ntfs_rl_realloc(runlist_element *rl, int old_size,
|
#include "mem2.h"
|
||||||
|
static runlist_element *ntfs_rl_realloc(runlist_element *rl, int old_size,
|
||||||
int new_size)
|
int new_size)
|
||||||
{
|
{
|
||||||
old_size = (old_size * sizeof(runlist_element) + 0xfff) & ~0xfff;
|
old_size = (old_size * sizeof(runlist_element) + 0xfff) & ~0xfff;
|
||||||
new_size = (new_size * sizeof(runlist_element) + 0xfff) & ~0xfff;
|
new_size = (new_size * sizeof(runlist_element) + 0xfff) & ~0xfff;
|
||||||
if (old_size == new_size)
|
if (old_size == new_size)
|
||||||
return rl;
|
return rl;
|
||||||
return realloc(rl, new_size);
|
return MEM2_realloc(rl, new_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -381,7 +382,7 @@ static runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize,
|
|||||||
* left unmodified.
|
* left unmodified.
|
||||||
*/
|
*/
|
||||||
static runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize,
|
static runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize,
|
||||||
runlist_element *src, int ssize,
|
runlist_element *src, int ssize,
|
||||||
int loc)
|
int loc)
|
||||||
{
|
{
|
||||||
signed delta;
|
signed delta;
|
||||||
@ -502,7 +503,7 @@ static runlist_element *ntfs_rl_split(runlist_element *dst, int dsize,
|
|||||||
/**
|
/**
|
||||||
* ntfs_runlists_merge_i - see ntfs_runlists_merge
|
* ntfs_runlists_merge_i - see ntfs_runlists_merge
|
||||||
*/
|
*/
|
||||||
static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
|
static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
|
||||||
runlist_element *srl)
|
runlist_element *srl)
|
||||||
{
|
{
|
||||||
int di, si; /* Current index into @[ds]rl. */
|
int di, si; /* Current index into @[ds]rl. */
|
||||||
@ -744,8 +745,8 @@ critical_error:
|
|||||||
runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
runlist_element *ntfs_runlists_merge(runlist_element *drl,
|
||||||
runlist_element *srl)
|
runlist_element *srl)
|
||||||
{
|
{
|
||||||
runlist_element *rl;
|
runlist_element *rl;
|
||||||
|
|
||||||
ntfs_log_enter("Entering\n");
|
ntfs_log_enter("Entering\n");
|
||||||
rl = ntfs_runlists_merge_i(drl, srl);
|
rl = ntfs_runlists_merge_i(drl, srl);
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
@ -835,7 +836,7 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
|
|||||||
runlist_element *rl2;
|
runlist_element *rl2;
|
||||||
|
|
||||||
rlsize += 0x1000;
|
rlsize += 0x1000;
|
||||||
rl2 = realloc(rl, rlsize);
|
rl2 = MEM2_realloc(rl, rlsize);
|
||||||
if (!rl2) {
|
if (!rl2) {
|
||||||
int eo = errno;
|
int eo = errno;
|
||||||
free(rl);
|
free(rl);
|
||||||
@ -1006,8 +1007,8 @@ err_out:
|
|||||||
runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
|
||||||
const ATTR_RECORD *attr, runlist_element *old_rl)
|
const ATTR_RECORD *attr, runlist_element *old_rl)
|
||||||
{
|
{
|
||||||
runlist_element *rle;
|
runlist_element *rle;
|
||||||
|
|
||||||
ntfs_log_enter("Entering\n");
|
ntfs_log_enter("Entering\n");
|
||||||
rle = ntfs_mapping_pairs_decompress_i(vol, attr, old_rl);
|
rle = ntfs_mapping_pairs_decompress_i(vol, attr, old_rl);
|
||||||
ntfs_log_leave("\n");
|
ntfs_log_leave("\n");
|
||||||
@ -1211,10 +1212,10 @@ s64 ntfs_rl_pwrite(const ntfs_volume *vol, const runlist_element *rl,
|
|||||||
|
|
||||||
if (rl->lcn != (LCN)LCN_HOLE)
|
if (rl->lcn != (LCN)LCN_HOLE)
|
||||||
goto rl_err_out;
|
goto rl_err_out;
|
||||||
|
|
||||||
to_write = min(count, (rl->length <<
|
to_write = min(count, (rl->length <<
|
||||||
vol->cluster_size_bits) - ofs);
|
vol->cluster_size_bits) - ofs);
|
||||||
|
|
||||||
total += to_write;
|
total += to_write;
|
||||||
count -= to_write;
|
count -= to_write;
|
||||||
b = (u8*)b + to_write;
|
b = (u8*)b + to_write;
|
||||||
@ -1384,14 +1385,14 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
|
|||||||
prev_lcn = rl->lcn;
|
prev_lcn = rl->lcn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
return rls;
|
return rls;
|
||||||
err_out:
|
err_out:
|
||||||
if (rl->lcn == LCN_RL_NOT_MAPPED)
|
if (rl->lcn == LCN_RL_NOT_MAPPED)
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
else
|
else
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
errno_set:
|
errno_set:
|
||||||
rls = -1;
|
rls = -1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@ -1590,7 +1591,7 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
|
|||||||
/* Set stop vcn. */
|
/* Set stop vcn. */
|
||||||
if (stop_rl)
|
if (stop_rl)
|
||||||
*stop_rl = rl;
|
*stop_rl = rl;
|
||||||
ok:
|
ok:
|
||||||
/* Add terminator byte. */
|
/* Add terminator byte. */
|
||||||
*dst = 0;
|
*dst = 0;
|
||||||
out:
|
out:
|
||||||
@ -1644,31 +1645,31 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
|
|||||||
" arl: %p *arl: %p", arl, *arl);
|
" arl: %p *arl: %p", arl, *arl);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rl = *arl;
|
rl = *arl;
|
||||||
|
|
||||||
if (start_vcn < rl->vcn) {
|
if (start_vcn < rl->vcn) {
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
ntfs_log_perror("Start_vcn lies outside front of runlist");
|
ntfs_log_perror("Start_vcn lies outside front of runlist");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Find the starting vcn in the run list. */
|
/* Find the starting vcn in the run list. */
|
||||||
while (rl->length) {
|
while (rl->length) {
|
||||||
if (start_vcn < rl[1].vcn)
|
if (start_vcn < rl[1].vcn)
|
||||||
break;
|
break;
|
||||||
rl++;
|
rl++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!rl->length) {
|
if (!rl->length) {
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
ntfs_log_trace("Truncating already truncated runlist?\n");
|
ntfs_log_trace("Truncating already truncated runlist?\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Truncate the run. */
|
/* Truncate the run. */
|
||||||
rl->length = start_vcn - rl->vcn;
|
rl->length = start_vcn - rl->vcn;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If a run was partially truncated, make the following runlist
|
* If a run was partially truncated, make the following runlist
|
||||||
* element a terminator instead of the truncated runlist
|
* element a terminator instead of the truncated runlist
|
||||||
@ -1684,10 +1685,10 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
|
|||||||
rl->lcn = (LCN)LCN_ENOENT;
|
rl->lcn = (LCN)LCN_ENOENT;
|
||||||
/**
|
/**
|
||||||
* Reallocate memory if necessary.
|
* Reallocate memory if necessary.
|
||||||
* FIXME: Below code is broken, because runlist allocations must be
|
* FIXME: Below code is broken, because runlist allocations must be
|
||||||
* a multiply of 4096. The code caused crashes and corruptions.
|
* a multiply of 4096. The code caused crashes and corruptions.
|
||||||
*/
|
*/
|
||||||
/*
|
/*
|
||||||
if (!is_end) {
|
if (!is_end) {
|
||||||
size_t new_size = (rl - *arl + 1) * sizeof(runlist_element);
|
size_t new_size = (rl - *arl + 1) * sizeof(runlist_element);
|
||||||
rl = realloc(*arl, new_size);
|
rl = realloc(*arl, new_size);
|
||||||
@ -1900,7 +1901,7 @@ static runlist_element * test_rl_pure_src(BOOL contig, BOOL multi, int vcn, int
|
|||||||
result = ntfs_malloc(4096);
|
result = ntfs_malloc(4096);
|
||||||
if (!result)
|
if (!result)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (multi) {
|
if (multi) {
|
||||||
MKRL(result+0, vcn + (0*len/4), fudge + vcn + 1000 + (0*len/4), len / 4)
|
MKRL(result+0, vcn + (0*len/4), fudge + vcn + 1000 + (0*len/4), len / 4)
|
||||||
MKRL(result+1, vcn + (1*len/4), fudge + vcn + 1000 + (1*len/4), len / 4)
|
MKRL(result+1, vcn + (1*len/4), fudge + vcn + 1000 + (1*len/4), len / 4)
|
||||||
|
@ -127,8 +127,8 @@ struct SDH { /* this is an image of an $SDH index entry */
|
|||||||
|
|
||||||
static ntfschar sii_stream[] = { const_cpu_to_le16('$'),
|
static ntfschar sii_stream[] = { const_cpu_to_le16('$'),
|
||||||
const_cpu_to_le16('S'),
|
const_cpu_to_le16('S'),
|
||||||
const_cpu_to_le16('I'),
|
const_cpu_to_le16('I'),
|
||||||
const_cpu_to_le16('I'),
|
const_cpu_to_le16('I'),
|
||||||
const_cpu_to_le16(0) };
|
const_cpu_to_le16(0) };
|
||||||
static ntfschar sdh_stream[] = { const_cpu_to_le16('$'),
|
static ntfschar sdh_stream[] = { const_cpu_to_le16('$'),
|
||||||
const_cpu_to_le16('S'),
|
const_cpu_to_le16('S'),
|
||||||
@ -769,7 +769,7 @@ static le32 entersecurityattr(ntfs_volume *vol,
|
|||||||
retries = 0;
|
retries = 0;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
next = ntfs_index_next(entry,xsii);
|
next = ntfs_index_next(entry,xsii);
|
||||||
if (next) {
|
if (next) {
|
||||||
psii = (struct SII*)next;
|
psii = (struct SII*)next;
|
||||||
/* save last key and */
|
/* save last key and */
|
||||||
/* available position */
|
/* available position */
|
||||||
@ -1109,7 +1109,7 @@ static int update_secur_descr(ntfs_volume *vol,
|
|||||||
* This is intended to allow graceful upgrades for files which
|
* This is intended to allow graceful upgrades for files which
|
||||||
* were created in previous versions, with a security attributes
|
* were created in previous versions, with a security attributes
|
||||||
* and no security id.
|
* and no security id.
|
||||||
*
|
*
|
||||||
* It will allocate a security id and replace the individual
|
* It will allocate a security id and replace the individual
|
||||||
* security attribute by a reference to the global one
|
* security attribute by a reference to the global one
|
||||||
*
|
*
|
||||||
@ -1458,7 +1458,7 @@ static int leg_compare(const struct CACHED_PERMISSIONS_LEGACY *cached,
|
|||||||
/*
|
/*
|
||||||
* Resize permission cache table
|
* Resize permission cache table
|
||||||
* do not call unless resizing is needed
|
* do not call unless resizing is needed
|
||||||
*
|
*
|
||||||
* If allocation fails, the cache size is not updated
|
* If allocation fails, the cache size is not updated
|
||||||
* Lack of memory is not considered as an error, the cache is left
|
* Lack of memory is not considered as an error, the cache is left
|
||||||
* consistent and errno is not set.
|
* consistent and errno is not set.
|
||||||
@ -1554,7 +1554,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx,
|
|||||||
if (pxdesc) {
|
if (pxdesc) {
|
||||||
pxsize = sizeof(struct POSIX_SECURITY)
|
pxsize = sizeof(struct POSIX_SECURITY)
|
||||||
+ (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
+ (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
||||||
pxcached = (struct POSIX_SECURITY*)malloc(pxsize);
|
pxcached = (struct POSIX_SECURITY*)ntfs_malloc(pxsize);
|
||||||
if (pxcached) {
|
if (pxcached) {
|
||||||
memcpy(pxcached, pxdesc, pxsize);
|
memcpy(pxcached, pxdesc, pxsize);
|
||||||
cacheentry->pxdesc = pxcached;
|
cacheentry->pxdesc = pxcached;
|
||||||
@ -1585,7 +1585,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx,
|
|||||||
/* allocate block, if cache table was allocated */
|
/* allocate block, if cache table was allocated */
|
||||||
if (pcache && (index1 <= pcache->head.last)) {
|
if (pcache && (index1 <= pcache->head.last)) {
|
||||||
cacheblock = (struct CACHED_PERMISSIONS*)
|
cacheblock = (struct CACHED_PERMISSIONS*)
|
||||||
malloc(sizeof(struct CACHED_PERMISSIONS)
|
ntfs_malloc(sizeof(struct CACHED_PERMISSIONS)
|
||||||
<< CACHE_PERMISSIONS_BITS);
|
<< CACHE_PERMISSIONS_BITS);
|
||||||
pcache->cachetable[index1] = cacheblock;
|
pcache->cachetable[index1] = cacheblock;
|
||||||
for (i=0; i<(1 << CACHE_PERMISSIONS_BITS); i++)
|
for (i=0; i<(1 << CACHE_PERMISSIONS_BITS); i++)
|
||||||
@ -1598,7 +1598,7 @@ static struct CACHED_PERMISSIONS *enter_cache(struct SECURITY_CONTEXT *scx,
|
|||||||
if (pxdesc) {
|
if (pxdesc) {
|
||||||
pxsize = sizeof(struct POSIX_SECURITY)
|
pxsize = sizeof(struct POSIX_SECURITY)
|
||||||
+ (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
+ (pxdesc->acccnt + pxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
||||||
pxcached = (struct POSIX_SECURITY*)malloc(pxsize);
|
pxcached = (struct POSIX_SECURITY*)ntfs_malloc(pxsize);
|
||||||
if (pxcached) {
|
if (pxcached) {
|
||||||
memcpy(pxcached, pxdesc, pxsize);
|
memcpy(pxcached, pxdesc, pxsize);
|
||||||
cacheentry->pxdesc = pxcached;
|
cacheentry->pxdesc = pxcached;
|
||||||
@ -2088,7 +2088,7 @@ static int ntfs_get_perm(struct SECURITY_CONTEXT *scx,
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
|
int ntfs_get_posix_acl(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
|
||||||
const char *name, char *value, size_t size)
|
const char *name, char *value, size_t size)
|
||||||
{
|
{
|
||||||
const SECURITY_DESCRIPTOR_RELATIVE *phead;
|
const SECURITY_DESCRIPTOR_RELATIVE *phead;
|
||||||
struct POSIX_SECURITY *pxdesc;
|
struct POSIX_SECURITY *pxdesc;
|
||||||
@ -2429,7 +2429,7 @@ int ntfs_get_owner_mode(struct SECURITY_CONTEXT *scx,
|
|||||||
stbuf->st_uid = ntfs_find_user(scx->mapping[MAPUSERS],usid);
|
stbuf->st_uid = ntfs_find_user(scx->mapping[MAPUSERS],usid);
|
||||||
#else
|
#else
|
||||||
if (!perm && ntfs_same_sid(usid, adminsid)) {
|
if (!perm && ntfs_same_sid(usid, adminsid)) {
|
||||||
stbuf->st_uid =
|
stbuf->st_uid =
|
||||||
find_tenant(scx,
|
find_tenant(scx,
|
||||||
securattr);
|
securattr);
|
||||||
if (stbuf->st_uid)
|
if (stbuf->st_uid)
|
||||||
@ -2541,7 +2541,7 @@ static struct POSIX_SECURITY *inherit_posix(struct SECURITY_CONTEXT *scx,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a security_id for a file being created
|
* Allocate a security_id for a file being created
|
||||||
*
|
*
|
||||||
* Returns zero if not possible (NTFS v3.x required)
|
* Returns zero if not possible (NTFS v3.x required)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -2763,7 +2763,7 @@ le32 ntfs_alloc_securid(struct SECURITY_CONTEXT *scx,
|
|||||||
/*
|
/*
|
||||||
* Update ownership and mode of a file, reusing an existing
|
* Update ownership and mode of a file, reusing an existing
|
||||||
* security descriptor when possible
|
* security descriptor when possible
|
||||||
*
|
*
|
||||||
* Returns zero if successful
|
* Returns zero if successful
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -3177,7 +3177,7 @@ int ntfs_set_mode(struct SECURITY_CONTEXT *scx, ntfs_inode *ni, mode_t mode)
|
|||||||
/* must copy before merging */
|
/* must copy before merging */
|
||||||
pxsize = sizeof(struct POSIX_SECURITY)
|
pxsize = sizeof(struct POSIX_SECURITY)
|
||||||
+ (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
+ (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
||||||
newpxdesc = (struct POSIX_SECURITY*)malloc(pxsize);
|
newpxdesc = (struct POSIX_SECURITY*)ntfs_malloc(pxsize);
|
||||||
if (newpxdesc) {
|
if (newpxdesc) {
|
||||||
memcpy(newpxdesc, oldpxdesc, pxsize);
|
memcpy(newpxdesc, oldpxdesc, pxsize);
|
||||||
if (ntfs_merge_mode_posix(newpxdesc, mode))
|
if (ntfs_merge_mode_posix(newpxdesc, mode))
|
||||||
@ -3265,7 +3265,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||||||
ACCESS_ALLOWED_ACE *ace;
|
ACCESS_ALLOWED_ACE *ace;
|
||||||
SID *sid;
|
SID *sid;
|
||||||
int ret, sd_len;
|
int ret, sd_len;
|
||||||
|
|
||||||
/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
|
/* Create SECURITY_DESCRIPTOR attribute (everyone has full access). */
|
||||||
/*
|
/*
|
||||||
* Calculate security descriptor length. We have 2 sub-authorities in
|
* Calculate security descriptor length. We have 2 sub-authorities in
|
||||||
@ -3273,14 +3273,14 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||||||
* 4 bytes to every SID.
|
* 4 bytes to every SID.
|
||||||
*/
|
*/
|
||||||
sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +
|
sd_len = sizeof(SECURITY_DESCRIPTOR_ATTR) + 2 * (sizeof(SID) + 4) +
|
||||||
sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
|
sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE);
|
||||||
sd = (SECURITY_DESCRIPTOR_RELATIVE*)ntfs_calloc(sd_len);
|
sd = (SECURITY_DESCRIPTOR_RELATIVE*)ntfs_calloc(sd_len);
|
||||||
if (!sd)
|
if (!sd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
sd->revision = SECURITY_DESCRIPTOR_REVISION;
|
sd->revision = SECURITY_DESCRIPTOR_REVISION;
|
||||||
sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
|
sd->control = SE_DACL_PRESENT | SE_SELF_RELATIVE;
|
||||||
|
|
||||||
sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
|
sid = (SID*)((u8*)sd + sizeof(SECURITY_DESCRIPTOR_ATTR));
|
||||||
sid->revision = SID_REVISION;
|
sid->revision = SID_REVISION;
|
||||||
sid->sub_authority_count = 2;
|
sid->sub_authority_count = 2;
|
||||||
@ -3288,21 +3288,21 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||||||
sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
||||||
sid->identifier_authority.value[5] = 5;
|
sid->identifier_authority.value[5] = 5;
|
||||||
sd->owner = cpu_to_le32((u8*)sid - (u8*)sd);
|
sd->owner = cpu_to_le32((u8*)sid - (u8*)sd);
|
||||||
|
|
||||||
sid = (SID*)((u8*)sid + sizeof(SID) + 4);
|
sid = (SID*)((u8*)sid + sizeof(SID) + 4);
|
||||||
sid->revision = SID_REVISION;
|
sid->revision = SID_REVISION;
|
||||||
sid->sub_authority_count = 2;
|
sid->sub_authority_count = 2;
|
||||||
sid->sub_authority[0] = const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
|
sid->sub_authority[0] = const_cpu_to_le32(SECURITY_BUILTIN_DOMAIN_RID);
|
||||||
sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
sid->sub_authority[1] = const_cpu_to_le32(DOMAIN_ALIAS_RID_ADMINS);
|
||||||
sid->identifier_authority.value[5] = 5;
|
sid->identifier_authority.value[5] = 5;
|
||||||
sd->group = cpu_to_le32((u8*)sid - (u8*)sd);
|
sd->group = cpu_to_le32((u8*)sid - (u8*)sd);
|
||||||
|
|
||||||
acl = (ACL*)((u8*)sid + sizeof(SID) + 4);
|
acl = (ACL*)((u8*)sid + sizeof(SID) + 4);
|
||||||
acl->revision = ACL_REVISION;
|
acl->revision = ACL_REVISION;
|
||||||
acl->size = const_cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
|
acl->size = const_cpu_to_le16(sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE));
|
||||||
acl->ace_count = const_cpu_to_le16(1);
|
acl->ace_count = const_cpu_to_le16(1);
|
||||||
sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd);
|
sd->dacl = cpu_to_le32((u8*)acl - (u8*)sd);
|
||||||
|
|
||||||
ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL));
|
ace = (ACCESS_ALLOWED_ACE*)((u8*)acl + sizeof(ACL));
|
||||||
ace->type = ACCESS_ALLOWED_ACE_TYPE;
|
ace->type = ACCESS_ALLOWED_ACE_TYPE;
|
||||||
ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
ace->flags = OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE;
|
||||||
@ -3317,7 +3317,7 @@ int ntfs_sd_add_everyone(ntfs_inode *ni)
|
|||||||
sd_len);
|
sd_len);
|
||||||
if (ret)
|
if (ret)
|
||||||
ntfs_log_perror("Failed to add initial SECURITY_DESCRIPTOR");
|
ntfs_log_perror("Failed to add initial SECURITY_DESCRIPTOR");
|
||||||
|
|
||||||
free(sd);
|
free(sd);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -3416,7 +3416,7 @@ int ntfs_allowed_access(struct SECURITY_CONTEXT *scx,
|
|||||||
*
|
*
|
||||||
* Returns true if access is allowed, including user is root and
|
* Returns true if access is allowed, including user is root and
|
||||||
* no user mapping defined
|
* no user mapping defined
|
||||||
*
|
*
|
||||||
* Sets errno if there is a problem or if not allowed
|
* Sets errno if there is a problem or if not allowed
|
||||||
*
|
*
|
||||||
* This is used for Posix ACL and checking creation of DOS file names
|
* This is used for Posix ACL and checking creation of DOS file names
|
||||||
@ -3564,7 +3564,7 @@ int ntfs_set_owner(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
|
|||||||
if (uid && (fileuid != uid))
|
if (uid && (fileuid != uid))
|
||||||
mode &= 01777;
|
mode &= 01777;
|
||||||
#if POSIXACLS
|
#if POSIXACLS
|
||||||
res = ntfs_set_owner_mode(scx, ni, uid, gid,
|
res = ntfs_set_owner_mode(scx, ni, uid, gid,
|
||||||
mode, pxdesc);
|
mode, pxdesc);
|
||||||
#else
|
#else
|
||||||
res = ntfs_set_owner_mode(scx, ni, uid, gid, mode);
|
res = ntfs_set_owner_mode(scx, ni, uid, gid, mode);
|
||||||
@ -3626,7 +3626,7 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
|
|||||||
/* must copy before merging */
|
/* must copy before merging */
|
||||||
pxsize = sizeof(struct POSIX_SECURITY)
|
pxsize = sizeof(struct POSIX_SECURITY)
|
||||||
+ (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
+ (oldpxdesc->acccnt + oldpxdesc->defcnt)*sizeof(struct POSIX_ACE);
|
||||||
newpxdesc = (struct POSIX_SECURITY*)malloc(pxsize);
|
newpxdesc = (struct POSIX_SECURITY*)ntfs_malloc(pxsize);
|
||||||
if (newpxdesc) {
|
if (newpxdesc) {
|
||||||
memcpy(newpxdesc, oldpxdesc, pxsize);
|
memcpy(newpxdesc, oldpxdesc, pxsize);
|
||||||
if (ntfs_merge_mode_posix(newpxdesc, mode))
|
if (ntfs_merge_mode_posix(newpxdesc, mode))
|
||||||
@ -3680,7 +3680,7 @@ int ntfs_set_ownmod(struct SECURITY_CONTEXT *scx, ntfs_inode *ni,
|
|||||||
if ((int)gid < 0)
|
if ((int)gid < 0)
|
||||||
gid = filegid;
|
gid = filegid;
|
||||||
#if POSIXACLS
|
#if POSIXACLS
|
||||||
res = ntfs_set_owner_mode(scx, ni, uid, gid,
|
res = ntfs_set_owner_mode(scx, ni, uid, gid,
|
||||||
mode, newpxdesc);
|
mode, newpxdesc);
|
||||||
#else
|
#else
|
||||||
res = ntfs_set_owner_mode(scx, ni, uid, gid, mode);
|
res = ntfs_set_owner_mode(scx, ni, uid, gid, mode);
|
||||||
@ -3891,7 +3891,7 @@ le32 ntfs_inherited_id(struct SECURITY_CONTEXT *scx,
|
|||||||
*
|
*
|
||||||
* Returns 0 if OK, -1 (and errno set) if error
|
* Returns 0 if OK, -1 (and errno set) if error
|
||||||
*/
|
*/
|
||||||
|
#include "mem2.h"
|
||||||
static int link_single_group(struct MAPPING *usermapping, struct passwd *user,
|
static int link_single_group(struct MAPPING *usermapping, struct passwd *user,
|
||||||
gid_t gid)
|
gid_t gid)
|
||||||
{
|
{
|
||||||
@ -3911,9 +3911,9 @@ static int link_single_group(struct MAPPING *usermapping, struct passwd *user,
|
|||||||
grmem++;
|
grmem++;
|
||||||
if (*grmem) {
|
if (*grmem) {
|
||||||
if (!grcnt)
|
if (!grcnt)
|
||||||
groups = (gid_t*)malloc(sizeof(gid_t));
|
groups = (gid_t*)ntfs_malloc(sizeof(gid_t));
|
||||||
else
|
else
|
||||||
groups = (gid_t*)realloc(groups,
|
groups = (gid_t*)MEM2_realloc(groups,
|
||||||
(grcnt+1)*sizeof(gid_t));
|
(grcnt+1)*sizeof(gid_t));
|
||||||
if (groups)
|
if (groups)
|
||||||
groups[grcnt++] = gid;
|
groups[grcnt++] = gid;
|
||||||
@ -4323,7 +4323,7 @@ void ntfs_close_secure(struct SECURITY_CONTEXT *scx)
|
|||||||
ntfs_index_ctx_put(vol->secure_xsii);
|
ntfs_index_ctx_put(vol->secure_xsii);
|
||||||
ntfs_index_ctx_put(vol->secure_xsdh);
|
ntfs_index_ctx_put(vol->secure_xsdh);
|
||||||
ntfs_inode_close(vol->secure_ni);
|
ntfs_inode_close(vol->secure_ni);
|
||||||
|
|
||||||
}
|
}
|
||||||
ntfs_free_mapping(scx->mapping);
|
ntfs_free_mapping(scx->mapping);
|
||||||
free_caches(scx);
|
free_caches(scx);
|
||||||
|
@ -434,18 +434,18 @@ void ntfs_file_value_upcase(FILE_NAME_ATTR *file_name_attr,
|
|||||||
so this patch fixes the resulting issues for systems which use
|
so this patch fixes the resulting issues for systems which use
|
||||||
UTF-8 and for others, specifying the locale in fstab brings them
|
UTF-8 and for others, specifying the locale in fstab brings them
|
||||||
the encoding which they want.
|
the encoding which they want.
|
||||||
|
|
||||||
If no locale is defined or there was a problem with setting one
|
If no locale is defined or there was a problem with setting one
|
||||||
up and whenever nl_langinfo(CODESET) returns a sting starting with
|
up and whenever nl_langinfo(CODESET) returns a sting starting with
|
||||||
"ANSI", use an internal UCS-2LE <-> UTF-8 codeset converter to fix
|
"ANSI", use an internal UCS-2LE <-> UTF-8 codeset converter to fix
|
||||||
the bug where NTFS-3G does not show any path names which include
|
the bug where NTFS-3G does not show any path names which include
|
||||||
international characters!!! (and also fails on creating them) as result.
|
international characters!!! (and also fails on creating them) as result.
|
||||||
|
|
||||||
Author: Bernhard Kaindl <bk@suse.de>
|
Author: Bernhard Kaindl <bk@suse.de>
|
||||||
Jean-Pierre Andre made it compliant with RFC3629/RFC2781.
|
Jean-Pierre Andre made it compliant with RFC3629/RFC2781.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the amount of 8-bit elements in UTF-8 needed (without the terminating
|
* Return the amount of 8-bit elements in UTF-8 needed (without the terminating
|
||||||
* null) to store a given UTF-16LE string.
|
* null) to store a given UTF-16LE string.
|
||||||
*
|
*
|
||||||
@ -464,7 +464,7 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l
|
|||||||
if ((c >= 0xdc00) && (c < 0xe000)) {
|
if ((c >= 0xdc00) && (c < 0xe000)) {
|
||||||
surrog = FALSE;
|
surrog = FALSE;
|
||||||
count += 4;
|
count += 4;
|
||||||
} else
|
} else
|
||||||
goto fail;
|
goto fail;
|
||||||
} else
|
} else
|
||||||
if (c < 0x80)
|
if (c < 0x80)
|
||||||
@ -481,14 +481,14 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l
|
|||||||
else if (c >= 0xe000)
|
else if (c >= 0xe000)
|
||||||
#endif
|
#endif
|
||||||
count += 3;
|
count += 3;
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
if (count > outs_len) {
|
if (count > outs_len) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (surrog)
|
if (surrog)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
ret = count;
|
ret = count;
|
||||||
@ -550,7 +550,7 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
|
|||||||
*t++ = 0x80 + ((c >> 6) & 15) + ((halfpair & 3) << 4);
|
*t++ = 0x80 + ((c >> 6) & 15) + ((halfpair & 3) << 4);
|
||||||
*t++ = 0x80 + (c & 63);
|
*t++ = 0x80 + (c & 63);
|
||||||
halfpair = 0;
|
halfpair = 0;
|
||||||
} else
|
} else
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (c < 0x80) {
|
} else if (c < 0x80) {
|
||||||
*t++ = c;
|
*t++ = c;
|
||||||
@ -568,12 +568,12 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
|
|||||||
*t++ = 0xe0 | (c >> 12);
|
*t++ = 0xe0 | (c >> 12);
|
||||||
*t++ = 0x80 | ((c >> 6) & 0x3f);
|
*t++ = 0x80 | ((c >> 6) & 0x3f);
|
||||||
*t++ = 0x80 | (c & 0x3f);
|
*t++ = 0x80 | (c & 0x3f);
|
||||||
} else
|
} else
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*t = '\0';
|
*t = '\0';
|
||||||
|
|
||||||
#if defined(__APPLE__) || defined(__DARWIN__)
|
#if defined(__APPLE__) || defined(__DARWIN__)
|
||||||
#ifdef ENABLE_NFCONV
|
#ifdef ENABLE_NFCONV
|
||||||
if(nfconvert_utf8 && (t - *outs) > 0) {
|
if(nfconvert_utf8 && (t - *outs) > 0) {
|
||||||
@ -602,7 +602,7 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
|
|||||||
}
|
}
|
||||||
#endif /* ENABLE_NFCONV */
|
#endif /* ENABLE_NFCONV */
|
||||||
#endif /* defined(__APPLE__) || defined(__DARWIN__) */
|
#endif /* defined(__APPLE__) || defined(__DARWIN__) */
|
||||||
|
|
||||||
ret = t - *outs;
|
ret = t - *outs;
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
@ -611,8 +611,8 @@ fail:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Return the amount of 16-bit elements in UTF-16LE needed
|
* Return the amount of 16-bit elements in UTF-16LE needed
|
||||||
* (without the terminating null) to store given UTF-8 string.
|
* (without the terminating null) to store given UTF-8 string.
|
||||||
*
|
*
|
||||||
* Return -1 with errno set if it's longer than PATH_MAX or string is invalid.
|
* Return -1 with errno set if it's longer than PATH_MAX or string is invalid.
|
||||||
@ -627,22 +627,22 @@ static int utf8_to_utf16_size(const char *s)
|
|||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
while ((byte = *((const unsigned char *)s++))) {
|
while ((byte = *((const unsigned char *)s++))) {
|
||||||
if (++count >= PATH_MAX)
|
if (++count >= PATH_MAX)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (byte >= 0xc0) {
|
if (byte >= 0xc0) {
|
||||||
if (byte >= 0xF5) {
|
if (byte >= 0xF5) {
|
||||||
errno = EILSEQ;
|
errno = EILSEQ;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (!*s)
|
if (!*s)
|
||||||
break;
|
break;
|
||||||
if (byte >= 0xC0)
|
if (byte >= 0xC0)
|
||||||
s++;
|
s++;
|
||||||
if (!*s)
|
if (!*s)
|
||||||
break;
|
break;
|
||||||
if (byte >= 0xE0)
|
if (byte >= 0xE0)
|
||||||
s++;
|
s++;
|
||||||
if (!*s)
|
if (!*s)
|
||||||
break;
|
break;
|
||||||
if (byte >= 0xF0) {
|
if (byte >= 0xF0) {
|
||||||
s++;
|
s++;
|
||||||
@ -658,11 +658,11 @@ fail:
|
|||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* This converts one UTF-8 sequence to cpu-endian Unicode value
|
* This converts one UTF-8 sequence to cpu-endian Unicode value
|
||||||
* within range U+0 .. U+10ffff and excluding U+D800 .. U+DFFF
|
* within range U+0 .. U+10ffff and excluding U+D800 .. U+DFFF
|
||||||
*
|
*
|
||||||
* Return the number of used utf8 bytes or -1 with errno set
|
* Return the number of used utf8 bytes or -1 with errno set
|
||||||
* if sequence is invalid.
|
* if sequence is invalid.
|
||||||
*/
|
*/
|
||||||
static int utf8_to_unicode(u32 *wc, const char *s)
|
static int utf8_to_unicode(u32 *wc, const char *s)
|
||||||
@ -728,7 +728,7 @@ fail:
|
|||||||
* @ins: input multibyte string buffer
|
* @ins: input multibyte string buffer
|
||||||
* @outs: on return contains the (allocated) output utf16 string
|
* @outs: on return contains the (allocated) output utf16 string
|
||||||
* @outs_len: length of output buffer in utf16 characters
|
* @outs_len: length of output buffer in utf16 characters
|
||||||
*
|
*
|
||||||
* Return -1 with errno set.
|
* Return -1 with errno set.
|
||||||
*/
|
*/
|
||||||
static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
|
static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
|
||||||
@ -789,7 +789,7 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
|
|||||||
}
|
}
|
||||||
t += m;
|
t += m;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = --outpos - *outs;
|
ret = --outpos - *outs;
|
||||||
fail:
|
fail:
|
||||||
#if defined(__APPLE__) || defined(__DARWIN__)
|
#if defined(__APPLE__) || defined(__DARWIN__)
|
||||||
@ -932,7 +932,7 @@ err_out:
|
|||||||
* 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.
|
||||||
*
|
*
|
||||||
* The function allocates the string and the caller is responsible for calling
|
* The function allocates the string and the caller is 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
|
||||||
@ -963,7 +963,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
|
|||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (use_utf8)
|
if (use_utf8)
|
||||||
return ntfs_utf8_to_utf16(ins, outs);
|
return ntfs_utf8_to_utf16(ins, outs);
|
||||||
|
|
||||||
@ -1013,7 +1013,7 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
|
|||||||
if (o >= ucs_len) {
|
if (o >= ucs_len) {
|
||||||
ntfschar *tc;
|
ntfschar *tc;
|
||||||
ucs_len = (ucs_len * sizeof(ntfschar) + 64) & ~63;
|
ucs_len = (ucs_len * sizeof(ntfschar) + 64) & ~63;
|
||||||
tc = realloc(ucs, ucs_len);
|
tc = MEM2_realloc(ucs, ucs_len);
|
||||||
if (!tc)
|
if (!tc)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
ucs = tc;
|
ucs = tc;
|
||||||
@ -1227,12 +1227,12 @@ ntfschar *ntfs_locase_table_build(const ntfschar *uc, u32 uc_cnt)
|
|||||||
* @len: length of output buffer in Unicode characters
|
* @len: length of output buffer in Unicode characters
|
||||||
*
|
*
|
||||||
* Convert the input @s string into the corresponding little endian,
|
* Convert the input @s string into the corresponding little endian,
|
||||||
* 2-byte Unicode string. The length of the converted string is less
|
* 2-byte Unicode string. The length of the converted string is less
|
||||||
* or equal to the maximum length allowed by the NTFS format (255).
|
* or equal to the maximum length allowed by the NTFS format (255).
|
||||||
*
|
*
|
||||||
* If @s is NULL then return AT_UNNAMED.
|
* If @s is NULL then return AT_UNNAMED.
|
||||||
*
|
*
|
||||||
* On success the function returns the Unicode string in an allocated
|
* On success the function returns the Unicode string in an allocated
|
||||||
* buffer and the caller is responsible to free it when it's not needed
|
* buffer and the caller is responsible to free it when it's not needed
|
||||||
* anymore.
|
* anymore.
|
||||||
*
|
*
|
||||||
@ -1371,7 +1371,7 @@ int ntfs_macosx_normalize_filenames(int normalize) {
|
|||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* ENABLE_NFCONV */
|
#endif /* ENABLE_NFCONV */
|
||||||
}
|
}
|
||||||
|
|
||||||
int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
|
int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
|
||||||
int composed) {
|
int composed) {
|
||||||
@ -1383,14 +1383,14 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
|
|||||||
CFIndex requiredBufferLength;
|
CFIndex requiredBufferLength;
|
||||||
char *result = NULL;
|
char *result = NULL;
|
||||||
int resultLength = -1;
|
int resultLength = -1;
|
||||||
|
|
||||||
/* Convert the UTF-8 string to a CFString. */
|
/* Convert the UTF-8 string to a CFString. */
|
||||||
cfSourceString = CFStringCreateWithCString(kCFAllocatorDefault, utf8_string, kCFStringEncodingUTF8);
|
cfSourceString = CFStringCreateWithCString(kCFAllocatorDefault, utf8_string, kCFStringEncodingUTF8);
|
||||||
if(cfSourceString == NULL) {
|
if(cfSourceString == NULL) {
|
||||||
ntfs_log_error("CFStringCreateWithCString failed!\n");
|
ntfs_log_error("CFStringCreateWithCString failed!\n");
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a mutable string from cfSourceString that we are free to modify. */
|
/* Create a mutable string from cfSourceString that we are free to modify. */
|
||||||
cfMutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfSourceString);
|
cfMutableString = CFStringCreateMutableCopy(kCFAllocatorDefault, 0, cfSourceString);
|
||||||
CFRelease(cfSourceString); /* End-of-life. */
|
CFRelease(cfSourceString); /* End-of-life. */
|
||||||
@ -1398,16 +1398,16 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
|
|||||||
ntfs_log_error("CFStringCreateMutableCopy failed!\n");
|
ntfs_log_error("CFStringCreateMutableCopy failed!\n");
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Normalize the mutable string to the desired normalization form. */
|
/* Normalize the mutable string to the desired normalization form. */
|
||||||
CFStringNormalize(cfMutableString, (composed != 0 ? kCFStringNormalizationFormC : kCFStringNormalizationFormD));
|
CFStringNormalize(cfMutableString, (composed != 0 ? kCFStringNormalizationFormC : kCFStringNormalizationFormD));
|
||||||
|
|
||||||
/* Store the resulting string in a '\0'-terminated UTF-8 encoded char* buffer. */
|
/* Store the resulting string in a '\0'-terminated UTF-8 encoded char* buffer. */
|
||||||
rangeToProcess = CFRangeMake(0, CFStringGetLength(cfMutableString));
|
rangeToProcess = CFRangeMake(0, CFStringGetLength(cfMutableString));
|
||||||
if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, NULL, 0, &requiredBufferLength) > 0) {
|
if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, NULL, 0, &requiredBufferLength) > 0) {
|
||||||
resultLength = sizeof(char)*(requiredBufferLength + 1);
|
resultLength = sizeof(char)*(requiredBufferLength + 1);
|
||||||
result = ntfs_calloc(resultLength);
|
result = ntfs_calloc(resultLength);
|
||||||
|
|
||||||
if(result != NULL) {
|
if(result != NULL) {
|
||||||
if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8,
|
if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8,
|
||||||
0, false, (UInt8*)result, resultLength-1, &requiredBufferLength) <= 0) {
|
0, false, (UInt8*)result, resultLength-1, &requiredBufferLength) <= 0) {
|
||||||
@ -1422,9 +1422,9 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
|
|||||||
else
|
else
|
||||||
ntfs_log_error("Could not perform check for required length of UTF-8 conversion of normalized CFMutableString.\n");
|
ntfs_log_error("Could not perform check for required length of UTF-8 conversion of normalized CFMutableString.\n");
|
||||||
|
|
||||||
|
|
||||||
CFRelease(cfMutableString);
|
CFRelease(cfMutableString);
|
||||||
|
|
||||||
if(result != NULL) {
|
if(result != NULL) {
|
||||||
*target = result;
|
*target = result;
|
||||||
return resultLength - 1;
|
return resultLength - 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user