Tidy whitespace: trailing space; <space><tab> at the beginning of lines
Fix warnings about sign differences Fix warnings about unused parameters Tidy a few functions that didn't have { on a new lineedge.strict_endians
parent
cc992ab0f6
commit
949043ab36
|
@ -286,7 +286,7 @@ extern int ntfs_attr_can_be_non_resident(const ntfs_volume *vol,
|
|||
const ATTR_TYPES type);
|
||||
extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
|
||||
const ATTR_TYPES type);
|
||||
|
||||
|
||||
extern int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size);
|
||||
|
||||
extern int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
|
||||
|
@ -304,7 +304,7 @@ extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
|
|||
|
||||
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
|
||||
const u32 newsize);
|
||||
|
||||
|
||||
extern int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni);
|
||||
extern int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra);
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ extern int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx);
|
|||
*
|
||||
* This function cannot fail.
|
||||
*/
|
||||
static __inline__ void ntfs_attrlist_mark_dirty(ntfs_inode *ni) {
|
||||
static __inline__ void ntfs_attrlist_mark_dirty(ntfs_inode *ni)
|
||||
{
|
||||
if (ni->nr_extents == -1)
|
||||
NInoAttrListSetDirty(ni->base_ni);
|
||||
else
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
#define NTFS_COLLATION_ERROR -2
|
||||
|
||||
static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr) {
|
||||
static inline BOOL ntfs_is_collation_rule_supported(COLLATION_RULES cr)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
|
|
|
@ -154,9 +154,9 @@
|
|||
#define le32_to_cpu(x) (u32)__le32_to_cpu((u32)(x))
|
||||
#define le64_to_cpu(x) (u64)__le64_to_cpu((u64)(x))
|
||||
|
||||
#define le16_to_cpup(x) (u16)__le16_to_cpu(*(u16*)(x))
|
||||
#define le32_to_cpup(x) (u32)__le32_to_cpu(*(u32*)(x))
|
||||
#define le64_to_cpup(x) (u64)__le64_to_cpu(*(u64*)(x))
|
||||
#define le16_to_cpup(x) (u16)__le16_to_cpu(*(const u16*)(x))
|
||||
#define le32_to_cpup(x) (u32)__le32_to_cpu(*(const u32*)(x))
|
||||
#define le64_to_cpup(x) (u64)__le64_to_cpu(*(const u64*)(x))
|
||||
|
||||
/* Signed from LE to CPU conversion. */
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Copyright (c) 2002-2003 Jan Kratochvil <project-captive@jankratochvil.net>
|
||||
* Copyright (c) 2000-2004 Anton Altaparmakov
|
||||
*
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Copyright (c) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
|
||||
* Copyright (c) 2000-2004 Anton Altaparmakov
|
||||
*
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
* If @is_in_root is FALSE, @entry is in the index allocation attribute and @ia
|
||||
* and @ia_vcn point to the index allocation block and VCN where it's placed,
|
||||
* respectively. @ir and @actx are NULL in this case. @ia_na is opened
|
||||
* INDEX_ALLOCTAION attribute. @ia_dirty is TRUE if index block was changed and
|
||||
* INDEX_ALLOCTAION attribute. @ia_dirty is TRUE if index block was changed and
|
||||
* FALSE otherwise.
|
||||
*
|
||||
* To obtain a context call ntfs_index_ctx_get().
|
||||
|
|
|
@ -152,7 +152,7 @@ extern int ntfs_inode_close(ntfs_inode *ni);
|
|||
|
||||
extern ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni,
|
||||
const MFT_REF mref);
|
||||
|
||||
|
||||
extern int ntfs_inode_attach_all_extents(ntfs_inode *ni);
|
||||
|
||||
/**
|
||||
|
@ -165,7 +165,8 @@ extern int ntfs_inode_attach_all_extents(ntfs_inode *ni);
|
|||
*
|
||||
* This function cannot fail.
|
||||
*/
|
||||
static __inline__ void ntfs_inode_mark_dirty(ntfs_inode *ni) {
|
||||
static __inline__ void ntfs_inode_mark_dirty(ntfs_inode *ni)
|
||||
{
|
||||
NInoSetDirty(ni);
|
||||
if (ni->nr_extents == -1)
|
||||
NInoSetDirty(ni->base_ni);
|
||||
|
|
|
@ -2219,7 +2219,7 @@ typedef struct {
|
|||
// the key_length is zero, then the vcn immediately
|
||||
// follows the INDEX_ENTRY_HEADER. Regardless of
|
||||
// key_length, the address of the 8-byte boundary
|
||||
// alligned vcn of INDEX_ENTRY{_HEADER} *ie is given by
|
||||
// aligned vcn of INDEX_ENTRY{_HEADER} *ie is given by
|
||||
// (char*)ie + le16_to_cpu(ie*)->length) - sizeof(VCN),
|
||||
// where sizeof(VCN) can be hardcoded as 8 if wanted. */
|
||||
} __attribute__ ((__packed__)) INDEX_ENTRY;
|
||||
|
|
|
@ -428,7 +428,7 @@ int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn)
|
|||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x, vcn 0x%llx.\n",
|
||||
__FUNCTION__, (unsigned long long)na->ni->mft_no,
|
||||
na->type, (long long)vcn);
|
||||
|
||||
|
||||
lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
|
||||
if (lcn >= 0 || lcn == LCN_HOLE || lcn == LCN_ENOENT)
|
||||
return 0;
|
||||
|
@ -490,7 +490,7 @@ int ntfs_attr_map_whole_runlist(ntfs_attr *na)
|
|||
a = NULL;
|
||||
while (1) {
|
||||
runlist_element *rl;
|
||||
|
||||
|
||||
int not_mapped = 0;
|
||||
if (ntfs_rl_vcn_to_lcn(na->rl, next_vcn) == LCN_RL_NOT_MAPPED)
|
||||
not_mapped = 1;
|
||||
|
@ -1219,7 +1219,7 @@ s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, void *b)
|
|||
free(buf);
|
||||
}
|
||||
if (rl->vcn < cur_vcn) {
|
||||
/*
|
||||
/*
|
||||
* Clusters that replaced hole are merged with
|
||||
* previous run, so we need to update offset.
|
||||
*/
|
||||
|
@ -2423,7 +2423,7 @@ int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPES type)
|
|||
int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size)
|
||||
{
|
||||
u32 biu;
|
||||
|
||||
|
||||
Dprintf("%s(): Entering for pos 0x%d, size %u.\n",
|
||||
__FUNCTION__, (int)(pos - (u8*)m), (unsigned) size);
|
||||
|
||||
|
@ -2705,7 +2705,7 @@ int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||
ntfs_attr_put_search_ctx(ctx);
|
||||
errno = err;
|
||||
return -1;
|
||||
|
||||
|
||||
}
|
||||
offset = (u8*)ctx->attr - (u8*)ctx->mrec;
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
|
@ -2867,7 +2867,7 @@ int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx) {
|
|||
* added transparently to caller. So, this function should not be called with
|
||||
* @type == AT_ATTRIBUTE_LIST, if you really need to add attribute list call
|
||||
* ntfs_inode_add_attrlist instead.
|
||||
*
|
||||
*
|
||||
* On success return opened new ntfs attribute. On error return NULL with errno
|
||||
* set to the error code.
|
||||
*/
|
||||
|
@ -2878,7 +2878,7 @@ ntfs_attr *ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||
int err, i, offset;
|
||||
ntfs_inode *attr_ni;
|
||||
ntfs_attr *na;
|
||||
|
||||
|
||||
if (!ni || size < 0 || type == AT_ATTRIBUTE_LIST) {
|
||||
Dprintf("%s(): Invalid arguments passed.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
|
@ -2908,7 +2908,7 @@ ntfs_attr *ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
|
|||
}
|
||||
|
||||
/*
|
||||
* Determine resident or not will be new attribute. We add 8 to size in
|
||||
* Determine resident or not will be new attribute. We add 8 to size in
|
||||
* non resident case for mapping pairs.
|
||||
*/
|
||||
if (ntfs_attr_can_be_resident(ni->vol, type)) {
|
||||
|
@ -3056,7 +3056,7 @@ int ntfs_attr_rm(ntfs_attr *na)
|
|||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
int ret = 0;
|
||||
|
||||
|
||||
if (!na) {
|
||||
Dprintf("%s(): Invalid arguments passed.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
|
@ -3262,7 +3262,7 @@ int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni)
|
|||
}
|
||||
|
||||
/* Make space and move attribute. */
|
||||
if (ntfs_make_room_for_attr(ni->mrec, (u8*) nctx->attr,
|
||||
if (ntfs_make_room_for_attr(ni->mrec, (u8*) nctx->attr,
|
||||
le32_to_cpu(a->length))) {
|
||||
err = errno;
|
||||
Dprintf("%s(): Couldn't make space for attribute.\n",
|
||||
|
@ -3298,7 +3298,7 @@ put_err_out:
|
|||
*
|
||||
* New attribute record holder must have free @extra bytes after moving
|
||||
* attribute record to it.
|
||||
*
|
||||
*
|
||||
* If this function succeed, user should reinit search context if he/she wants
|
||||
* use it anymore.
|
||||
*
|
||||
|
@ -3319,7 +3319,7 @@ int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra)
|
|||
Dprintf("%s(): Entering for attr 0x%x, inode 0x%llx.\n", __FUNCTION__,
|
||||
(unsigned) le32_to_cpu(ctx->attr->type),
|
||||
(long long) ctx->ntfs_ino->mft_no);
|
||||
|
||||
|
||||
if (ctx->ntfs_ino->nr_extents == -1)
|
||||
base_ni = ctx->base_ntfs_ino;
|
||||
else
|
||||
|
@ -3356,7 +3356,7 @@ int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Failed to move attribute to one of the current extents, so allocate
|
||||
* new extent and move attribute to it.
|
||||
*/
|
||||
|
@ -3467,7 +3467,7 @@ static int ntfs_attr_make_non_resident(ntfs_attr *na,
|
|||
NAttrClearSparse(na);
|
||||
NAttrClearEncrypted(na);
|
||||
|
||||
if (rl) {
|
||||
if (rl) {
|
||||
/* Now copy the attribute value to the allocated cluster(s). */
|
||||
bw = ntfs_attr_pwrite(na, 0, le32_to_cpu(a->value_length),
|
||||
(u8*)a + le16_to_cpu(a->value_offset));
|
||||
|
@ -3736,14 +3736,14 @@ static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
|
|||
err = ENOSPC;
|
||||
goto put_err_out;
|
||||
}
|
||||
|
||||
|
||||
/* Add attribute list if not present. */
|
||||
if (na->ni->nr_extents == -1)
|
||||
ni = na->ni->base_ni;
|
||||
else
|
||||
ni = na->ni;
|
||||
if (!NInoAttrList(ni)) {
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
if (ntfs_inode_add_attrlist(ni))
|
||||
return -1;
|
||||
return ntfs_resident_attr_resize(na, newsize);
|
||||
|
@ -4004,8 +4004,8 @@ retry:
|
|||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, attr 0x%x.\n", __FUNCTION__,
|
||||
(unsigned long long)na->ni->mft_no, na->type);
|
||||
|
||||
if (na->ni->nr_extents == -1)
|
||||
|
||||
if (na->ni->nr_extents == -1)
|
||||
base_ni = na->ni->base_ni;
|
||||
else
|
||||
base_ni = na->ni;
|
||||
|
@ -4058,7 +4058,7 @@ retry:
|
|||
/* If we in the first extent, then set/clean sparse bit. */
|
||||
if (!a->lowest_vcn) {
|
||||
int sparse;
|
||||
|
||||
|
||||
sparse = ntfs_rl_sparse(na->rl);
|
||||
if (sparse == -1) {
|
||||
Dprintf("%s(): Bad runlist.\n", __FUNCTION__);
|
||||
|
@ -4163,7 +4163,7 @@ retry:
|
|||
* Determine maximum possible length of mapping pairs,
|
||||
* if we shall *not* expand space for mapping pairs.
|
||||
*/
|
||||
cur_max_mp_size = le32_to_cpu(a->length) -
|
||||
cur_max_mp_size = le32_to_cpu(a->length) -
|
||||
le16_to_cpu(a->mapping_pairs_offset);
|
||||
/*
|
||||
* Determine maximum possible length of mapping pairs in the
|
||||
|
@ -4270,7 +4270,7 @@ retry:
|
|||
Dprintf("%s(): Attribute lookup failed.\n", __FUNCTION__);
|
||||
goto put_err_out;
|
||||
}
|
||||
|
||||
|
||||
/* Deallocate not used attribute extents and return with success. */
|
||||
if (finished_build) {
|
||||
ntfs_attr_reinit_search_ctx(ctx);
|
||||
|
@ -4446,7 +4446,7 @@ static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize)
|
|||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Truncate the runlist itself. */
|
||||
if (ntfs_rl_truncate(&na->rl, first_free_vcn)) {
|
||||
err = errno;
|
||||
|
@ -4461,7 +4461,7 @@ static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize)
|
|||
errno = err;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Write mapping pairs for new runlist. */
|
||||
if (ntfs_attr_update_mapping_pairs(na)) {
|
||||
err = errno;
|
||||
|
@ -4472,7 +4472,7 @@ static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Get the first attribute record. */
|
||||
ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
|
||||
if (!ctx) {
|
||||
|
@ -4497,7 +4497,7 @@ static int ntfs_non_resident_attr_shrink(ntfs_attr *na, const s64 newsize)
|
|||
goto put_err_out;
|
||||
}
|
||||
a = ctx->attr;
|
||||
|
||||
|
||||
/* Update allocated size only if it is changed. */
|
||||
if ((na->allocated_size >> vol->cluster_size_bits) != first_free_vcn) {
|
||||
na->allocated_size = first_free_vcn << vol->cluster_size_bits;
|
||||
|
@ -4822,7 +4822,7 @@ int ntfs_attr_truncate(ntfs_attr *na, const s64 newsize)
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (na->data_size == newsize)
|
||||
return 0;
|
||||
/*
|
||||
|
|
|
@ -65,7 +65,7 @@ int ntfs_attrlist_need(ntfs_inode *ni)
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (!ni->attr_list) {
|
||||
Dprintf("%s(): Corrput in-memory struct.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
|
@ -255,7 +255,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
"%lld.\n", __FUNCTION__, (long long) ctx->ntfs_ino->mft_no,
|
||||
(unsigned) le32_to_cpu(ctx->al_entry->type),
|
||||
(long long) le64_to_cpu(ctx->al_entry->lowest_vcn));
|
||||
|
||||
|
||||
if (!NInoAttrList(base_ni)) {
|
||||
Dprintf("%s(): Attribute list isn't present.\n", __FUNCTION__);
|
||||
errno = ENOENT;
|
||||
|
@ -270,7 +270,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
|
|||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Reisze $ATTRIBUTE_LIST to new length. */
|
||||
na = ntfs_attr_open(base_ni, AT_ATTRIBUTE_LIST, NULL, 0);
|
||||
if (!na) {
|
||||
|
|
|
@ -73,7 +73,7 @@ static int ntfs_collate_file_name(ntfs_volume *vol,
|
|||
const void *data2, const int data2_len __attribute__((unused))){
|
||||
int rc;
|
||||
const FILE_NAME_ATTR *fn1, *fn2;
|
||||
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
fn1 = (const FILE_NAME_ATTR *)data1;
|
||||
fn2 = (const FILE_NAME_ATTR *)data2;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Copyright (c) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
|
||||
* Copyright (c) 2003 Anton Altaparmakov
|
||||
*
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* Copyright (c) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
|
||||
* Copyright (c) 2003 Anton Altaparmakov
|
||||
*
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or
|
||||
|
|
|
@ -269,7 +269,7 @@ done:
|
|||
descend_into_child_node:
|
||||
ntfs_debug("Descend into node with VCN %lld.", vcn);
|
||||
/* Read index allocation block. */
|
||||
if (ntfs_attr_mst_pread(na, vcn << vol->cluster_size_bits, 1,
|
||||
if (ntfs_attr_mst_pread(na, vcn << vol->cluster_size_bits, 1,
|
||||
ictx->block_size, ia) != 1) {
|
||||
ntfs_error(, "Failed to read index allocation.");
|
||||
goto err_out;
|
||||
|
|
|
@ -389,7 +389,7 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
|
|||
/* Inode haven't got attribute list, thus nothing to attach. */
|
||||
if (!NInoAttrList(ni))
|
||||
return 0;
|
||||
|
||||
|
||||
if (!ni->attr_list) {
|
||||
Dprintf("%s(): Corrput in-memory struct.\n", __FUNCTION__);
|
||||
errno = EINVAL;
|
||||
|
@ -681,7 +681,7 @@ int ntfs_inode_sync(ntfs_inode *ni)
|
|||
|
||||
for (i = 0; i < ni->nr_extents; ++i) {
|
||||
ntfs_inode *eni;
|
||||
|
||||
|
||||
eni = ni->extent_nis[i];
|
||||
if (NInoTestAndClearDirty(eni)) {
|
||||
if (ntfs_mft_record_write(eni->vol, eni->mft_no,
|
||||
|
@ -740,7 +740,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
al_allocated = 0x40;
|
||||
al_len = 0;
|
||||
al = malloc(al_allocated);
|
||||
|
@ -750,7 +750,7 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
|
|||
errno = ENOMEM;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Form attribute list. */
|
||||
ctx = ntfs_attr_get_search_ctx(ni, NULL);
|
||||
if (!ctx) {
|
||||
|
@ -937,10 +937,10 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
|
|||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx, size %d.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no, size);
|
||||
|
||||
|
||||
freed = (le32_to_cpu(ni->mrec->bytes_allocated) -
|
||||
le32_to_cpu(ni->mrec->bytes_in_use));
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
|
|||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Return empty runlist if @count == 0 */
|
||||
if (!count) {
|
||||
rl = malloc(0x1000);
|
||||
|
|
|
@ -0,0 +1,716 @@
|
|||
/*
|
||||
* logfile.c - NTFS journal handling. Part of the Linux-NTFS project.
|
||||
*
|
||||
* Copyright (c) 2002-2004 Anton Altaparmakov
|
||||
* Copyright (c) 2005 Yura Pakhuchiy
|
||||
*
|
||||
* This program/include file is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program/include file is distributed in the hope that it will be
|
||||
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program (in the main directory of the Linux-NTFS
|
||||
* distribution in the file COPYING); if not, write to the Free Software
|
||||
* Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "attrib.h"
|
||||
#include "debug.h"
|
||||
#include "logfile.h"
|
||||
#include "volume.h"
|
||||
#include "mst.h"
|
||||
|
||||
/**
|
||||
* ntfs_check_restart_page_header - check the page header for consistency
|
||||
* @rp: restart page header to check
|
||||
* @pos: position in logfile at which the restart page header resides
|
||||
*
|
||||
* Check the restart page header @rp for consistency and return TRUE if it is
|
||||
* consistent and FALSE otherwise.
|
||||
*
|
||||
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
|
||||
* require the full restart page.
|
||||
*/
|
||||
static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
|
||||
{
|
||||
u32 logfile_system_page_size, logfile_log_page_size;
|
||||
u16 usa_count, usa_ofs, usa_end, ra_ofs;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
/*
|
||||
* If the system or log page sizes are smaller than the ntfs block size
|
||||
* or either is not a power of 2 we cannot handle this log file.
|
||||
*/
|
||||
logfile_system_page_size = le32_to_cpu(rp->system_page_size);
|
||||
logfile_log_page_size = le32_to_cpu(rp->log_page_size);
|
||||
if (logfile_system_page_size < NTFS_BLOCK_SIZE ||
|
||||
logfile_log_page_size < NTFS_BLOCK_SIZE ||
|
||||
logfile_system_page_size &
|
||||
(logfile_system_page_size - 1) ||
|
||||
logfile_log_page_size & (logfile_log_page_size - 1)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile uses unsupported page size.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* We must be either at !pos (1st restart page) or at pos = system page
|
||||
* size (2nd restart page).
|
||||
*/
|
||||
if (pos && pos != logfile_system_page_size) {
|
||||
ntfs_error(vi->i_sb, "Found restart area in incorrect "
|
||||
"position in $LogFile.");
|
||||
return FALSE;
|
||||
}
|
||||
/* We only know how to handle version 1.1. */
|
||||
if (sle16_to_cpu(rp->major_ver) != 1 ||
|
||||
sle16_to_cpu(rp->minor_ver) != 1) {
|
||||
ntfs_error(vi->i_sb, "$LogFile version %i.%i is not "
|
||||
"supported. (This driver supports version "
|
||||
"1.1 only.)", (int)sle16_to_cpu(rp->major_ver),
|
||||
(int)sle16_to_cpu(rp->minor_ver));
|
||||
return FALSE;
|
||||
}
|
||||
/* Verify the size of the update sequence array. */
|
||||
usa_count = 1 + (logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS);
|
||||
if (usa_count != le16_to_cpu(rp->usa_count)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
"inconsistent update sequence array count.");
|
||||
return FALSE;
|
||||
}
|
||||
/* Verify the position of the update sequence array. */
|
||||
usa_ofs = le16_to_cpu(rp->usa_ofs);
|
||||
usa_end = usa_ofs + usa_count * sizeof(u16);
|
||||
if (usa_ofs < sizeof(RESTART_PAGE_HEADER) ||
|
||||
usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
"inconsistent update sequence array offset.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Verify the position of the restart area. It must be:
|
||||
* - aligned to 8-byte boundary,
|
||||
* - after the update sequence array, and
|
||||
* - within the system page size.
|
||||
*/
|
||||
ra_ofs = le16_to_cpu(rp->restart_area_offset);
|
||||
if (ra_ofs & 7 || ra_ofs < usa_end ||
|
||||
ra_ofs > logfile_system_page_size) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page specifies "
|
||||
"inconsistent restart area offset.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Only restart pages modified by chkdsk are allowed to have chkdsk_lsn
|
||||
* set.
|
||||
*/
|
||||
if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart page is not modified "
|
||||
"chkdsk but a chkdsk LSN is specified.");
|
||||
return FALSE;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_check_restart_area - check the restart area for consistency
|
||||
* @rp: restart page whose restart area to check
|
||||
*
|
||||
* Check the restart area of the restart page @rp for consistency and return
|
||||
* TRUE if it is consistent and FALSE otherwise.
|
||||
*
|
||||
* This function assumes that the restart page header has already been
|
||||
* consistency checked.
|
||||
*
|
||||
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
|
||||
* require the full restart page.
|
||||
*/
|
||||
static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
|
||||
{
|
||||
u64 file_size;
|
||||
RESTART_AREA *ra;
|
||||
u16 ra_ofs, ra_len, ca_ofs;
|
||||
u8 fs_bits;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ra_ofs = le16_to_cpu(rp->restart_area_offset);
|
||||
ra = (RESTART_AREA*)((u8*)rp + ra_ofs);
|
||||
/*
|
||||
* Everything before ra->file_size must be before the first word
|
||||
* protected by an update sequence number. This ensures that it is
|
||||
* safe to access ra->client_array_offset.
|
||||
*/
|
||||
if (ra_ofs + offsetof(RESTART_AREA, file_size) >
|
||||
NTFS_BLOCK_SIZE - sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"inconsistent file offset.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Now that we can access ra->client_array_offset, make sure everything
|
||||
* up to the log client array is before the first word protected by an
|
||||
* update sequence number. This ensures we can access all of the
|
||||
* restart area elements safely. Also, the client array offset must be
|
||||
* aligned to an 8-byte boundary.
|
||||
*/
|
||||
ca_ofs = le16_to_cpu(ra->client_array_offset);
|
||||
if (((ca_ofs + 7) & ~7) != ca_ofs ||
|
||||
ra_ofs + ca_ofs > NTFS_BLOCK_SIZE - sizeof(u16)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"inconsistent client array offset.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* The restart area must end within the system page size both when
|
||||
* calculated manually and as specified by ra->restart_area_length.
|
||||
* Also, the calculated length must not exceed the specified length.
|
||||
*/
|
||||
ra_len = ca_ofs + le16_to_cpu(ra->log_clients) *
|
||||
sizeof(LOG_CLIENT_RECORD);
|
||||
if (ra_ofs + ra_len > le32_to_cpu(rp->system_page_size) ||
|
||||
ra_ofs + le16_to_cpu(ra->restart_area_length) >
|
||||
le32_to_cpu(rp->system_page_size) ||
|
||||
ra_len > le16_to_cpu(ra->restart_area_length)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area is out of bounds "
|
||||
"of the system page size specified by the "
|
||||
"restart page header and/or the specified "
|
||||
"restart area length is inconsistent.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* The ra->client_free_list and ra->client_in_use_list must be either
|
||||
* LOGFILE_NO_CLIENT or less than ra->log_clients or they are
|
||||
* overflowing the client array.
|
||||
*/
|
||||
if ((ra->client_free_list != LOGFILE_NO_CLIENT &&
|
||||
le16_to_cpu(ra->client_free_list) >=
|
||||
le16_to_cpu(ra->log_clients)) ||
|
||||
(ra->client_in_use_list != LOGFILE_NO_CLIENT &&
|
||||
le16_to_cpu(ra->client_in_use_list) >=
|
||||
le16_to_cpu(ra->log_clients))) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"overflowing client free and/or in use lists.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Check ra->seq_number_bits against ra->file_size for consistency.
|
||||
* We cannot just use ffs() because the file size is not a power of 2.
|
||||
*/
|
||||
file_size = (u64)sle64_to_cpu(ra->file_size);
|
||||
fs_bits = 0;
|
||||
while (file_size) {
|
||||
file_size >>= 1;
|
||||
fs_bits++;
|
||||
}
|
||||
if (le32_to_cpu(ra->seq_number_bits) != (u32)(67 - fs_bits)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"inconsistent sequence number bits.");
|
||||
return FALSE;
|
||||
}
|
||||
/* The log record header length must be a multiple of 8. */
|
||||
if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) !=
|
||||
le16_to_cpu(ra->log_record_header_length)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"inconsistent log record header length.");
|
||||
return FALSE;
|
||||
}
|
||||
/* Dito for the log page data offset. */
|
||||
if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) !=
|
||||
le16_to_cpu(ra->log_page_data_offset)) {
|
||||
ntfs_error(vi->i_sb, "$LogFile restart area specifies "
|
||||
"inconsistent log page data offset.");
|
||||
return FALSE;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_check_log_client_array - check the log client array for consistency
|
||||
* @rp: restart page whose log client array to check
|
||||
*
|
||||
* Check the log client array of the restart page @rp for consistency and
|
||||
* return TRUE if it is consistent and FALSE otherwise.
|
||||
*
|
||||
* This function assumes that the restart page header and the restart area have
|
||||
* already been consistency checked.
|
||||
*
|
||||
* Unlike ntfs_check_restart_page_header() and ntfs_check_restart_area(), this
|
||||
* function needs @rp->system_page_size bytes in @rp, i.e. it requires the full
|
||||
* restart page and the page must be multi sector transfer deprotected.
|
||||
*/
|
||||
static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
|
||||
{
|
||||
RESTART_AREA *ra;
|
||||
LOG_CLIENT_RECORD *ca, *cr;
|
||||
u16 nr_clients, idx;
|
||||
BOOL in_free_list, idx_is_first;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
|
||||
ca = (LOG_CLIENT_RECORD*)((u8*)ra +
|
||||
le16_to_cpu(ra->client_array_offset));
|
||||
/*
|
||||
* Check the ra->client_free_list first and then check the
|
||||
* ra->client_in_use_list. Check each of the log client records in
|
||||
* each of the lists and check that the array does not overflow the
|
||||
* ra->log_clients value. Also keep track of the number of records
|
||||
* visited as there cannot be more than ra->log_clients records and
|
||||
* that way we detect eventual loops in within a list.
|
||||
*/
|
||||
nr_clients = le16_to_cpu(ra->log_clients);
|
||||
idx = le16_to_cpu(ra->client_free_list);
|
||||
in_free_list = TRUE;
|
||||
check_list:
|
||||
for (idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--,
|
||||
idx = le16_to_cpu(cr->next_client)) {
|
||||
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
|
||||
goto err_out;
|
||||
/* Set @cr to the current log client record. */
|
||||
cr = ca + idx;
|
||||
/* The first log client record must not have a prev_client. */
|
||||
if (idx_is_first) {
|
||||
if (cr->prev_client != LOGFILE_NO_CLIENT)
|
||||
goto err_out;
|
||||
idx_is_first = FALSE;
|
||||
}
|
||||
}
|
||||
/* Switch to and check the in use list if we just did the free list. */
|
||||
if (in_free_list) {
|
||||
in_free_list = FALSE;
|
||||
idx = le16_to_cpu(ra->client_in_use_list);
|
||||
goto check_list;
|
||||
}
|
||||
ntfs_debug("Done.");
|
||||
return TRUE;
|
||||
err_out:
|
||||
ntfs_error(vi->i_sb, "$LogFile log client array is corrupt.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_check_and_load_restart_page - check the restart page for consistency
|
||||
* @log_na: opened ntfs attribute for journal $LogFile
|
||||
* @rp: restart page to check
|
||||
* @pos: position in @log_na at which the restart page resides
|
||||
* @wrp: copy of the multi sector transfer deprotected restart page
|
||||
*
|
||||
* Check the restart page @rp for consistency and return TRUE if it is
|
||||
* consistent and FALSE otherwise.
|
||||
*
|
||||
* This function only needs NTFS_BLOCK_SIZE bytes in @rp, i.e. it does not
|
||||
* require the full restart page.
|
||||
*
|
||||
* If @wrp is not NULL, on success, *@wrp will point to a buffer containing a
|
||||
* copy of the complete multi sector transfer deprotected page. On failure,
|
||||
* *@wrp is undefined.
|
||||
*/
|
||||
static BOOL ntfs_check_and_load_restart_page(ntfs_attr *log_na,
|
||||
RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp)
|
||||
{
|
||||
RESTART_AREA *ra;
|
||||
RESTART_PAGE_HEADER *trp;
|
||||
BOOL ret;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
/* Check the restart page header for consistency. */
|
||||
if (!ntfs_check_restart_page_header(rp, pos)) {
|
||||
/* Error output already done inside the function. */
|
||||
return FALSE;
|
||||
}
|
||||
/* Check the restart area for consistency. */
|
||||
if (!ntfs_check_restart_area(rp)) {
|
||||
/* Error output already done inside the function. */
|
||||
return FALSE;
|
||||
}
|
||||
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
|
||||
/*
|
||||
* Allocate a buffer to store the whole restart page so we can multi
|
||||
* sector transfer deprotect it.
|
||||
*/
|
||||
trp = malloc(le32_to_cpu(rp->system_page_size));
|
||||
if (!trp) {
|
||||
ntfs_error(vi->i_sb, "Failed to allocate memory for $LogFile "
|
||||
"restart page buffer.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Read the whole of the restart page into the buffer. If it fits
|
||||
* completely inside @rp, just copy it from there. Otherwise read it
|
||||
* from disk.
|
||||
*/
|
||||
if (le32_to_cpu(rp->system_page_size) <= NTFS_BLOCK_SIZE)
|
||||
memcpy(trp, rp, le32_to_cpu(rp->system_page_size));
|
||||
else
|
||||
if (ntfs_attr_pread(log_na, pos, le32_to_cpu(
|
||||
rp->system_page_size), trp) !=
|
||||
le32_to_cpu(rp->system_page_size)) {
|
||||
ntfs_error(, "Failed to read whole restart page into "
|
||||
"the buffer.");
|
||||
goto err_out;
|
||||
}
|
||||
/* Perform the multi sector transfer deprotection on the buffer. */
|
||||
if (ntfs_mst_post_read_fixup((NTFS_RECORD*)trp,
|
||||
le32_to_cpu(rp->system_page_size))) {
|
||||
ntfs_error(vi->i_sb, "Multi sector transfer error detected in "
|
||||
"$LogFile restart page.");
|
||||
goto err_out;
|
||||
}
|
||||
/* Check the log client records for consistency. */
|
||||
ret = ntfs_check_log_client_array(trp);
|
||||
if (ret && wrp)
|
||||
*wrp = trp;
|
||||
else
|
||||
free(trp);
|
||||
ntfs_debug("Done.");
|
||||
return ret;
|
||||
err_out:
|
||||
free(trp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_ckeck_logfile - check in the journal if the volume is consistent
|
||||
* @log_na: ntfs attribute of loaded journal $LogFile to check
|
||||
*
|
||||
* Check the $LogFile journal for consistency and return TRUE if it is
|
||||
* consistent and FALSE if not.
|
||||
*
|
||||
* At present we only check the two restart pages and ignore the log record
|
||||
* pages.
|
||||
*
|
||||
* Note that the MstProtected flag is not set on the $LogFile inode and hence
|
||||
* when reading pages they are not deprotected. This is because we do not know
|
||||
* if the $LogFile was created on a system with a different page size to ours
|
||||
* yet and mst deprotection would fail if our page size is smaller.
|
||||
*/
|
||||
BOOL ntfs_check_logfile(ntfs_attr *log_na)
|
||||
{
|
||||
s64 size, pos, rstr1_pos, rstr2_pos;
|
||||
ntfs_volume *vol = log_na->ni->vol;
|
||||
u8 *buf = NULL;
|
||||
RESTART_PAGE_HEADER *rstr1_ph = NULL;
|
||||
RESTART_PAGE_HEADER *rstr2_ph = NULL;
|
||||
int log_page_size, log_page_mask, ofs;
|
||||
BOOL logfile_is_empty = TRUE;
|
||||
BOOL rstr1_found = FALSE;
|
||||
BOOL rstr2_found = FALSE;
|
||||
u8 log_page_bits;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
/* An empty $LogFile must have been clean before it got emptied. */
|
||||
if (NVolLogFileEmpty(vol))
|
||||
goto is_empty;
|
||||
size = log_na->data_size;
|
||||
/* Make sure the file doesn't exceed the maximum allowed size. */
|
||||
if (size > (s64)MaxLogFileSize)
|
||||
size = MaxLogFileSize;
|
||||
log_page_size = DefaultLogPageSize;
|
||||
log_page_mask = log_page_size - 1;
|
||||
/*
|
||||
* Use generic_ffs() instead of ffs() to enable the compiler to
|
||||
* optimize log_page_size and log_page_bits into constants.
|
||||
*/
|
||||
log_page_bits = ffs(log_page_size) - 1;
|
||||
size &= ~(log_page_size - 1);
|
||||
|
||||
/*
|
||||
* Ensure the log file is big enough to store at least the two restart
|
||||
* pages and the minimum number of log record pages.
|
||||
*/
|
||||
if (size < log_page_size * 2 || (size - log_page_size * 2) >>
|
||||
log_page_bits < MinLogRecordPages) {
|
||||
ntfs_error(vol->sb, "$LogFile is too small.");
|
||||
return FALSE;
|
||||
}
|
||||
/* Allocate memory for restart page. */
|
||||
buf = malloc(NTFS_BLOCK_SIZE);
|
||||
if (!buf) {
|
||||
ntfs_error(, "Not enough memory.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Read through the file looking for a restart page. Since the restart
|
||||
* page header is at the beginning of a page we only need to search at
|
||||
* what could be the beginning of a page (for each page size) rather
|
||||
* than scanning the whole file byte by byte. If all potential places
|
||||
* contain empty and uninitialzed records, the log file can be assumed
|
||||
* to be empty.
|
||||
*/
|
||||
for (pos = 0; pos < size; pos <<= 1) {
|
||||
/*
|
||||
* Read first NTFS_BLOCK_SIZE bytes of potential restart page.
|
||||
*/
|
||||
if (ntfs_attr_pread(log_na, pos, NTFS_BLOCK_SIZE, buf) !=
|
||||
NTFS_BLOCK_SIZE) {
|
||||
ntfs_error(, "Failed to read first NTFS_BLOCK_SIZE "
|
||||
"bytes of potential restart page.");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* A non-empty block means the logfile is not empty while an
|
||||
* empty block after a non-empty block has been encountered
|
||||
* means we are done.
|
||||
*/
|
||||
if (!ntfs_is_empty_recordp((le32*)buf))
|
||||
logfile_is_empty = FALSE;
|
||||
else if (!logfile_is_empty)
|
||||
break;
|
||||
/*
|
||||
* A log record page means there cannot be a restart page after
|
||||
* this so no need to continue searching.
|
||||
*/
|
||||
if (ntfs_is_rcrd_recordp((le32*)buf))
|
||||
break;
|
||||
/*
|
||||
* A modified by chkdsk restart page means we cannot handle
|
||||
* this log file.
|
||||
*/
|
||||
if (ntfs_is_chkd_recordp((le32*)buf)) {
|
||||
ntfs_error(vol->sb, "$LogFile has been modified by "
|
||||
"chkdsk. Mount this volume in "
|
||||
"Windows.");
|
||||
goto err_out;
|
||||
}
|
||||
/* If not a restart page, continue. */
|
||||
if (!ntfs_is_rstr_recordp((le32*)buf)) {
|
||||
/* Skip to the minimum page size for the next one. */
|
||||
if (!pos)
|
||||
pos = NTFS_BLOCK_SIZE >> 1;
|
||||
continue;
|
||||
}
|
||||
/* We now know we have a restart page. */
|
||||
if (!pos) {
|
||||
rstr1_found = TRUE;
|
||||
rstr1_pos = pos;
|
||||
} else {
|
||||
if (rstr2_found) {
|
||||
ntfs_error(vol->sb, "Found more than two "
|
||||
"restart pages in $LogFile.");
|
||||
goto err_out;
|
||||
}
|
||||
rstr2_found = TRUE;
|
||||
rstr2_pos = pos;
|
||||
}
|
||||
/*
|
||||
* Check the restart page for consistency and get a copy of the
|
||||
* complete multi sector transfer deprotected restart page.
|
||||
*/
|
||||
if (!ntfs_check_and_load_restart_page(log_na,
|
||||
(RESTART_PAGE_HEADER*)buf, pos,
|
||||
!pos ? &rstr1_ph : &rstr2_ph)) {
|
||||
/* Error output already done inside the function. */
|
||||
goto err_out;
|
||||
}
|
||||
/*
|
||||
* We have a valid restart page. The next one must be after
|
||||
* a whole system page size as specified by the valid restart
|
||||
* page.
|
||||
*/
|
||||
if (!pos)
|
||||
pos = le32_to_cpu(rstr1_ph->system_page_size) >> 1;
|
||||
}
|
||||
if (buf) {
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
if (logfile_is_empty) {
|
||||
NVolSetLogFileEmpty(vol);
|
||||
is_empty:
|
||||
ntfs_debug("Done. ($LogFile is empty.)");
|
||||
return TRUE;
|
||||
}
|
||||
if (!rstr1_found || !rstr2_found) {
|
||||
ntfs_error(vol->sb, "Did not find two restart pages in "
|
||||
"$LogFile.");
|
||||
goto err_out;
|
||||
}
|
||||
/*
|
||||
* The two restart areas must be identical except for the update
|
||||
* sequence number.
|
||||
*/
|
||||
ofs = le16_to_cpu(rstr1_ph->usa_ofs);
|
||||
if (memcmp(rstr1_ph, rstr2_ph, ofs) || (ofs += sizeof(u16),
|
||||
memcmp((u8*)rstr1_ph + ofs, (u8*)rstr2_ph + ofs,
|
||||
le32_to_cpu(rstr1_ph->system_page_size) - ofs))) {
|
||||
ntfs_error(vol->sb, "The two restart pages in $LogFile do not "
|
||||
"match.");
|
||||
goto err_out;
|
||||
}
|
||||
free(rstr1_ph);
|
||||
free(rstr2_ph);
|
||||
/* All consistency checks passed. */
|
||||
ntfs_debug("Done.");
|
||||
return TRUE;
|
||||
err_out:
|
||||
if (buf)
|
||||
free(buf);
|
||||
if (rstr1_ph)
|
||||
free(rstr1_ph);
|
||||
if (rstr2_ph)
|
||||
free(rstr2_ph);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_is_logfile_clean - check in the journal if the volume is clean
|
||||
* @log_na: ntfs attribute of loaded journal $LogFile to check
|
||||
*
|
||||
* Analyze the $LogFile journal and return TRUE if it indicates the volume was
|
||||
* shutdown cleanly and FALSE if not.
|
||||
*
|
||||
* At present we only look at the two restart pages and ignore the log record
|
||||
* pages. This is a little bit crude in that there will be a very small number
|
||||
* of cases where we think that a volume is dirty when in fact it is clean.
|
||||
* This should only affect volumes that have not been shutdown cleanly but did
|
||||
* not have any pending, non-check-pointed i/o, i.e. they were completely idle
|
||||
* at least for the five seconds preceeding the unclean shutdown.
|
||||
*
|
||||
* This function assumes that the $LogFile journal has already been consistency
|
||||
* checked by a call to ntfs_check_logfile() and in particular if the $LogFile
|
||||
* is empty this function requires that NVolLogFileEmpty() is true otherwise an
|
||||
* empty volume will be reported as dirty.
|
||||
*/
|
||||
BOOL ntfs_is_logfile_clean(ntfs_attr *log_na)
|
||||
{
|
||||
RESTART_PAGE_HEADER *rp;
|
||||
RESTART_AREA *ra;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
/* An empty $LogFile must have been clean before it got emptied. */
|
||||
if (NVolLogFileEmpty(log_na->ni->vol)) {
|
||||
ntfs_debug("Done. ($LogFile is empty.)");
|
||||
return TRUE;
|
||||
}
|
||||
/* Allocate memory. */
|
||||
rp = malloc(NTFS_BLOCK_SIZE);
|
||||
if (!rp) {
|
||||
ntfs_error(, "Not enough memory.");
|
||||
return FALSE;
|
||||
}
|
||||
/*
|
||||
* Read the first restart page. It will be possibly incomplete and
|
||||
* will not be multi sector transfer deprotected but we only need the
|
||||
* first NTFS_BLOCK_SIZE bytes so it does not matter.
|
||||
*/
|
||||
if (ntfs_attr_pread(log_na, 0, NTFS_BLOCK_SIZE, rp) !=
|
||||
NTFS_BLOCK_SIZE) {
|
||||
ntfs_error(, "Failed to read first restart page.");
|
||||
goto err_out;
|
||||
}
|
||||
if (!ntfs_is_rstr_record(rp->magic)) {
|
||||
ntfs_error(vol->sb, "No restart page found at offset zero in "
|
||||
"$LogFile. This is probably a bug in that "
|
||||
"the $LogFile should have been consistency "
|
||||
"checked before calling this function.");
|
||||
goto err_out;
|
||||
}
|
||||
ra = (RESTART_AREA*)((u8*)rp + le16_to_cpu(rp->restart_area_offset));
|
||||
/*
|
||||
* If the $LogFile has active clients, i.e. it is open, and we do not
|
||||
* have the RESTART_VOLUME_IS_CLEAN bit set in the restart area flags,
|
||||
* we assume there was an unclean shutdown.
|
||||
*/
|
||||
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
|
||||
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
|
||||
ntfs_debug("Done. $LogFile indicates a dirty shutdown.");
|
||||
goto err_out;
|
||||
}
|
||||
free(rp);
|
||||
/* $LogFile indicates a clean shutdown. */
|
||||
ntfs_debug("Done. $LogFile indicates a clean shutdown.");
|
||||
return TRUE;
|
||||
err_out:
|
||||
free(rp);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* ntfs_empty_logfile - empty the contents of the $LogFile journal
|
||||
* @na: ntfs attribute of journal $LogFile to empty
|
||||
*
|
||||
* Empty the contents of the $LogFile journal @na and return 0 on success and
|
||||
* -1 on error.
|
||||
*
|
||||
* This function assumes that the $LogFile journal has already been consistency
|
||||
* checked by a call to ntfs_check_logfile() and that ntfs_is_logfile_clean()
|
||||
* has been used to ensure that the $LogFile is clean.
|
||||
*/
|
||||
int ntfs_empty_logfile(ntfs_attr *na)
|
||||
{
|
||||
s64 len, pos, count;
|
||||
char buf[NTFS_BUF_SIZE];
|
||||
int err;
|
||||
|
||||
ntfs_debug("Entering.");
|
||||
if (NVolLogFileEmpty(na->ni->vol))
|
||||
goto done;
|
||||
|
||||
/* The $DATA attribute of the $LogFile has to be non-resident. */
|
||||
if (!NAttrNonResident(na)) {
|
||||
err = EIO;
|
||||
Dprintf("$LogFile $DATA attribute is resident!?!\n");
|
||||
goto io_error_exit;
|
||||
}
|
||||
|
||||
/* Get length of $LogFile contents. */
|
||||
len = na->data_size;
|
||||
if (!len) {
|
||||
Dprintf("$LogFile has zero length, no disk write needed.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read $LogFile until its end. We do this as a check for correct
|
||||
length thus making sure we are decompressing the mapping pairs
|
||||
array correctly and hence writing below is safe as well. */
|
||||
pos = 0;
|
||||
while ((count = ntfs_attr_pread(na, pos, NTFS_BUF_SIZE, buf)) > 0)
|
||||
pos += count;
|
||||
|
||||
if (count == -1 || pos != len) {
|
||||
err = errno;
|
||||
Dprintf("Amount of $LogFile data read does not "
|
||||
"correspond to expected length!");
|
||||
if (count != -1)
|
||||
err = EIO;
|
||||
goto io_error_exit;
|
||||
}
|
||||
|
||||
/* Fill the buffer with 0xff's. */
|
||||
memset(buf, -1, NTFS_BUF_SIZE);
|
||||
|
||||
/* Set the $DATA attribute. */
|
||||
pos = 0;
|
||||
while ((count = len - pos) > 0) {
|
||||
if (count > NTFS_BUF_SIZE)
|
||||
count = NTFS_BUF_SIZE;
|
||||
|
||||
if ((count = ntfs_attr_pwrite(na, pos, count, buf)) <= 0) {
|
||||
err = errno;
|
||||
Dprintf("Failed to set the $LogFile attribute value.");
|
||||
if (count != -1)
|
||||
err = EIO;
|
||||
goto io_error_exit;
|
||||
}
|
||||
pos += count;
|
||||
}
|
||||
|
||||
/* Set the flag so we do not have to do it again on remount. */
|
||||
NVolSetLogFileEmpty(na->ni->vol);
|
||||
done:
|
||||
ntfs_debug("Done.");
|
||||
return 0;
|
||||
io_error_exit:
|
||||
ntfs_attr_close(na);
|
||||
ntfs_inode_close(na->ni);
|
||||
errno = err;
|
||||
return -1;
|
||||
}
|
|
@ -1472,7 +1472,7 @@ int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
|
|||
u64 mft_no;
|
||||
int err;
|
||||
u16 seq_no, old_seq_no;
|
||||
|
||||
|
||||
Dprintf("%s(): Entering for inode 0x%llx.\n",
|
||||
__FUNCTION__, (long long) ni->mft_no);
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ char *ntfs_guid_to_mbs(const GUID *guid, char *guid_str)
|
|||
return _guid_str;
|
||||
if (!guid_str)
|
||||
free(_guid_str);
|
||||
errno = EINVAL;
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -563,7 +563,7 @@ static int ntfs_volume_check_logfile(ntfs_volume *vol)
|
|||
ntfs_inode *ni;
|
||||
ntfs_attr *na = NULL;
|
||||
int ret, err = 0;
|
||||
|
||||
|
||||
if ((ni = ntfs_inode_open(vol, FILE_LogFile)) == NULL) {
|
||||
Dprintf("Failed to open inode FILE_LogFile.\n");
|
||||
errno = EIO;
|
||||
|
@ -610,13 +610,13 @@ static ntfs_inode *ntfs_hiberfile_open(ntfs_volume *vol)
|
|||
errno = EINVAL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
ni_root = ntfs_inode_open(vol, FILE_root);
|
||||
if (!ni_root) {
|
||||
Dprintf("Couldn't open the root directory.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
unicode_len = ntfs_mbstoucs(hiberfile, &unicode, 0);
|
||||
if (unicode_len < 0) {
|
||||
Dperror("Couldn't convert 'hiberfil.sys' to Unicode");
|
||||
|
@ -659,7 +659,7 @@ static int ntfs_volume_check_hiberfile(ntfs_volume *vol)
|
|||
ntfs_attr *na = NULL;
|
||||
int i, bytes_read, ret = -1;
|
||||
char *buf = NULL;
|
||||
|
||||
|
||||
ni = ntfs_hiberfile_open(vol);
|
||||
if (!ni) {
|
||||
if (errno == ENOENT)
|
||||
|
|
|
@ -165,7 +165,7 @@ static BOOL WINAPI libntfs_SetFilePointerEx(HANDLE hFile,
|
|||
*
|
||||
* The Find*Volume and SetFilePointerEx functions exist only on win2k+, as such
|
||||
* we cannot just staticly import them.
|
||||
*
|
||||
*
|
||||
* This function initializes the imports if the functions do exist and in the
|
||||
* SetFilePointerEx case, we emulate the function ourselves if it is not
|
||||
* present.
|
||||
|
@ -257,11 +257,11 @@ static int ntfs_device_win32_simple_open_file(const char *filename,
|
|||
*handle = CreateFile(filename,
|
||||
ntfs_device_unix_status_flags_to_win32(flags),
|
||||
locking ? 0 : (FILE_SHARE_WRITE | FILE_SHARE_READ),
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (*handle == INVALID_HANDLE_VALUE) {
|
||||
errno = ntfs_w32error_to_errno(GetLastError());
|
||||
Dprintf("CreateFile(%s) failed.\n", filename);
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -512,7 +512,7 @@ static __inline__ int ntfs_device_win32_open_file(char *filename, win32_fd *fd,
|
|||
if (ntfs_device_win32_simple_open_file(filename, &handle, flags,
|
||||
FALSE)) {
|
||||
/* open error */
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
/* fill fd */
|
||||
fd->handle = handle;
|
||||
|
@ -545,7 +545,7 @@ static __inline__ int ntfs_device_win32_open_drive(int drive_id, win32_fd *fd,
|
|||
if ((err = ntfs_device_win32_simple_open_file(filename, &handle, flags,
|
||||
TRUE))) {
|
||||
/* open error */
|
||||
return err;
|
||||
return err;
|
||||
}
|
||||
/* store the drive geometry */
|
||||
ntfs_device_win32_getgeo(handle, fd);
|
||||
|
@ -798,7 +798,7 @@ static int ntfs_device_win32_open_partition(int drive_id,
|
|||
drive_id);
|
||||
CloseHandle(handle);
|
||||
errno = ENODEV;
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1257,7 +1257,7 @@ static s64 ntfs_device_win32_write(struct ntfs_device *dev, const void *b,
|
|||
}
|
||||
}
|
||||
/* Copy the data to be written into @alignedbuffer. */
|
||||
memcpy(alignedbuffer + ofs, b, count);
|
||||
memcpy(alignedbuffer + ofs, b, count);
|
||||
}
|
||||
if (fd->vol_handle != INVALID_HANDLE_VALUE && old_pos < fd->geo_size) {
|
||||
s64 vol_to_write = fd->geo_size - old_pos;
|
||||
|
@ -1379,8 +1379,8 @@ static __inline__ int ntfs_win32_blksszget(struct ntfs_device *dev,int *argp)
|
|||
DWORD bytesReturned;
|
||||
DISK_GEOMETRY dg;
|
||||
|
||||
if (DeviceIoControl(fd->handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||
&dg, sizeof(DISK_GEOMETRY), &bytesReturned, NULL)) {
|
||||
if (DeviceIoControl(fd->handle, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
|
||||
&dg, sizeof(DISK_GEOMETRY), &bytesReturned, NULL)) {
|
||||
/* success */
|
||||
*argp = dg.BytesPerSector;
|
||||
return 0;
|
||||
|
|
|
@ -135,8 +135,7 @@ switch if you want to be able to build the NTFS utilities."
|
|||
|
||||
extern const unsigned char attrdef_ntfs12_array[2400];
|
||||
extern const unsigned char boot_array[3429];
|
||||
extern void init_system_file_sd(int sys_file_no, char **sd_val,
|
||||
int *sd_val_len);
|
||||
extern void init_system_file_sd(int sys_file_no, u8 **sd_val, int *sd_val_len);
|
||||
extern void init_upcase_table(ntfschar *uc, u32 uc_len);
|
||||
|
||||
/* Page size on ia32. Can change to 8192 on Alpha. */
|
||||
|
@ -145,13 +144,13 @@ extern void init_upcase_table(ntfschar *uc, u32 uc_len);
|
|||
const char *EXEC_NAME = "mkntfs";
|
||||
|
||||
/* Need these global so mkntfs_exit can access them. */
|
||||
char *buf = NULL;
|
||||
char *buf2 = NULL;
|
||||
u8 *buf = NULL;
|
||||
u8 *buf2 = NULL;
|
||||
int buf2_size = 0;
|
||||
int mft_bitmap_size, mft_bitmap_byte_size;
|
||||
unsigned char *mft_bitmap = NULL;
|
||||
u8 *mft_bitmap = NULL;
|
||||
int lcn_bitmap_byte_size;
|
||||
unsigned char *lcn_bitmap = NULL;
|
||||
u8 *lcn_bitmap = NULL;
|
||||
runlist *rl_mft = NULL, *rl_mft_bmp = NULL, *rl_mftmirr = NULL;
|
||||
runlist *rl_logfile = NULL, *rl_boot = NULL, *rl_bad = NULL, *rl_index;
|
||||
INDEX_ALLOCATION *index_block = NULL;
|
||||
|
@ -174,7 +173,7 @@ struct {
|
|||
long long logfile_lcn; /* lcn of $LogFile, $DATA. */
|
||||
int logfile_size; /* in bytes, determined from
|
||||
volume_size. */
|
||||
int mft_zone_multiplier; /* -z, value from 1 to 4. Default is
|
||||
int mft_zone_multiplier; /* -z, value from 1 to 4. Default is
|
||||
1. */
|
||||
long long mft_zone_end; /* Determined from volume_size and
|
||||
mft_zone_multiplier, in clusters. */
|
||||
|
@ -251,7 +250,7 @@ GEN_PRINTF(Qprintf, stdout, &opts.quiet, FALSE)
|
|||
/**
|
||||
* err_exit - error output and terminate; ignores quiet (-q)
|
||||
*/
|
||||
static void err_exit(const char *fmt, ...)
|
||||
static void err_exit(const char *fmt, ...)
|
||||
__attribute__((noreturn))
|
||||
__attribute__((format(printf, 1, 2)));
|
||||
static void err_exit(const char *fmt, ...)
|
||||
|
@ -520,7 +519,7 @@ static __inline__ long long mkntfs_write(struct ntfs_device *dev,
|
|||
* Note: Might not return.
|
||||
*/
|
||||
static s64 ntfs_rlwrite(struct ntfs_device *dev, const runlist *rl,
|
||||
const char *val, const s64 val_len, s64 *inited_size)
|
||||
const u8 *val, const s64 val_len, s64 *inited_size)
|
||||
{
|
||||
s64 bytes_written, total, length, delta;
|
||||
int retry, i;
|
||||
|
@ -1191,7 +1190,7 @@ err_end:
|
|||
static int insert_positioned_attr_in_mft_record(MFT_RECORD *m,
|
||||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const runlist *rl, const char *val, const s64 val_len)
|
||||
const runlist *rl, const u8 *val, const s64 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *a;
|
||||
|
@ -1376,7 +1375,7 @@ err_out:
|
|||
static int insert_non_resident_attr_in_mft_record(MFT_RECORD *m,
|
||||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const char *val, const s64 val_len)
|
||||
const u8 *val, const s64 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *a;
|
||||
|
@ -1568,7 +1567,7 @@ static int insert_resident_attr_in_mft_record(MFT_RECORD *m,
|
|||
const ATTR_TYPES type, const char *name, u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const RESIDENT_ATTR_FLAGS res_flags,
|
||||
const char *val, const u32 val_len)
|
||||
const u8 *val, const u32 val_len)
|
||||
{
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *a;
|
||||
|
@ -1698,7 +1697,7 @@ static int add_attr_std_info(MFT_RECORD *m, const FILE_ATTR_FLAGS flags)
|
|||
}
|
||||
/* NTFS 1.2: size of si = 48, NTFS 3.0: size of si = 72 */
|
||||
err = insert_resident_attr_in_mft_record(m, AT_STANDARD_INFORMATION,
|
||||
NULL, 0, 0, 0, 0, (char*)&si,
|
||||
NULL, 0, 0, 0, 0, (u8*)&si,
|
||||
vol->major_ver < 3 ? 48 : 72);
|
||||
if (err < 0)
|
||||
Eprintf("add_attr_std_info failed: %s\n", strerror(-err));
|
||||
|
@ -1778,7 +1777,7 @@ static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
|
|||
fn->file_name_length = i;
|
||||
fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(ntfschar);
|
||||
i = insert_resident_attr_in_mft_record(m, AT_FILE_NAME, NULL, 0, 0,
|
||||
0, RESIDENT_ATTR_IS_INDEXED, (char*)fn, fn_size);
|
||||
0, RESIDENT_ATTR_IS_INDEXED, (u8*)fn, fn_size);
|
||||
free(fn);
|
||||
if (i < 0)
|
||||
Eprintf("add_attr_file_name failed: %s\n", strerror(-i));
|
||||
|
@ -1792,7 +1791,7 @@ static int add_attr_file_name(MFT_RECORD *m, const MFT_REF parent_dir,
|
|||
*
|
||||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
static int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
|
||||
static int add_attr_sd(MFT_RECORD *m, const u8 *sd, const s64 sd_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1817,7 +1816,7 @@ static int add_attr_sd(MFT_RECORD *m, const char *sd, const s64 sd_len)
|
|||
*/
|
||||
static int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const ATTR_FLAGS flags,
|
||||
const char *val, const s64 val_len)
|
||||
const u8 *val, const s64 val_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1857,7 +1856,7 @@ static int add_attr_data(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
static int add_attr_data_positioned(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const ATTR_FLAGS flags, const runlist *rl,
|
||||
const char *val, const s64 val_len)
|
||||
const u8 *val, const s64 val_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -1904,7 +1903,7 @@ static int add_attr_vol_name(MFT_RECORD *m, const char *vol_name,
|
|||
len = 0;
|
||||
}
|
||||
i = insert_resident_attr_in_mft_record(m, AT_VOLUME_NAME, NULL, 0, 0,
|
||||
0, 0, (char*)uname, len);
|
||||
0, 0, (u8*)uname, len);
|
||||
if (uname)
|
||||
free(uname);
|
||||
if (i < 0)
|
||||
|
@ -1927,7 +1926,7 @@ static int add_attr_vol_info(MFT_RECORD *m, const VOLUME_FLAGS flags,
|
|||
vi.minor_ver = minor_ver;
|
||||
vi.flags = flags & VOLUME_FLAGS_MASK;
|
||||
err = insert_resident_attr_in_mft_record(m, AT_VOLUME_INFORMATION, NULL,
|
||||
0, 0, 0, 0, (char*)&vi, sizeof(vi));
|
||||
0, 0, 0, 0, (u8*)&vi, sizeof(vi));
|
||||
if (err < 0)
|
||||
Eprintf("add_attr_vol_info failed: %s\n", strerror(-err));
|
||||
return err;
|
||||
|
@ -2006,7 +2005,7 @@ static int add_attr_index_root(MFT_RECORD *m, const char *name,
|
|||
e->flags = INDEX_ENTRY_END;
|
||||
e->reserved = cpu_to_le16(0);
|
||||
err = insert_resident_attr_in_mft_record(m, AT_INDEX_ROOT, name,
|
||||
name_len, ic, 0, 0, (char*)r, val_len);
|
||||
name_len, ic, 0, 0, (u8*)r, val_len);
|
||||
free(r);
|
||||
if (err < 0)
|
||||
Eprintf("add_attr_index_root failed: %s\n", strerror(-err));
|
||||
|
@ -2019,7 +2018,7 @@ static int add_attr_index_root(MFT_RECORD *m, const char *name,
|
|||
*/
|
||||
static int add_attr_index_alloc(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const char *index_alloc_val, const u32 index_alloc_val_len)
|
||||
const u8 *index_alloc_val, const u32 index_alloc_val_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -2036,7 +2035,7 @@ static int add_attr_index_alloc(MFT_RECORD *m, const char *name,
|
|||
* Return 0 on success or -errno on error.
|
||||
*/
|
||||
static int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
|
||||
const IGNORE_CASE_BOOL ic, const char *bitmap,
|
||||
const IGNORE_CASE_BOOL ic, const u8 *bitmap,
|
||||
const u32 bitmap_len)
|
||||
{
|
||||
int err;
|
||||
|
@ -2065,7 +2064,7 @@ static int add_attr_bitmap(MFT_RECORD *m, const char *name, const u32 name_len,
|
|||
*/
|
||||
static int add_attr_bitmap_positioned(MFT_RECORD *m, const char *name,
|
||||
const u32 name_len, const IGNORE_CASE_BOOL ic,
|
||||
const runlist *rl, const char *bitmap, const u32 bitmap_len)
|
||||
const runlist *rl, const u8 *bitmap, const u32 bitmap_len)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
@ -2095,7 +2094,7 @@ static int upgrade_to_large_index(MFT_RECORD *m, const char *name,
|
|||
INDEX_ENTRY *re;
|
||||
INDEX_ALLOCATION *ia_val = NULL;
|
||||
ntfschar *uname;
|
||||
char bmp[8];
|
||||
u8 bmp[8];
|
||||
char *re_start, *re_end;
|
||||
int i, err, index_block_size;
|
||||
|
||||
|
@ -2147,7 +2146,7 @@ static int upgrade_to_large_index(MFT_RECORD *m, const char *name,
|
|||
memset(bmp, 0, sizeof(bmp));
|
||||
ntfs_bit_set(bmp, 0ULL, 1);
|
||||
/* Bitmap has to be at least 8 bytes in size. */
|
||||
err = add_attr_bitmap(m, name, name_len, ic, (char*)&bmp, sizeof(bmp));
|
||||
err = add_attr_bitmap(m, name, name_len, ic, bmp, sizeof(bmp));
|
||||
if (err)
|
||||
goto err_out;
|
||||
ia_val = calloc(1, index_block_size);
|
||||
|
@ -2224,7 +2223,7 @@ static int upgrade_to_large_index(MFT_RECORD *m, const char *name,
|
|||
"upgrade_to_large_index.\n");
|
||||
goto err_out;
|
||||
}
|
||||
err = add_attr_index_alloc(m, name, name_len, ic, (char*)ia_val,
|
||||
err = add_attr_index_alloc(m, name, name_len, ic, (u8*)ia_val,
|
||||
index_block_size);
|
||||
ntfs_mst_post_write_fixup((NTFS_RECORD*)ia_val);
|
||||
if (err) {
|
||||
|
@ -2491,7 +2490,7 @@ static int create_hardlink(INDEX_BLOCK *idx, const MFT_REF ref_parent,
|
|||
m_file->link_count = cpu_to_le16(i + 1);
|
||||
/* Add the file_name to @m_file. */
|
||||
i = insert_resident_attr_in_mft_record(m_file, AT_FILE_NAME, NULL, 0, 0,
|
||||
0, RESIDENT_ATTR_IS_INDEXED, (char*)fn, fn_size);
|
||||
0, RESIDENT_ATTR_IS_INDEXED, (u8*)fn, fn_size);
|
||||
if (i < 0) {
|
||||
Eprintf("create_hardlink failed adding file name attribute: "
|
||||
"%s\n", strerror(-i));
|
||||
|
@ -2883,7 +2882,7 @@ static void mkntfs_override_phys_params(void)
|
|||
static void mkntfs_initialize_bitmaps(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
||||
/* Determine lcn bitmap byte size and allocate it. */
|
||||
lcn_bitmap_byte_size = (opts.nr_clusters + 7) >> 3;
|
||||
/* Needs to be multiple of 8 bytes. */
|
||||
|
@ -2949,7 +2948,7 @@ static void mkntfs_initialize_bitmaps(void)
|
|||
static void mkntfs_initialize_rl_mft(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
|
||||
/* If user didn't specify the mft lcn, determine it now. */
|
||||
if (!opts.mft_lcn) {
|
||||
/*
|
||||
|
@ -3224,7 +3223,7 @@ static void mkntfs_fill_device_with_zeroes(void)
|
|||
static void create_file_volume(MFT_RECORD *m, MFT_REF root_ref, VOLUME_FLAGS fl)
|
||||
{
|
||||
int i, err;
|
||||
char *sd;
|
||||
u8 *sd;
|
||||
|
||||
Vprintf("Creating $Volume (mft record 3)\n");
|
||||
m = (MFT_RECORD*)(buf + 3 * vol->mft_record_size);
|
||||
|
@ -3256,7 +3255,7 @@ static void create_file_volume(MFT_RECORD *m, MFT_REF root_ref, VOLUME_FLAGS fl)
|
|||
*
|
||||
* Return 0 on success or 1 if it couldn't be created.
|
||||
*/
|
||||
static int create_backup_boot_sector(char *buff, int size)
|
||||
static int create_backup_boot_sector(u8 *buff, int size)
|
||||
{
|
||||
ssize_t bw;
|
||||
int _e = errno;
|
||||
|
@ -3304,7 +3303,7 @@ static void mkntfs_create_root_structures(void)
|
|||
MFT_RECORD *m;
|
||||
MFT_REF root_ref;
|
||||
int i, j, err;
|
||||
char *sd;
|
||||
u8 *sd;
|
||||
VOLUME_FLAGS volume_flags = 0;
|
||||
|
||||
Qprintf("Creating NTFS volume structures.\n");
|
||||
|
@ -3473,7 +3472,7 @@ static void mkntfs_create_root_structures(void)
|
|||
buf2_size = 36000;
|
||||
else
|
||||
buf2_size = opts.attr_defs_len;
|
||||
buf2 = (char*)calloc(1, buf2_size);
|
||||
buf2 = calloc(1, buf2_size);
|
||||
if (!buf2)
|
||||
err_exit("Failed to allocate internal buffer: %s\n",
|
||||
strerror(errno));
|
||||
|
@ -3598,7 +3597,7 @@ static void mkntfs_create_root_structures(void)
|
|||
}
|
||||
if (err < 0)
|
||||
err_exit("Couldn't create $Boot: %s\n", strerror(-err));
|
||||
|
||||
|
||||
if (create_backup_boot_sector(buf2, i) != 0) {
|
||||
/*
|
||||
* Pre-2.6 kernels couldn't access the last sector
|
||||
|
@ -3651,7 +3650,7 @@ static void mkntfs_create_root_structures(void)
|
|||
//dump_mft_record(m);
|
||||
Vprintf("Creating $UpCase (mft record 0xa)\n");
|
||||
m = (MFT_RECORD*)(buf + 0xa * vol->mft_record_size);
|
||||
err = add_attr_data(m, NULL, 0, 0, 0, (char*)vol->upcase,
|
||||
err = add_attr_data(m, NULL, 0, 0, 0, (u8*)vol->upcase,
|
||||
vol->upcase_len << 1);
|
||||
if (!err)
|
||||
err = create_hardlink(index_block, root_ref, m,
|
||||
|
@ -3790,7 +3789,7 @@ int main(int argc, char **argv)
|
|||
if (err)
|
||||
err_exit("ntfs_mst_pre_write_fixup() failed while syncing "
|
||||
"root directory index block.\n");
|
||||
lw = ntfs_rlwrite(vol->dev, rl_index, (char*)index_block, i, NULL);
|
||||
lw = ntfs_rlwrite(vol->dev, rl_index, (u8*)index_block, i, NULL);
|
||||
if (lw != i)
|
||||
err_exit("Error writing $INDEX_ALLOCATION.\n");
|
||||
/* No more changes to @index_block below here so no need for fixup: */
|
||||
|
|
|
@ -215,7 +215,7 @@ static int cat (ntfs_volume *vol __attribute__((unused)), ntfs_inode *inode,
|
|||
int namelen __attribute__((unused)))
|
||||
{
|
||||
/* increase 1024 only if you fix partial writes below */
|
||||
const int bufsize = 1024;
|
||||
const int bufsize = 1024;
|
||||
char *buffer;
|
||||
ntfs_attr *attr;
|
||||
s64 bytes_read, written;
|
||||
|
@ -279,25 +279,25 @@ int main (int argc, char *argv[])
|
|||
|
||||
vol = utils_mount_volume (opts.device, MS_RDONLY, opts.force);
|
||||
if (!vol) {
|
||||
perror("ERROR: couldn't mount volume");
|
||||
perror("ERROR: couldn't mount volume");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (opts.inode != -1)
|
||||
inode = ntfs_inode_open (vol, opts.inode);
|
||||
else
|
||||
inode = ntfs_pathname_to_inode (vol, NULL, opts.file);
|
||||
if (opts.inode != -1)
|
||||
inode = ntfs_inode_open (vol, opts.inode);
|
||||
else
|
||||
inode = ntfs_pathname_to_inode (vol, NULL, opts.file);
|
||||
|
||||
if (!inode) {
|
||||
perror("ERROR: Couldn't open inode");
|
||||
perror("ERROR: Couldn't open inode");
|
||||
return 1;
|
||||
}
|
||||
|
||||
attr = AT_DATA;
|
||||
if (opts.attr != (ATTR_TYPES)-1)
|
||||
attr = opts.attr;
|
||||
|
||||
result = cat (vol, inode, attr, NULL, 0);
|
||||
attr = AT_DATA;
|
||||
if (opts.attr != (ATTR_TYPES)-1)
|
||||
attr = opts.attr;
|
||||
|
||||
result = cat (vol, inode, attr, NULL, 0);
|
||||
|
||||
ntfs_inode_close (inode);
|
||||
ntfs_umount (vol, FALSE);
|
||||
|
|
|
@ -60,7 +60,7 @@ struct {
|
|||
int force;
|
||||
int overwrite;
|
||||
int std_out;
|
||||
int blkdev_out; /* output file is block device */
|
||||
int blkdev_out; /* output file is block device */
|
||||
int metadata_only;
|
||||
int ignore_fs_check;
|
||||
int rescue;
|
||||
|
@ -300,7 +300,7 @@ static void parse_options(int argc, char **argv)
|
|||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (opt.output == NULL) {
|
||||
err_printf("You must specify an output file.\n");
|
||||
usage();
|
||||
|
@ -321,7 +321,7 @@ static void parse_options(int argc, char **argv)
|
|||
if (opt.metadata_only && opt.restore_image)
|
||||
err_exit("Restoring only metadata from an image is not "
|
||||
"supported!\n");
|
||||
|
||||
|
||||
if (opt.metadata_only && opt.std_out)
|
||||
err_exit("Cloning only metadata to stdout isn't supported!\n");
|
||||
|
||||
|
@ -332,13 +332,13 @@ static void parse_options(int argc, char **argv)
|
|||
if (opt.save_image && opt.restore_image)
|
||||
err_exit("Saving and restoring an image at the same time "
|
||||
"is not supported!\n");
|
||||
|
||||
|
||||
if (!opt.std_out) {
|
||||
struct stat st;
|
||||
|
||||
|
||||
if (stat(opt.output, &st) == -1) {
|
||||
if (errno != ENOENT)
|
||||
perr_exit("Couldn't access '%s'", opt.output);
|
||||
perr_exit("Couldn't access '%s'", opt.output);
|
||||
} else {
|
||||
if (!opt.overwrite)
|
||||
err_exit("Output file '%s' already exists.\n"
|
||||
|
@ -352,16 +352,16 @@ static void parse_options(int argc, char **argv)
|
|||
"block device isn't supported!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
msg_out = stdout;
|
||||
|
||||
|
||||
/* FIXME: this is a workaround for loosing debug info if stdout != stderr
|
||||
and for the uncontrollable verbose messages in libntfs. Ughhh. */
|
||||
if (opt.std_out)
|
||||
msg_out = stderr;
|
||||
else if (opt.debug)
|
||||
stderr = stdout;
|
||||
stderr = stdout;
|
||||
else
|
||||
if (!(stderr = fopen("/dev/null", "rw")))
|
||||
perr_exit("Couldn't open /dev/null");
|
||||
|
@ -413,7 +413,7 @@ static s64 is_critical_metadata(ntfs_walk_clusters_ctx *image, runlist *rl)
|
|||
s64 inode = image->ni->mft_no;
|
||||
|
||||
if (inode <= LAST_METADATA_INODE) {
|
||||
|
||||
|
||||
/* Don't save bad sectors (both $Bad and unnamed are ignored */
|
||||
if (inode == FILE_BadClus && image->ctx->attr->type == AT_DATA)
|
||||
return 0;
|
||||
|
@ -434,7 +434,7 @@ static s64 is_critical_metadata(ntfs_walk_clusters_ctx *image, runlist *rl)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (image->ctx->attr->type != AT_DATA)
|
||||
return rl->length;
|
||||
|
||||
|
@ -446,7 +446,7 @@ static int io_all(void *fd, void *buf, int count, int do_write)
|
|||
{
|
||||
int i;
|
||||
struct ntfs_device *dev = fd;
|
||||
|
||||
|
||||
while (count > 0) {
|
||||
if (do_write)
|
||||
i = write(*(int *)fd, buf, count);
|
||||
|
@ -494,7 +494,7 @@ static void copy_cluster(int rescue, off_t rescue_pos)
|
|||
/* vol is NULL if opt.restore_image is set */
|
||||
u32 csize = image_hdr.cluster_size;
|
||||
void *fd = (void *)&fd_in;
|
||||
|
||||
|
||||
if (!opt.restore_image) {
|
||||
csize = vol->cluster_size;
|
||||
fd = vol->dev;
|
||||
|
@ -516,7 +516,7 @@ static void copy_cluster(int rescue, off_t rescue_pos)
|
|||
if (write_all(&fd_out, &cmd, sizeof(cmd)) == -1)
|
||||
perr_exit("write_all");
|
||||
}
|
||||
|
||||
|
||||
if (write_all(&fd_out, buff, csize) == -1) {
|
||||
int err = errno;
|
||||
perr_printf("Write failed");
|
||||
|
@ -532,9 +532,9 @@ static void copy_cluster(int rescue, off_t rescue_pos)
|
|||
static void lseek_to_cluster(s64 lcn)
|
||||
{
|
||||
off_t pos;
|
||||
|
||||
|
||||
pos = (off_t)(lcn * vol->cluster_size);
|
||||
|
||||
|
||||
if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1)
|
||||
perr_exit("lseek input");
|
||||
|
||||
|
@ -552,7 +552,7 @@ static void image_skip_clusters(s64 count)
|
|||
|
||||
buff[0] = 0;
|
||||
memcpy(buff + 1, &count, sizeof(count));
|
||||
|
||||
|
||||
if (write_all(&fd_out, buff, sizeof(buff)) == -1)
|
||||
perr_exit("write_all");
|
||||
}
|
||||
|
@ -561,15 +561,15 @@ static void image_skip_clusters(s64 count)
|
|||
static void dump_clusters(ntfs_walk_clusters_ctx *image, runlist *rl)
|
||||
{
|
||||
s64 i, len; /* number of clusters to copy */
|
||||
|
||||
|
||||
if (opt.std_out || !opt.metadata_only)
|
||||
return;
|
||||
|
||||
|
||||
if (!(len = is_critical_metadata(image, rl)))
|
||||
return;
|
||||
|
||||
|
||||
lseek_to_cluster(rl->lcn);
|
||||
|
||||
|
||||
/* FIXME: this could give pretty suboptimal performance */
|
||||
for (i = 0; i < len; i++)
|
||||
copy_cluster(opt.rescue, rl->lcn + i);
|
||||
|
@ -597,19 +597,19 @@ static void clone_ntfs(u64 nr_clusters)
|
|||
if (write_all(&fd_out, &image_hdr, sizeof(image_hdr)) == -1)
|
||||
perr_exit("write_all");
|
||||
}
|
||||
|
||||
|
||||
for (last_cl = cl = 0; cl < (u64)vol->nr_clusters; cl++) {
|
||||
|
||||
|
||||
if (ntfs_bit_get(lcn_bitmap.bm, cl)) {
|
||||
progress_update(&progress, ++p_counter);
|
||||
lseek_to_cluster(cl);
|
||||
image_skip_clusters(cl - last_cl - 1);
|
||||
|
||||
|
||||
copy_cluster(opt.rescue, cl);
|
||||
last_cl = cl;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (opt.std_out && !opt.save_image) {
|
||||
progress_update(&progress, ++p_counter);
|
||||
if (write_all(&fd_out, buf, csize) == -1)
|
||||
|
@ -624,7 +624,7 @@ static void write_empty_clusters(s32 csize, s64 count,
|
|||
{
|
||||
s64 i;
|
||||
char buff[NTFS_MAX_CLUSTER_SIZE];
|
||||
|
||||
|
||||
memset(buff, 0, csize);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
|
@ -689,14 +689,14 @@ do { \
|
|||
static void wipe_timestamps(ntfs_walk_clusters_ctx *image)
|
||||
{
|
||||
ATTR_RECORD *a = image->ctx->attr;
|
||||
|
||||
|
||||
if (image->ni->mft_no <= LAST_METADATA_INODE)
|
||||
return;
|
||||
|
||||
if (a->type == AT_FILE_NAME)
|
||||
if (a->type == AT_FILE_NAME)
|
||||
WIPE_TIMESTAMPS(FILE_NAME_ATTR, a);
|
||||
|
||||
else if (a->type == AT_STANDARD_INFORMATION)
|
||||
else if (a->type == AT_STANDARD_INFORMATION)
|
||||
WIPE_TIMESTAMPS(STANDARD_INFORMATION, a);
|
||||
}
|
||||
|
||||
|
@ -709,27 +709,27 @@ static void wipe_resident_data(ntfs_walk_clusters_ctx *image)
|
|||
|
||||
a = image->ctx->attr;
|
||||
p = (u8*)a + le16_to_cpu(a->value_offset);
|
||||
|
||||
|
||||
if (image->ni->mft_no <= LAST_METADATA_INODE)
|
||||
return;
|
||||
|
||||
|
||||
if (a->type != AT_DATA)
|
||||
return;
|
||||
|
||||
|
||||
for (i = 0; i < le32_to_cpu(a->value_length); i++) {
|
||||
if (p[i]) {
|
||||
p[i] = 0;
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
wiped_resident_data += n;
|
||||
}
|
||||
|
||||
static void clone_logfile_parts(ntfs_walk_clusters_ctx *image, runlist *rl)
|
||||
{
|
||||
s64 offset = 0, lcn, vcn;
|
||||
|
||||
|
||||
while (1) {
|
||||
|
||||
vcn = offset / image->ni->vol->cluster_size;
|
||||
|
@ -781,10 +781,10 @@ static void walk_runs(struct ntfs_walk_cluster *walk)
|
|||
"%llx length %llx\n", ctx->ntfs_ino->mft_no,
|
||||
(unsigned int)le32_to_cpu(a->type), lcn,
|
||||
lcn_length);
|
||||
|
||||
|
||||
if (!wipe)
|
||||
dump_clusters(walk->image, rl + i);
|
||||
|
||||
|
||||
for (j = 0; j < lcn_length; j++) {
|
||||
u64 k = (u64)lcn + j;
|
||||
if (ntfs_bit_get_and_set(lcn_bitmap.bm, k, 1))
|
||||
|
@ -799,7 +799,7 @@ static void walk_runs(struct ntfs_walk_cluster *walk)
|
|||
walk->image->ni->mft_no == FILE_LogFile &&
|
||||
walk->image->ctx->attr->type == AT_DATA)
|
||||
clone_logfile_parts(walk->image, rl);
|
||||
|
||||
|
||||
free(rl);
|
||||
}
|
||||
|
||||
|
@ -847,7 +847,7 @@ static void compare_bitmaps(struct bitmap *a)
|
|||
}
|
||||
|
||||
for (i = 0; i < count; i++, pos++) {
|
||||
s64 cl; /* current cluster */
|
||||
s64 cl; /* current cluster */
|
||||
|
||||
if (a->bm[pos] == bm[i])
|
||||
continue;
|
||||
|
@ -858,7 +858,7 @@ static void compare_bitmaps(struct bitmap *a)
|
|||
bit = ntfs_bit_get(a->bm, cl);
|
||||
if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))
|
||||
continue;
|
||||
|
||||
|
||||
if (opt.ignore_fs_check) {
|
||||
lseek_to_cluster(cl);
|
||||
copy_cluster(opt.rescue, cl);
|
||||
|
@ -892,13 +892,13 @@ static void compare_bitmaps(struct bitmap *a)
|
|||
static int wipe_data(char *p, int pos, int len)
|
||||
{
|
||||
int wiped = 0;
|
||||
|
||||
|
||||
for (p += pos; --len >= 0;) {
|
||||
if (p[len]) {
|
||||
p[len] = 0;
|
||||
wiped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return wiped;
|
||||
}
|
||||
|
@ -907,11 +907,11 @@ static void wipe_unused_mft_data(ntfs_inode *ni)
|
|||
{
|
||||
int unused;
|
||||
MFT_RECORD *m = ni->mrec;
|
||||
|
||||
|
||||
/* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
|
||||
if (ni->mft_no <= LAST_METADATA_INODE)
|
||||
return;
|
||||
|
||||
|
||||
unused = le32_to_cpu(m->bytes_allocated) - le32_to_cpu(m->bytes_in_use);
|
||||
wiped_unused_mft_data += wipe_data((char *)m,
|
||||
le32_to_cpu(m->bytes_in_use), unused);
|
||||
|
@ -921,11 +921,11 @@ static void wipe_unused_mft(ntfs_inode *ni)
|
|||
{
|
||||
int unused;
|
||||
MFT_RECORD *m = ni->mrec;
|
||||
|
||||
|
||||
/* FIXME: broken MFTMirr update was fixed in libntfs, check if OK now */
|
||||
if (ni->mft_no <= LAST_METADATA_INODE)
|
||||
return;
|
||||
|
||||
|
||||
unused = le32_to_cpu(m->bytes_in_use) - sizeof(MFT_RECORD);
|
||||
wiped_unused_mft += wipe_data((char *)m, sizeof(MFT_RECORD), unused);
|
||||
}
|
||||
|
@ -945,7 +945,7 @@ static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
|
|||
progress_init(&progress, inode, last_mft_rec, 100);
|
||||
|
||||
for (; inode <= last_mft_rec; inode++) {
|
||||
|
||||
|
||||
int err, deleted_inode;
|
||||
MFT_REF mref = (MFT_REF)inode;
|
||||
|
||||
|
@ -956,14 +956,14 @@ static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
|
|||
ni = (ntfs_inode*)calloc(1, sizeof(ntfs_inode));
|
||||
if (!ni)
|
||||
perr_exit("walk_clusters");
|
||||
|
||||
|
||||
ni->vol = volume;
|
||||
|
||||
err = ntfs_file_record_read(volume, mref, &ni->mrec, NULL);
|
||||
if (err == -1) {
|
||||
free(ni);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
deleted_inode = !(ni->mrec->flags & MFT_RECORD_IN_USE);
|
||||
|
||||
|
@ -975,16 +975,16 @@ static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
|
|||
wipe_unused_mft_data(ni);
|
||||
if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec))
|
||||
perr_exit("ntfs_mft_record_write");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ni->mrec)
|
||||
free(ni->mrec);
|
||||
free(ni);
|
||||
|
||||
if (deleted_inode)
|
||||
if (deleted_inode)
|
||||
continue;
|
||||
|
||||
|
||||
if ((ni = ntfs_inode_open(volume, mref)) == NULL) {
|
||||
/* FIXME: continue only if it make sense, e.g.
|
||||
MFT record not in use based on $MFT bitmap */
|
||||
|
@ -1001,17 +1001,17 @@ static int walk_clusters(ntfs_volume *volume, struct ntfs_walk_cluster *walk)
|
|||
|
||||
walk->image->ni = ni;
|
||||
walk_attributes(walk);
|
||||
out:
|
||||
out:
|
||||
if (wipe) {
|
||||
wipe_unused_mft_data(ni);
|
||||
if (ntfs_mft_record_write(volume, ni->mft_no, ni->mrec))
|
||||
perr_exit("ntfs_mft_record_write");
|
||||
}
|
||||
}
|
||||
|
||||
if (ntfs_inode_close(ni))
|
||||
perr_exit("ntfs_inode_close for inode %lld", inode);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1088,7 +1088,7 @@ static void print_image_info(void)
|
|||
static void check_if_mounted(const char *device, unsigned long new_mntflag)
|
||||
{
|
||||
unsigned long mntflag;
|
||||
|
||||
|
||||
if (ntfs_check_if_mounted(device, &mntflag))
|
||||
perr_exit("Failed to check '%s' mount state", device);
|
||||
|
||||
|
@ -1110,7 +1110,7 @@ static void check_if_mounted(const char *device, unsigned long new_mntflag)
|
|||
static void mount_volume(unsigned long new_mntflag)
|
||||
{
|
||||
check_if_mounted(opt.volume, new_mntflag);
|
||||
|
||||
|
||||
if (!(vol = ntfs_mount(opt.volume, new_mntflag))) {
|
||||
|
||||
int err = errno;
|
||||
|
@ -1129,7 +1129,7 @@ static void mount_volume(unsigned long new_mntflag)
|
|||
if (opt.force-- <= 0)
|
||||
err_exit("Volume is dirty. Run chkdsk and "
|
||||
"please try again (or see -f option).\n");
|
||||
|
||||
|
||||
if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)
|
||||
err_exit("Cluster size %u is too large!\n",
|
||||
(unsigned int)vol->cluster_size);
|
||||
|
@ -1144,7 +1144,7 @@ static void mount_volume(unsigned long new_mntflag)
|
|||
volume_size(vol, vol->nr_clusters));
|
||||
}
|
||||
|
||||
struct ntfs_walk_cluster backup_clusters = { NULL, NULL };
|
||||
struct ntfs_walk_cluster backup_clusters = { NULL, NULL };
|
||||
|
||||
static int device_offset_valid(int fd, s64 ofs)
|
||||
{
|
||||
|
@ -1163,7 +1163,7 @@ static s64 device_size_get(int fd)
|
|||
|
||||
if (ioctl(fd, BLKGETSIZE64, &size) >= 0) {
|
||||
Dprintf("BLKGETSIZE64 nr bytes = %llu (0x%llx)\n",
|
||||
(unsigned long long)size,
|
||||
(unsigned long long)size,
|
||||
(unsigned long long)size);
|
||||
return (s64)size;
|
||||
}
|
||||
|
@ -1250,7 +1250,7 @@ static void set_filesize(s64 filesize)
|
|||
static s64 open_image(void)
|
||||
{
|
||||
if (strcmp(opt.volume, "-") == 0) {
|
||||
if ((fd_in = fileno(stdin)) == -1)
|
||||
if ((fd_in = fileno(stdin)) == -1)
|
||||
perr_exit("fileno for stdout failed");
|
||||
} else {
|
||||
if ((fd_in = open(opt.volume, O_RDONLY)) == -1)
|
||||
|
@ -1269,15 +1269,15 @@ static s64 open_image(void)
|
|||
static s64 open_volume(void)
|
||||
{
|
||||
s64 device_size;
|
||||
|
||||
|
||||
mount_volume(MS_RDONLY);
|
||||
|
||||
|
||||
device_size = ntfs_device_size_get(vol->dev, 1);
|
||||
if (device_size <= 0)
|
||||
err_exit("Couldn't get device size (%lld)!\n", device_size);
|
||||
|
||||
|
||||
print_volume_size("Current device size", device_size);
|
||||
|
||||
|
||||
if (device_size < vol->nr_clusters * vol->cluster_size)
|
||||
err_exit("Current NTFS volume size is bigger than the device "
|
||||
"size (%lld)!\nCorrupt partition table or incorrect "
|
||||
|
@ -1304,7 +1304,7 @@ static void check_output_device(s64 input_size)
|
|||
if (dest_size < input_size)
|
||||
err_exit("Output device is too small (%lld) to fit the "
|
||||
"NTFS image (%lld).\n", dest_size, input_size);
|
||||
|
||||
|
||||
check_if_mounted(opt.output, 0);
|
||||
} else
|
||||
set_filesize(input_size);
|
||||
|
@ -1331,7 +1331,7 @@ static int str2unicode(const char *aname, ntfschar **ustr, int *len)
|
|||
*ustr = AT_UNNAMED;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1348,10 +1348,10 @@ static ntfs_attr_search_ctx *lookup_data_attr(ntfs_inode *ni, const char *aname)
|
|||
|
||||
if ((ctx = attr_get_search_ctx(ni, NULL)) == NULL)
|
||||
return NULL;
|
||||
|
||||
|
||||
if (str2unicode(aname, &ustr, &len) == -1)
|
||||
goto error_out;
|
||||
|
||||
|
||||
if (ntfs_attr_lookup(AT_DATA, ustr, len, 0, 0, NULL, 0, ctx)) {
|
||||
perr_printf("ntfs_attr_lookup");
|
||||
goto error_out;
|
||||
|
@ -1364,14 +1364,14 @@ error_out:
|
|||
ntfs_attr_put_search_ctx(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static void ignore_bad_clusters(ntfs_walk_clusters_ctx *image)
|
||||
{
|
||||
ntfs_inode *ni;
|
||||
ntfs_attr_search_ctx *ctx = NULL;
|
||||
runlist *rl;
|
||||
s64 nr_bad_clusters = 0;
|
||||
|
||||
|
||||
if (!(ni = ntfs_inode_open(vol, FILE_BadClus)))
|
||||
perr_exit("ntfs_open_inode");
|
||||
|
||||
|
@ -1380,10 +1380,10 @@ static void ignore_bad_clusters(ntfs_walk_clusters_ctx *image)
|
|||
|
||||
if (!(rl = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL)))
|
||||
perr_exit("ntfs_mapping_pairs_decompress");
|
||||
|
||||
|
||||
for (; rl->length; rl++) {
|
||||
s64 lcn = rl->lcn;
|
||||
|
||||
|
||||
if (lcn == LCN_HOLE || lcn < 0)
|
||||
continue;
|
||||
|
||||
|
@ -1413,7 +1413,7 @@ int main(int argc, char **argv)
|
|||
msg_out = stderr;
|
||||
|
||||
parse_options(argc, argv);
|
||||
|
||||
|
||||
utils_set_locale();
|
||||
|
||||
if (opt.restore_image) {
|
||||
|
@ -1426,19 +1426,19 @@ int main(int argc, char **argv)
|
|||
ntfs_size += 512; /* add backup boot sector */
|
||||
|
||||
if (opt.std_out) {
|
||||
if ((fd_out = fileno(stdout)) == -1)
|
||||
if ((fd_out = fileno(stdout)) == -1)
|
||||
perr_exit("fileno for stdout failed");
|
||||
} else {
|
||||
/* device_size_get() might need to read() */
|
||||
int flags = O_RDWR;
|
||||
|
||||
|
||||
if (!opt.blkdev_out) {
|
||||
flags |= O_CREAT | O_TRUNC;
|
||||
if (!opt.overwrite)
|
||||
flags |= O_EXCL;
|
||||
}
|
||||
|
||||
if ((fd_out = open(opt.output, flags, S_IRWXU)) == -1)
|
||||
if ((fd_out = open(opt.output, flags, S_IRWXU)) == -1)
|
||||
perr_exit("Opening file '%s' failed", opt.output);
|
||||
|
||||
if (!opt.save_image)
|
||||
|
@ -1451,20 +1451,20 @@ int main(int argc, char **argv)
|
|||
fsync_clone(fd_out);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
setup_lcn_bitmap();
|
||||
memset(&image, 0, sizeof(image));
|
||||
backup_clusters.image = ℑ
|
||||
backup_clusters.image = ℑ
|
||||
|
||||
walk_clusters(vol, &backup_clusters);
|
||||
compare_bitmaps(&lcn_bitmap);
|
||||
print_disk_usage(vol->cluster_size, vol->nr_clusters, image.inuse);
|
||||
|
||||
|
||||
ignore_bad_clusters(&image);
|
||||
|
||||
if (opt.save_image)
|
||||
initialise_image_hdr(device_size, image.inuse);
|
||||
|
||||
|
||||
/* FIXME: save backup boot sector */
|
||||
|
||||
if (opt.std_out || !opt.metadata_only) {
|
||||
|
@ -1477,9 +1477,9 @@ int main(int argc, char **argv)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
wipe = 1;
|
||||
wipe = 1;
|
||||
opt.volume = opt.output;
|
||||
/* 'force' again mount for dirty volumes (e.g. after resize).
|
||||
/* 'force' again mount for dirty volumes (e.g. after resize).
|
||||
FIXME: use mount flags to avoid potential side-effects in future */
|
||||
opt.force++;
|
||||
mount_volume(0);
|
||||
|
@ -1487,26 +1487,26 @@ int main(int argc, char **argv)
|
|||
free(lcn_bitmap.bm);
|
||||
setup_lcn_bitmap();
|
||||
memset(&image, 0, sizeof(image));
|
||||
backup_clusters.image = ℑ
|
||||
backup_clusters.image = ℑ
|
||||
|
||||
walk_clusters(vol, &backup_clusters);
|
||||
|
||||
|
||||
Printf("Num of MFT records = %10lld\n",
|
||||
(long long)vol->mft_na->initialized_size >>
|
||||
vol->mft_record_size_bits);
|
||||
Printf("Num of used MFT records = %10u\n", nr_used_mft_records);
|
||||
|
||||
Printf("Wiped unused MFT data = %10u\n", wiped_unused_mft_data);
|
||||
Printf("Wiped deleted MFT data = %10u\n", wiped_unused_mft);
|
||||
vol->mft_record_size_bits);
|
||||
Printf("Num of used MFT records = %10u\n", nr_used_mft_records);
|
||||
|
||||
Printf("Wiped unused MFT data = %10u\n", wiped_unused_mft_data);
|
||||
Printf("Wiped deleted MFT data = %10u\n", wiped_unused_mft);
|
||||
Printf("Wiped resident user data = %10u\n", wiped_resident_data);
|
||||
Printf("Wiped timestamp data = %10u\n", wiped_timestamp_data);
|
||||
|
||||
|
||||
wiped_total += wiped_unused_mft_data;
|
||||
wiped_total += wiped_unused_mft;
|
||||
wiped_total += wiped_resident_data;
|
||||
wiped_total += wiped_timestamp_data;
|
||||
Printf("Wiped totally = %10u\n", wiped_total);
|
||||
|
||||
|
||||
fsync_clone(fd_out);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -357,7 +357,7 @@ static int info (ntfs_volume *vol)
|
|||
*/
|
||||
static int dump_file (ntfs_volume *vol, ntfs_inode *ino)
|
||||
{
|
||||
u8 buffer[1024];
|
||||
char buffer[1024];
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
ATTR_RECORD *rec;
|
||||
int i;
|
||||
|
|
|
@ -46,8 +46,8 @@ struct options {
|
|||
int force; /* Override common sense */
|
||||
char *filename; /* File to examine */
|
||||
u64 inode; /* Inode to examine */
|
||||
u64 range_begin; /* Look for objects in this range */
|
||||
u64 range_end;
|
||||
s64 range_begin; /* Look for objects in this range */
|
||||
s64 range_end;
|
||||
};
|
||||
|
||||
struct match {
|
||||
|
|
|
@ -115,7 +115,7 @@ static int parse_options (int argc, char **argv)
|
|||
{ "inode", no_argument, NULL, 'i' },
|
||||
{ "force", no_argument, NULL, 'f' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "attr-name", required_argument, NULL, 'N' },
|
||||
{ "attr-name", required_argument, NULL, 'N' },
|
||||
{ "no-action", no_argument, NULL, 'n' },
|
||||
{ "quiet", no_argument, NULL, 'q' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
|
@ -129,7 +129,7 @@ static int parse_options (int argc, char **argv)
|
|||
int ver = 0;
|
||||
int help = 0;
|
||||
s64 attr;
|
||||
|
||||
|
||||
opts.device = NULL;
|
||||
opts.src_file = NULL;
|
||||
opts.dest_file = NULL;
|
||||
|
@ -182,7 +182,7 @@ static int parse_options (int argc, char **argv)
|
|||
Eprintf("You can specify only one attribute "
|
||||
"name.\n");
|
||||
err++;
|
||||
} else
|
||||
} else
|
||||
opts.attr_name = argv[optind - 1];
|
||||
break;
|
||||
case 'n':
|
||||
|
@ -286,7 +286,7 @@ int main (int argc, char *argv[])
|
|||
|
||||
vol = utils_mount_volume(opts.device, flags, opts.force);
|
||||
if (!vol) {
|
||||
perror("ERROR: couldn't mount volume");
|
||||
perror("ERROR: couldn't mount volume");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ int main (int argc, char *argv[])
|
|||
} else
|
||||
out = ntfs_pathname_to_inode(vol, NULL, opts.dest_file);
|
||||
if (!out) {
|
||||
perror("ERROR: Couldn't open destination file");
|
||||
perror("ERROR: Couldn't open destination file");
|
||||
goto close_src;
|
||||
}
|
||||
if ((le16_to_cpu(out->mrec->flags) & MFT_RECORD_IS_DIRECTORY) &&
|
||||
|
@ -362,7 +362,7 @@ int main (int argc, char *argv[])
|
|||
}
|
||||
}
|
||||
|
||||
if (opts.attr_name) {
|
||||
if (opts.attr_name) {
|
||||
attr_name_len = ntfs_mbstoucs(opts.attr_name, &attr_name, 0);
|
||||
if (attr_name_len == -1) {
|
||||
perror("ERROR: Failed to parse attribute name");
|
||||
|
|
|
@ -505,7 +505,7 @@ skip_rstr_pass:
|
|||
++pass;
|
||||
goto rstr_pass_loc;
|
||||
}
|
||||
|
||||
|
||||
return rstr;
|
||||
}
|
||||
|
||||
|
@ -714,7 +714,7 @@ int main(int argc, char **argv)
|
|||
puts("$LogFile is not initialized.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* First, verify the restart page header for consistency.
|
||||
*/
|
||||
|
@ -739,7 +739,7 @@ int main(int argc, char **argv)
|
|||
*/
|
||||
rcrd = (RECORD_PAGE_HEADER*)dump_restart_areas(rstr, buf, page_size);
|
||||
printf("\n\nFinished with restart pages. "
|
||||
"Beginning with log pages.\n");
|
||||
"Beginning with log pages.\n");
|
||||
|
||||
/*
|
||||
* Dump the log areas.
|
||||
|
|
|
@ -91,7 +91,7 @@ static int usage(void)
|
|||
" -h, --help Display this help\n"
|
||||
" -V, --version Display version information\n"
|
||||
"\n"
|
||||
"For example: %s /dev/hda6\n\n",
|
||||
"For example: %s /dev/hda6\n\n",
|
||||
EXEC_NAME, VERSION, EXEC_NAME, EXEC_NAME);
|
||||
printf("%s%s", ntfs_bugs, ntfs_home);
|
||||
exit(1);
|
||||
|
@ -139,7 +139,7 @@ static void parse_options(int argc, char **argv)
|
|||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (opt.volume == NULL) {
|
||||
printf("ERROR: You must specify a device.\n");
|
||||
usage();
|
||||
|
|
|
@ -300,7 +300,7 @@ static char *ntfs_attr_get_name(ATTR_RECORD *attr)
|
|||
ntfschar *ucs_attr_name;
|
||||
char *mbs_attr_name = NULL;
|
||||
int mbs_attr_name_size;
|
||||
|
||||
|
||||
/* calculate name position */
|
||||
ucs_attr_name = (ntfschar *)((char *)attr + le16_to_cpu(attr->name_offset));
|
||||
/* convert unicode to printable format */
|
||||
|
@ -330,7 +330,7 @@ static void ntfs_dump_volume(ntfs_volume *vol)
|
|||
printf("\tCluster Size: %u\n", (unsigned int)vol->cluster_size);
|
||||
printf("\tVolume Size in Clusters: %lld\n",
|
||||
(long long)vol->nr_clusters);
|
||||
|
||||
|
||||
printf("MFT Information \n");
|
||||
printf("\tMFT Record Size: %u\n", (unsigned int)vol->mft_record_size);
|
||||
printf("\tMFT Zone Multiplier: %u\n", vol->mft_zone_multiplier);
|
||||
|
@ -349,7 +349,7 @@ static void ntfs_dump_volume(ntfs_volume *vol)
|
|||
(long long)vol->mftmirr_lcn);
|
||||
printf("\tSize of Attribute Definition Table: %d\n",
|
||||
(int)vol->attrdef_len);
|
||||
|
||||
|
||||
printf("FILE_Bitmap Information \n");
|
||||
printf("\tFILE_Bitmap MFT Record Number: %llu\n",
|
||||
(unsigned long long)vol->lcnbmp_ni->mft_no);
|
||||
|
@ -361,7 +361,7 @@ static void ntfs_dump_volume(ntfs_volume *vol)
|
|||
(int)vol->lcnbmp_ni->nr_extents);
|
||||
/* FIXME: need to add code for the union if nr_extens != 0, but
|
||||
i dont know if it will ever != 0 with FILE_Bitmap */
|
||||
|
||||
|
||||
printf("FILE_Bitmap Data Attribute Information\n");
|
||||
printf("\tDecompressed Runlist: not done yet\n");
|
||||
printf("\tBase Inode: %llu\n",
|
||||
|
@ -385,7 +385,7 @@ static void ntfs_dump_volume(ntfs_volume *vol)
|
|||
vol->lcnbmp_na->compression_block_size_bits);
|
||||
printf("\tCompression Block Clusters: %u\n",
|
||||
vol->lcnbmp_na->compression_block_clusters);
|
||||
|
||||
|
||||
//TODO: Still need to add a few more attributes
|
||||
}
|
||||
|
||||
|
@ -501,7 +501,7 @@ static void ntfs_dump_attr_standard_information(ATTR_RECORD *attr)
|
|||
le16_to_cpu(attr->value_offset));
|
||||
|
||||
printf("Dumping attribute $STANDARD_INFORMATION (0x10)\n");
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
/* let's start with mandatory? fields */
|
||||
|
@ -509,18 +509,18 @@ static void ntfs_dump_attr_standard_information(ATTR_RECORD *attr)
|
|||
/* time conversion stuff */
|
||||
if (!opts.notime) {
|
||||
char *ntfs_time_str = NULL;
|
||||
|
||||
|
||||
ntfs_time_str = ntfsinfo_time_to_str(standard_attr->creation_time);
|
||||
printf("\tFile Creation Time:\t %s",ntfs_time_str);
|
||||
|
||||
|
||||
ntfs_time_str = ntfsinfo_time_to_str(
|
||||
standard_attr->last_data_change_time);
|
||||
printf("\tFile Altered Time:\t %s",ntfs_time_str);
|
||||
|
||||
|
||||
ntfs_time_str = ntfsinfo_time_to_str(
|
||||
standard_attr->last_mft_change_time);
|
||||
printf("\tMFT Changed Time:\t %s",ntfs_time_str);
|
||||
|
||||
|
||||
ntfs_time_str = ntfsinfo_time_to_str(standard_attr->last_access_time);
|
||||
printf("\tLast Accessed Time:\t %s",ntfs_time_str);
|
||||
}
|
||||
|
@ -532,7 +532,7 @@ static void ntfs_dump_attr_standard_information(ATTR_RECORD *attr)
|
|||
(unsigned int)le32_to_cpu(standard_attr->version_number));
|
||||
printf("\tClass ID:\t\t %u \n",
|
||||
(unsigned int)le32_to_cpu(standard_attr->class_id));
|
||||
|
||||
|
||||
value_length = le32_to_cpu(attr->value_length);
|
||||
if (value_length == 48) {
|
||||
/* printf("\t$STANDARD_INFORMATION fields owner_id, security_id, quota \n"
|
||||
|
@ -559,7 +559,7 @@ static void ntfs_dump_attr_list(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
s64 l;
|
||||
|
||||
printf("Dumping attribute AT_ATTRIBUTE_LIST (0x20)\n");
|
||||
|
||||
|
||||
/* Dump list's name */
|
||||
if (attr->name_length) {
|
||||
char *stream_name = NULL;
|
||||
|
@ -576,7 +576,7 @@ static void ntfs_dump_attr_list(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
} else {
|
||||
printf("\tList name:\t\t unnamed\n");
|
||||
}
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
/* Dump list's size */
|
||||
|
@ -592,10 +592,10 @@ static void ntfs_dump_attr_list(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
printf("\tList's size:\t\t %u bytes\n",
|
||||
(unsigned int)le32_to_cpu(attr->value_length));
|
||||
}
|
||||
|
||||
|
||||
if (!opts.verbose)
|
||||
return;
|
||||
|
||||
|
||||
l = ntfs_get_attribute_value_length(attr);
|
||||
if (!l) {
|
||||
perror("ntfs_get_attribute_value_length failed");
|
||||
|
@ -659,7 +659,7 @@ static void ntfs_dump_attr_file_name(ATTR_RECORD *attr)
|
|||
le16_to_cpu(attr->value_offset));
|
||||
|
||||
printf("Dumping attribute $FILE_NAME (0x30)\n");
|
||||
|
||||
|
||||
/* let's start with the obvious - file name */
|
||||
|
||||
if (file_name_attr->file_name_length>0) {
|
||||
|
@ -688,7 +688,7 @@ static void ntfs_dump_attr_file_name(ATTR_RECORD *attr)
|
|||
ntfs_dump_namespace(file_name_attr->file_name_type);
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
|
||||
/* other basic stuff about the file */
|
||||
printf("\tAllocated File Size:\t %lld\n",
|
||||
(long long)sle64_to_cpu(file_name_attr->allocated_size));
|
||||
|
@ -701,7 +701,7 @@ static void ntfs_dump_attr_file_name(ATTR_RECORD *attr)
|
|||
/* time stuff stuff */
|
||||
if (!opts.notime) {
|
||||
char *ntfs_time_str;
|
||||
|
||||
|
||||
ntfs_time_str = ntfsinfo_time_to_str(file_name_attr->creation_time);
|
||||
printf("\tFile Creation Time:\t %s",ntfs_time_str);
|
||||
|
||||
|
@ -731,7 +731,7 @@ static void ntfs_dump_attr_object_id(ATTR_RECORD *attr,ntfs_volume *vol)
|
|||
le16_to_cpu(attr->value_offset));
|
||||
|
||||
printf("Dumping attribute $OBJECT_ID (0x40)\n");
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
if (vol->major_ver >= 3.0) {
|
||||
|
@ -786,7 +786,7 @@ static void ntfs_dump_acl(const char *prefix,ACL *acl)
|
|||
unsigned int i;
|
||||
u16 ace_count;
|
||||
ACCESS_ALLOWED_ACE *ace;
|
||||
|
||||
|
||||
printf("%sRevision\t %u\n",prefix,acl->revision);
|
||||
|
||||
/* don't recalc le16_to_cpu every iteration (minor speedup on big-endians */
|
||||
|
@ -799,7 +799,7 @@ static void ntfs_dump_acl(const char *prefix,ACL *acl)
|
|||
for (i=0;i<acl->ace_count;i++) {
|
||||
const char *ace_type;
|
||||
char *sid;
|
||||
|
||||
|
||||
/* set ace_type. */
|
||||
switch (ace->type) {
|
||||
case ACCESS_ALLOWED_ACE_TYPE:
|
||||
|
@ -815,7 +815,7 @@ static void ntfs_dump_acl(const char *prefix,ACL *acl)
|
|||
ace_type = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
printf("%sACE:\t\t type:%s flags:0x%x access:0x%x\n",prefix,ace_type,
|
||||
(unsigned int)le16_to_cpu(ace->flags),(unsigned int)le32_to_cpu(ace->mask));
|
||||
/* get a SID string */
|
||||
|
@ -823,7 +823,7 @@ static void ntfs_dump_acl(const char *prefix,ACL *acl)
|
|||
printf("%s\t\t SID: %s\n",prefix,sid);
|
||||
if (sid)
|
||||
free(sid);
|
||||
|
||||
|
||||
/* proceed to next ACE */
|
||||
ace = (ACCESS_ALLOWED_ACE *)(((char *)ace) + le32_to_cpu(ace->size));
|
||||
}
|
||||
|
@ -838,9 +838,9 @@ static void ntfs_dump_attr_security_descriptor(ATTR_RECORD *attr, ntfs_volume *v
|
|||
{
|
||||
SECURITY_DESCRIPTOR_ATTR *sec_desc_attr;
|
||||
char *sid;
|
||||
|
||||
|
||||
printf("Dumping attribute $SECURITY_DESCRIPTOR (0x50)\n");
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
if (attr->non_resident) {
|
||||
|
@ -895,7 +895,7 @@ static void ntfs_dump_attr_security_descriptor(ATTR_RECORD *attr, ntfs_volume *v
|
|||
} else {
|
||||
printf("missing\n");
|
||||
}
|
||||
|
||||
|
||||
printf("\tDiscretionary ACL:\t\t ");
|
||||
if (sec_desc_attr->control & SE_DACL_PRESENT) {
|
||||
if (sec_desc_attr->control & SE_SACL_DEFAULTED) {
|
||||
|
@ -907,7 +907,7 @@ static void ntfs_dump_attr_security_descriptor(ATTR_RECORD *attr, ntfs_volume *v
|
|||
} else {
|
||||
printf("missing\n");
|
||||
}
|
||||
|
||||
|
||||
if (attr->non_resident) free(sec_desc_attr);
|
||||
}
|
||||
|
||||
|
@ -921,7 +921,7 @@ static void ntfs_dump_attr_volume_name(ATTR_RECORD *attr)
|
|||
ntfschar *ucs_vol_name = NULL;
|
||||
|
||||
printf("Dumping attribute $VOLUME_NAME (0x60)\n");
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
if (attr->value_length>0) {
|
||||
|
@ -958,12 +958,12 @@ static void ntfs_dump_attr_volume_name(ATTR_RECORD *attr)
|
|||
static void ntfs_dump_attr_volume_information(ATTR_RECORD *attr)
|
||||
{
|
||||
VOLUME_INFORMATION *vol_information = NULL;
|
||||
|
||||
|
||||
vol_information = (VOLUME_INFORMATION*)((char *)attr+
|
||||
le16_to_cpu(attr->value_offset));
|
||||
|
||||
printf("Dumping attribute $VOLUME_INFORMATION (0x70)\n");
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
printf("\tVolume Version:\t %d.%d\n", vol_information->major_ver,
|
||||
|
@ -1018,12 +1018,12 @@ static void ntfs_dump_attr_data(ATTR_RECORD *attr, ntfs_volume *vol)
|
|||
} else {
|
||||
printf("\tStream name:\t\t unnamed\n");
|
||||
}
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
/* TODO: parse the flags */
|
||||
printf("\tFlags:\t\t\t 0x%04hx\n",le16_to_cpu(attr->flags));
|
||||
|
||||
|
||||
/* fork by residence */
|
||||
if (attr->non_resident) {
|
||||
/* VCN lowest_vcn; Lowest valid virtual cluster number
|
||||
|
@ -1079,7 +1079,7 @@ static int ntfs_dump_index_entries(INDEX_ENTRY *entry, ATTR_TYPES type)
|
|||
{
|
||||
int numb_entries = 1;
|
||||
char *name = NULL;
|
||||
|
||||
|
||||
Vprintf("\tDumping index entries:");
|
||||
while(1) {
|
||||
if (!opts.verbose) {
|
||||
|
@ -1099,7 +1099,7 @@ static int ntfs_dump_index_entries(INDEX_ENTRY *entry, ATTR_TYPES type)
|
|||
|
||||
if (entry->flags & INDEX_ENTRY_END)
|
||||
break;
|
||||
|
||||
|
||||
switch(type) {
|
||||
case(AT_FILE_NAME):
|
||||
Vprintf("\t\tFILE record number:\t %llu\n",
|
||||
|
@ -1154,16 +1154,16 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
|
|||
unsigned int type;
|
||||
INDEX_ROOT *index_root = NULL;
|
||||
INDEX_ENTRY *entry;
|
||||
|
||||
|
||||
index_root = (INDEX_ROOT*)((u8*)attr + le16_to_cpu(attr->value_offset));
|
||||
|
||||
|
||||
printf("Dumping attribute $INDEX_ROOT (0x90)\n");
|
||||
|
||||
|
||||
/* Dump index name */
|
||||
if (attr->name_length) {
|
||||
char *index_name = NULL;
|
||||
index_name = ntfs_attr_get_name(attr);
|
||||
|
||||
|
||||
if (index_name) {
|
||||
printf("\tIndex name:\t\t '%s'\n",index_name);
|
||||
free(index_name);
|
||||
|
@ -1175,7 +1175,7 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
|
|||
} else {
|
||||
printf("\tIndex name:\t\t unnamed\n");
|
||||
}
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
/* attr_type dumping */
|
||||
|
@ -1206,7 +1206,7 @@ static void ntfs_dump_attr_index_root(ATTR_RECORD *attr)
|
|||
(unsigned int)le32_to_cpu(index_root->index_block_size));
|
||||
printf("\tClusters Per Block:\t %u\n",
|
||||
index_root->clusters_per_index_block);
|
||||
|
||||
|
||||
/* index header starts here */
|
||||
printf("\tAllocated Size:\t\t %u\n",
|
||||
(unsigned int)le32_to_cpu(index_root->index.allocated_size));
|
||||
|
@ -1233,14 +1233,14 @@ static int get_type_and_size_of_indx(ntfs_inode *ni, ATTR_RECORD *attr,
|
|||
ntfs_attr_search_ctx *ctx;
|
||||
ntfschar *name = 0;
|
||||
INDEX_ROOT *root;
|
||||
|
||||
|
||||
if (attr->name_length) {
|
||||
name = malloc(attr->name_length * sizeof(ntfschar));
|
||||
if (!name) {
|
||||
perror("malloc failed");
|
||||
return -1;
|
||||
}
|
||||
memcpy(name, (u8 *)attr + attr->name_offset,
|
||||
memcpy(name, (u8 *)attr + attr->name_offset,
|
||||
attr->name_length * sizeof(ntfschar));
|
||||
}
|
||||
ctx = ntfs_attr_get_search_ctx(ni, 0);
|
||||
|
@ -1256,7 +1256,7 @@ static int get_type_and_size_of_indx(ntfs_inode *ni, ATTR_RECORD *attr,
|
|||
free(name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
root = (INDEX_ROOT*)((u8*)ctx->attr +
|
||||
le16_to_cpu(ctx->attr->value_offset));
|
||||
*size = le32_to_cpu(root->index_block_size);
|
||||
|
@ -1305,7 +1305,7 @@ static void ntfs_dump_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
|
|||
}
|
||||
ntfs_attr_close(na);
|
||||
byte = bitmap;
|
||||
|
||||
|
||||
na = ntfs_attr_open(ni, AT_INDEX_ALLOCATION, name, attr->name_length);
|
||||
if (!na) {
|
||||
perror("ntfs_attr_open failed");
|
||||
|
@ -1327,7 +1327,7 @@ static void ntfs_dump_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
|
|||
}
|
||||
ntfs_attr_close(na);
|
||||
tmp_alloc = allocation;
|
||||
|
||||
|
||||
bit = 0;
|
||||
while((u8 *)tmp_alloc < (u8 *)allocation + na->data_size) {
|
||||
if (*byte & (1 << bit)) {
|
||||
|
@ -1369,7 +1369,7 @@ static void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
|
|||
if (attr->name_length) {
|
||||
char *index_name = NULL;
|
||||
index_name = ntfs_attr_get_name(attr);
|
||||
|
||||
|
||||
if (index_name) {
|
||||
printf("\tIndex name:\t\t '%s'\n",index_name);
|
||||
free(index_name);
|
||||
|
@ -1398,7 +1398,7 @@ static void ntfs_dump_attr_index_allocation(ATTR_RECORD *attr, ntfs_inode *ni)
|
|||
Eprintf("Invalid $INDEX_ALLOCTION attribute. Should be be"
|
||||
" non-resident\n");
|
||||
}
|
||||
|
||||
|
||||
ntfs_dump_index_allocation(attr, ni);
|
||||
}
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ static void ntfs_dump_attr_bitmap(ATTR_RECORD *attr)
|
|||
if (attr->name_length) {
|
||||
char *bitmap_name = NULL;
|
||||
bitmap_name = ntfs_attr_get_name(attr);
|
||||
|
||||
|
||||
if (bitmap_name) {
|
||||
printf("\tBitmap name:\t\t '%s'\n",bitmap_name);
|
||||
free(bitmap_name);
|
||||
|
@ -1427,7 +1427,7 @@ static void ntfs_dump_attr_bitmap(ATTR_RECORD *attr)
|
|||
} else {
|
||||
printf("\tBitmap name:\t\t unnamed\n");
|
||||
}
|
||||
|
||||
|
||||
printf("\tAttribute instance:\t %u\n", le16_to_cpu(attr->instance));
|
||||
|
||||
/* dump bitmap size */
|
||||
|
@ -1518,12 +1518,12 @@ static void ntfs_hex_dump(void *buf,unsigned int length)
|
|||
unsigned char c = *((char *)buf + j);
|
||||
printf("%02hhX ",c);
|
||||
}
|
||||
|
||||
|
||||
/* realign */
|
||||
for (;j<i+16;j++) {
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
|
||||
/* char content */
|
||||
for (j=i;(j<length) && (j<i+16);j++) {
|
||||
unsigned char c = *((char *)buf + j);
|
||||
|
@ -1533,7 +1533,7 @@ static void ntfs_hex_dump(void *buf,unsigned int length)
|
|||
}
|
||||
printf("%c",c);
|
||||
}
|
||||
|
||||
|
||||
/* end line */
|
||||
printf("\n");
|
||||
i=j;
|
||||
|
@ -1617,9 +1617,9 @@ static void ntfs_dump_attr_unknown(ATTR_RECORD *attr)
|
|||
static void ntfs_dump_inode_general_info(ntfs_inode *inode)
|
||||
{
|
||||
u16 inode_flags = inode->mrec->flags;
|
||||
|
||||
|
||||
printf("Dumping Inode #%llu\n",(long long)inode->mft_no);
|
||||
|
||||
|
||||
printf("Update Sequence Array Count:\t %hu\n",
|
||||
le16_to_cpu(inode->mrec->usa_count));
|
||||
printf("$LogFile seqNum for this Inode:\t 0x%llx\n",
|
||||
|
@ -1649,7 +1649,7 @@ static void ntfs_dump_inode_general_info(ntfs_inode *inode)
|
|||
(unsigned int)le32_to_cpu(inode->mrec->bytes_in_use));
|
||||
printf("Size - Allocated:\t\t %u bytes\n",
|
||||
(unsigned int)le32_to_cpu(inode->mrec->bytes_allocated));
|
||||
|
||||
|
||||
if (inode->mrec->base_mft_record) {
|
||||
printf("base MFT record:\t\t %llu\n",
|
||||
MREF_LE(inode->mrec->base_mft_record));
|
||||
|
@ -1729,7 +1729,7 @@ static void ntfs_dump_file_attributes(ntfs_inode *inode)
|
|||
ntfs_dump_attr_unknown(ctx->attr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* if we exited the loop before we're done - notify the user */
|
||||
if (errno != ENOENT) {
|
||||
fprintf(stderr, "ntfsinfo error: stopped before finished "
|
||||
|
@ -1741,7 +1741,7 @@ static void ntfs_dump_file_attributes(ntfs_inode *inode)
|
|||
/* close all data-structures we used */
|
||||
ntfs_attr_put_search_ctx(ctx);
|
||||
ntfs_inode_close(inode);
|
||||
|
||||
|
||||
/* happily exit */
|
||||
}
|
||||
|
||||
|
|
|
@ -365,7 +365,8 @@ static void dump_runs (u8 *buffer, int len)
|
|||
/**
|
||||
* find_unused
|
||||
*/
|
||||
static runlist * find_unused (ntfs_volume *vol, s64 size, u64 loc, int flags)
|
||||
static runlist * find_unused (ntfs_volume *vol, s64 size, u64 loc
|
||||
__attribute__((unused)), int flags __attribute__((unused)))
|
||||
{
|
||||
const int bufsize = 8192;
|
||||
u8 *buffer;
|
||||
|
@ -703,7 +704,7 @@ static s64 move_datarun (ntfs_volume *vol, ntfs_inode *ino, ATTR_RECORD *rec,
|
|||
Eprintf ("!move_runlist\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// wipe orig runs
|
||||
memset (((u8*)rec) +rec->mapping_pairs_offset, 0, need_to - rec->mapping_pairs_offset);
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ struct progress_bar {
|
|||
struct llcn_t {
|
||||
s64 lcn; /* last used LCN for a "special" file/attr type */
|
||||
s64 inode; /* inode using it */
|
||||
};
|
||||
};
|
||||
|
||||
#define NTFSCK_PROGBAR 0x0001
|
||||
|
||||
|
@ -508,7 +508,7 @@ static int parse_options(int argc, char **argv)
|
|||
static void print_advise(ntfs_volume *vol, s64 supp_lcn)
|
||||
{
|
||||
s64 old_b, new_b, freed_b, old_mb, new_mb, freed_mb;
|
||||
|
||||
|
||||
old_b = vol->nr_clusters * vol->cluster_size;
|
||||
old_mb = rounded_up_division(old_b, NTFS_MBYTE);
|
||||
|
||||
|
@ -539,7 +539,7 @@ static void print_advise(ntfs_volume *vol, s64 supp_lcn)
|
|||
else
|
||||
printf("%lld bytes", (long long)freed_b);
|
||||
printf(").\n");
|
||||
|
||||
|
||||
printf("Please make a test run using both the -n and -s options "
|
||||
"before real resizing!\n");
|
||||
}
|
||||
|
@ -554,10 +554,10 @@ static void rl_set(runlist *rl, VCN vcn, LCN lcn, s64 len)
|
|||
static int rl_items(runlist *rl)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
|
||||
while (rl[i++].length)
|
||||
;
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -599,7 +599,7 @@ static int str2unicode(const char *aname, ntfschar **ustr, int *len)
|
|||
*ustr = AT_UNNAMED;
|
||||
*len = 0;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -608,7 +608,7 @@ static int has_bad_sectors(ntfs_resize_t *resize)
|
|||
int len, ret = 0;
|
||||
ntfschar *ustr = NULL;
|
||||
ATTR_RECORD *a = resize->ctx->attr;
|
||||
|
||||
|
||||
if (resize->ni->mft_no != FILE_BadClus)
|
||||
return 0;
|
||||
|
||||
|
@ -617,13 +617,13 @@ static int has_bad_sectors(ntfs_resize_t *resize)
|
|||
|
||||
if (ustr && ntfs_names_are_equal(ustr, len,
|
||||
(ntfschar*)((u8*)a + le16_to_cpu(a->name_offset)),
|
||||
a->name_length, 0, NULL, 0))
|
||||
a->name_length, 0, NULL, 0))
|
||||
ret = 1;
|
||||
|
||||
|
||||
if (ustr != AT_UNNAMED)
|
||||
free(ustr);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void collect_resize_constraints(ntfs_resize_t *resize, runlist *rl)
|
||||
|
@ -637,35 +637,35 @@ static void collect_resize_constraints(ntfs_resize_t *resize, runlist *rl)
|
|||
|
||||
inode = resize->ni->mft_no;
|
||||
flags = resize->ctx->attr->flags;
|
||||
|
||||
|
||||
if ((ret = has_bad_sectors(resize)) != 0) {
|
||||
if (ret == -1)
|
||||
perr_exit("Couldn't convert string to Unicode");
|
||||
err_exit("Your disk has bad sectors (manufacturing faults or "
|
||||
"dying disk).\nThis situation isn't supported yet.\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (NInoAttrList(resize->ni)) {
|
||||
llcn = &resize->last_multi_mft;
|
||||
|
||||
if (inode != FILE_MFT && inode != FILE_MFTMirr)
|
||||
supported = 1;
|
||||
|
||||
|
||||
} else if (flags & ATTR_IS_SPARSE) {
|
||||
llcn = &resize->last_sparse;
|
||||
supported = 1;
|
||||
|
||||
|
||||
} else if (flags & ATTR_IS_COMPRESSED) {
|
||||
llcn = &resize->last_compressed;
|
||||
supported = 1;
|
||||
|
||||
|
||||
} else if (inode == FILE_MFT) {
|
||||
llcn = &resize->last_mft;
|
||||
|
||||
/* First run of $MFT DATA attribute isn't supported yet */
|
||||
if (resize->ctx->attr->type != AT_DATA || rl->vcn)
|
||||
supported = 1;
|
||||
|
||||
|
||||
} else if (inode == FILE_MFTMirr) {
|
||||
llcn = &resize->last_mftmir;
|
||||
supported = 1;
|
||||
|
@ -678,11 +678,11 @@ static void collect_resize_constraints(ntfs_resize_t *resize, runlist *rl)
|
|||
llcn = &resize->last_lcn;
|
||||
supported = 1;
|
||||
}
|
||||
|
||||
|
||||
if (llcn->lcn < last_lcn) {
|
||||
llcn->lcn = last_lcn;
|
||||
llcn->inode = inode;
|
||||
}
|
||||
}
|
||||
|
||||
if (supported)
|
||||
return;
|
||||
|
@ -696,12 +696,12 @@ static void collect_relocation_info(ntfs_resize_t *resize, runlist *rl)
|
|||
{
|
||||
s64 lcn, lcn_length, start, len, inode;
|
||||
s64 new_vol_size; /* (last LCN on the volume) + 1 */
|
||||
|
||||
|
||||
lcn = rl->lcn;
|
||||
lcn_length = rl->length;
|
||||
inode = resize->ni->mft_no;
|
||||
new_vol_size = resize->new_volume_size;
|
||||
|
||||
|
||||
if (lcn + lcn_length <= new_vol_size)
|
||||
return;
|
||||
|
||||
|
@ -727,7 +727,7 @@ static void collect_relocation_info(ntfs_resize_t *resize, runlist *rl)
|
|||
|
||||
if (!opt.info || !resize->new_volume_size)
|
||||
return;
|
||||
|
||||
|
||||
printf("Relocation needed for inode %8lld attr 0x%x LCN 0x%08llx "
|
||||
"length %6lld\n", (long long)inode,
|
||||
(unsigned int)le32_to_cpu(resize->ctx->attr->type),
|
||||
|
@ -764,7 +764,7 @@ static void build_lcn_usage_bitmap(ntfs_volume *vol, ntfsck_t *fsck)
|
|||
printf(corrupt_volume_msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (i = 0; rl[i].length; i++) {
|
||||
s64 lcn = rl[i].lcn;
|
||||
|
@ -788,7 +788,7 @@ static void build_lcn_usage_bitmap(ntfs_volume *vol, ntfsck_t *fsck)
|
|||
if (k >= (u64)vol->nr_clusters) {
|
||||
|
||||
long long outsiders = lcn_length - j;
|
||||
|
||||
|
||||
fsck->outsider += outsiders;
|
||||
|
||||
if (++fsck->show_outsider <= 10 || opt.verbose)
|
||||
|
@ -802,7 +802,7 @@ static void build_lcn_usage_bitmap(ntfs_volume *vol, ntfsck_t *fsck)
|
|||
if (ntfs_bit_get_and_set(lcn_bitmap->bm, k, 1)) {
|
||||
if (++fsck->multi_ref <= 10 || opt.verbose)
|
||||
printf("Cluster %lld is referenced "
|
||||
"multiply times!\n",
|
||||
"multiply times!\n",
|
||||
(long long)k);
|
||||
continue;
|
||||
}
|
||||
|
@ -879,7 +879,7 @@ static void compare_bitmaps(ntfs_volume *vol, struct bitmap *a)
|
|||
pos + count, a->size);
|
||||
|
||||
for (i = 0; i < count; i++, pos++) {
|
||||
s64 cl; /* current cluster */
|
||||
s64 cl; /* current cluster */
|
||||
|
||||
if (a->bm[pos] == bm[i])
|
||||
continue;
|
||||
|
@ -891,14 +891,14 @@ static void compare_bitmaps(ntfs_volume *vol, struct bitmap *a)
|
|||
if (bit == ntfs_bit_get(bm, i * 8 + cl % 8))
|
||||
continue;
|
||||
|
||||
if (!mismatch && !bit && !backup_boot &&
|
||||
if (!mismatch && !bit && !backup_boot &&
|
||||
cl == vol->nr_clusters / 2) {
|
||||
/* FIXME: call also boot sector check */
|
||||
backup_boot = 1;
|
||||
printf("Found backup boot sector in "
|
||||
"the middle of the volume.\n");
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (++mismatch > 10)
|
||||
continue;
|
||||
|
@ -942,12 +942,12 @@ static void progress_init(struct progress_bar *p, u64 start, u64 stop, int flags
|
|||
static void progress_update(struct progress_bar *p, u64 current)
|
||||
{
|
||||
float percent;
|
||||
|
||||
|
||||
if (!(p->flags & NTFS_PROGBAR))
|
||||
return;
|
||||
if (p->flags & NTFS_PROGBAR_SUPPRESS)
|
||||
return;
|
||||
|
||||
|
||||
/* WARNING: don't modify the texts, external tools grep for them */
|
||||
percent = p->unit * current;
|
||||
if (current != p->stop) {
|
||||
|
@ -1028,7 +1028,7 @@ static void build_resize_constrains(ntfs_resize_t *resize)
|
|||
if (!resize->ctx->attr->non_resident)
|
||||
return;
|
||||
|
||||
if (!(rl = ntfs_mapping_pairs_decompress(resize->vol,
|
||||
if (!(rl = ntfs_mapping_pairs_decompress(resize->vol,
|
||||
resize->ctx->attr, NULL)))
|
||||
perr_exit("ntfs_decompress_mapping_pairs");
|
||||
|
||||
|
@ -1036,7 +1036,7 @@ static void build_resize_constrains(ntfs_resize_t *resize)
|
|||
/* CHECKME: LCN_RL_NOT_MAPPED check isn't needed */
|
||||
if (rl[i].lcn == LCN_HOLE || rl[i].lcn == LCN_RL_NOT_MAPPED)
|
||||
continue;
|
||||
|
||||
|
||||
collect_resize_constraints(resize, rl + i);
|
||||
if (resize->shrink)
|
||||
collect_relocation_info(resize, rl + i);
|
||||
|
@ -1117,19 +1117,19 @@ static void rl_fixup(runlist **rl)
|
|||
}
|
||||
}
|
||||
|
||||
static void replace_attribute_runlist(ntfs_volume *vol,
|
||||
ntfs_attr_search_ctx *ctx,
|
||||
static void replace_attribute_runlist(ntfs_volume *vol,
|
||||
ntfs_attr_search_ctx *ctx,
|
||||
runlist *rl)
|
||||
{
|
||||
int mp_size, l;
|
||||
void *mp;
|
||||
ATTR_RECORD *a = ctx->attr;
|
||||
|
||||
|
||||
rl_fixup(&rl);
|
||||
|
||||
if ((mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0)) == -1)
|
||||
perr_exit("ntfs_get_size_for_mapping_pairs");
|
||||
|
||||
|
||||
if (a->name_length) {
|
||||
u16 name_offs = le16_to_cpu(a->name_offset);
|
||||
u16 mp_offs = le16_to_cpu(a->mapping_pairs_offset);
|
||||
|
@ -1147,17 +1147,17 @@ static void replace_attribute_runlist(ntfs_volume *vol,
|
|||
char *next_attr;
|
||||
|
||||
Vprintf("Enlarging attribute header ...\n");
|
||||
|
||||
|
||||
mp_size = (mp_size + 7) & ~7;
|
||||
|
||||
|
||||
Vprintf("Old mp size : %d\n", l);
|
||||
Vprintf("New mp size : %d\n", mp_size);
|
||||
Vprintf("Bytes in use : %u\n", (unsigned int)
|
||||
le32_to_cpu(ctx->mrec->bytes_in_use));
|
||||
|
||||
|
||||
next_attr = (char *)a + le16_to_cpu(a->length);
|
||||
l = mp_size - l;
|
||||
|
||||
|
||||
Vprintf("Bytes in use new : %u\n", l + (unsigned int)
|
||||
le32_to_cpu(ctx->mrec->bytes_in_use));
|
||||
Vprintf("Bytes allocated : %u\n", (unsigned int)
|
||||
|
@ -1168,7 +1168,7 @@ static void replace_attribute_runlist(ntfs_volume *vol,
|
|||
|
||||
Vprintf("increase : %d\n", l);
|
||||
Vprintf("shift : %lld\n", (long long)remains_size);
|
||||
|
||||
|
||||
if (le32_to_cpu(ctx->mrec->bytes_in_use) + l >
|
||||
le32_to_cpu(ctx->mrec->bytes_allocated))
|
||||
err_exit("Extended record needed (%u > %u), not yet "
|
||||
|
@ -1221,9 +1221,9 @@ static void set_max_free_zone(s64 length, s64 end, runlist_element *rle)
|
|||
}
|
||||
}
|
||||
|
||||
static int find_free_cluster(struct bitmap *bm,
|
||||
static int find_free_cluster(struct bitmap *bm,
|
||||
runlist_element *rle,
|
||||
s64 nr_vol_clusters,
|
||||
s64 nr_vol_clusters,
|
||||
int hint)
|
||||
{
|
||||
/* FIXME: get rid of this 'static' variable */
|
||||
|
@ -1278,9 +1278,9 @@ static int find_free_cluster(struct bitmap *bm,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static runlist *alloc_cluster(struct bitmap *bm,
|
||||
s64 items,
|
||||
s64 nr_vol_clusters,
|
||||
static runlist *alloc_cluster(struct bitmap *bm,
|
||||
s64 items,
|
||||
s64 nr_vol_clusters,
|
||||
int hint)
|
||||
{
|
||||
runlist_element rle;
|
||||
|
@ -1300,7 +1300,7 @@ static runlist *alloc_cluster(struct bitmap *bm,
|
|||
rle.length = items;
|
||||
if (find_free_cluster(bm, &rle, nr_vol_clusters, hint) == -1)
|
||||
return NULL;
|
||||
|
||||
|
||||
rl_size = (runs + 2) * sizeof(runlist_element);
|
||||
if (!(rl = (runlist *)realloc(rl, rl_size)))
|
||||
return NULL;
|
||||
|
@ -1313,7 +1313,7 @@ static runlist *alloc_cluster(struct bitmap *bm,
|
|||
}
|
||||
|
||||
rl_set(rl + runs, vcn, -1LL, 0LL);
|
||||
|
||||
|
||||
if (runs > 1) {
|
||||
Vprintf("Multi-run allocation: \n");
|
||||
dump_runlist(rl);
|
||||
|
@ -1324,9 +1324,9 @@ static runlist *alloc_cluster(struct bitmap *bm,
|
|||
static int read_all(struct ntfs_device *dev, void *buf, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
while (count > 0) {
|
||||
|
||||
|
||||
i = count;
|
||||
if (!NDevReadOnly(dev))
|
||||
i = dev->d_ops->read(dev, buf, count);
|
||||
|
@ -1346,7 +1346,7 @@ static int read_all(struct ntfs_device *dev, void *buf, int count)
|
|||
static int write_all(struct ntfs_device *dev, void *buf, int count)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
while (count > 0) {
|
||||
|
||||
i = count;
|
||||
|
@ -1384,9 +1384,9 @@ static int write_mft_record(ntfs_volume *v, const MFT_REF mref, MFT_RECORD *buf)
|
|||
static void lseek_to_cluster(ntfs_volume *vol, s64 lcn)
|
||||
{
|
||||
off_t pos;
|
||||
|
||||
|
||||
pos = (off_t)(lcn * vol->cluster_size);
|
||||
|
||||
|
||||
if (vol->dev->d_ops->seek(vol->dev, pos, SEEK_SET) == (off_t)-1)
|
||||
perr_exit("seek failed to position %lld", lcn);
|
||||
}
|
||||
|
@ -1400,15 +1400,15 @@ static void copy_clusters(ntfs_resize_t *resize, s64 dest, s64 src, s64 len)
|
|||
for (i = 0; i < len; i++) {
|
||||
|
||||
lseek_to_cluster(vol, src + i);
|
||||
|
||||
|
||||
if (read_all(vol->dev, buff, vol->cluster_size) == -1)
|
||||
perr_exit("read_all");
|
||||
|
||||
|
||||
lseek_to_cluster(vol, dest + i);
|
||||
|
||||
|
||||
if (write_all(vol->dev, buff, vol->cluster_size) == -1)
|
||||
perr_exit("write_all");
|
||||
|
||||
|
||||
resize->relocations++;
|
||||
progress_update(&resize->progress, resize->relocations);
|
||||
}
|
||||
|
@ -1429,13 +1429,13 @@ static void relocate_clusters(ntfs_resize_t *r, runlist *dest_rl, s64 src_lcn)
|
|||
for (; dest_rl->length; src_lcn += dest_rl->length, dest_rl++)
|
||||
copy_clusters(r, dest_rl->lcn, src_lcn, dest_rl->length);
|
||||
}
|
||||
|
||||
|
||||
static void rl_split_run(runlist **rl, int run, s64 pos)
|
||||
{
|
||||
runlist *rl_new, *rle_new, *rle;
|
||||
int items, new_size, size_head, size_tail;
|
||||
s64 len_head, len_tail;
|
||||
|
||||
|
||||
items = rl_items(*rl);
|
||||
new_size = (items + 1) * sizeof(runlist_element);
|
||||
size_head = run * sizeof(runlist_element);
|
||||
|
@ -1452,10 +1452,10 @@ static void rl_split_run(runlist **rl, int run, s64 pos)
|
|||
|
||||
len_tail = rle->length - (pos - rle->lcn);
|
||||
len_head = rle->length - len_tail;
|
||||
|
||||
|
||||
rl_set(rle_new, rle->vcn, rle->lcn, len_head);
|
||||
rl_set(rle_new + 1, rle->vcn + len_head, rle->lcn + len_head, len_tail);
|
||||
|
||||
|
||||
Vprintf("Splitting run at cluster %lld:\n", (long long)pos);
|
||||
dump_run(rle); dump_run(rle_new); dump_run(rle_new + 1);
|
||||
|
||||
|
@ -1503,7 +1503,7 @@ static void relocate_run(ntfs_resize_t *resize, runlist **rl, int run)
|
|||
lcn = (*rl + run)->lcn;
|
||||
lcn_length = (*rl + run)->length;
|
||||
new_vol_size = resize->new_volume_size;
|
||||
|
||||
|
||||
if (lcn + lcn_length <= new_vol_size)
|
||||
return;
|
||||
|
||||
|
@ -1513,11 +1513,11 @@ static void relocate_run(ntfs_resize_t *resize, runlist **rl, int run)
|
|||
}
|
||||
|
||||
hint = (resize->mref == FILE_MFTMirr) ? 1 : 0;
|
||||
if (!(relocate_rl = alloc_cluster(&resize->lcn_bitmap, lcn_length,
|
||||
if (!(relocate_rl = alloc_cluster(&resize->lcn_bitmap, lcn_length,
|
||||
new_vol_size, hint)))
|
||||
perr_exit("Cluster allocation failed for %llu:%lld",
|
||||
resize->mref, lcn_length);
|
||||
|
||||
|
||||
/* FIXME: check $MFTMirr DATA isn't multi-run (or support it) */
|
||||
Vprintf("Relocate inode %7llu:0x%x:%08lld:0x%08llx --> 0x%08llx\n",
|
||||
(unsigned long long)resize->mref,
|
||||
|
@ -1620,10 +1620,10 @@ static void relocate_inodes(ntfs_resize_t *resize)
|
|||
MFT_REF mref;
|
||||
|
||||
printf("Relocating needed data ...\n");
|
||||
|
||||
|
||||
progress_init(&resize->progress, 0, resize->relocations, resize->progress.flags);
|
||||
resize->relocations = 0;
|
||||
|
||||
|
||||
resize->mrec = (MFT_RECORD *)malloc(resize->vol->mft_record_size);
|
||||
if (!resize->mrec)
|
||||
perr_exit("malloc failed");
|
||||
|
@ -1643,10 +1643,10 @@ static void relocate_inodes(ntfs_resize_t *resize)
|
|||
static void print_hint(ntfs_volume *vol, const char *s, struct llcn_t llcn)
|
||||
{
|
||||
s64 runs_b, runs_mb;
|
||||
|
||||
|
||||
if (llcn.lcn == 0)
|
||||
return;
|
||||
|
||||
|
||||
runs_b = llcn.lcn * vol->cluster_size;
|
||||
runs_mb = rounded_up_division(runs_b, NTFS_MBYTE);
|
||||
printf("%-19s: %9lld MB %8lld\n", s, (long long)runs_mb,
|
||||
|
@ -1731,9 +1731,9 @@ static void truncate_badclust_bad_attr(ntfs_resize_t *resize)
|
|||
* Shrink the metadata file $Bitmap. It must be large enough for one bit per
|
||||
* cluster of the shrunken volume. Also it must be a of 8 bytes in size.
|
||||
*/
|
||||
static void shrink_bitmap_data_attr(struct bitmap *bm,
|
||||
runlist **rlist,
|
||||
s64 nr_bm_clusters,
|
||||
static void shrink_bitmap_data_attr(struct bitmap *bm,
|
||||
runlist **rlist,
|
||||
s64 nr_bm_clusters,
|
||||
s64 new_size)
|
||||
{
|
||||
runlist *rl = *rlist;
|
||||
|
@ -1781,8 +1781,8 @@ static void shrink_bitmap_data_attr(struct bitmap *bm,
|
|||
*/
|
||||
static void enlarge_bitmap_data_attr(ntfs_volume *vol,
|
||||
struct bitmap *bm,
|
||||
runlist **rl,
|
||||
s64 nr_bm_clusters,
|
||||
runlist **rl,
|
||||
s64 nr_bm_clusters,
|
||||
s64 new_size)
|
||||
{
|
||||
s64 i;
|
||||
|
@ -1831,17 +1831,17 @@ static void truncate_bitmap_data_attr(ntfs_resize_t *resize)
|
|||
/* NOTE: shrink could use enlarge_bitmap_data_attr() also. Advantages:
|
||||
less code, better code coverage. "Drawback": could be relocated */
|
||||
if (resize->shrink)
|
||||
shrink_bitmap_data_attr(&resize->lcn_bitmap, &rl,
|
||||
shrink_bitmap_data_attr(&resize->lcn_bitmap, &rl,
|
||||
nr_bm_clusters, nr_clusters);
|
||||
else
|
||||
enlarge_bitmap_data_attr(vol, &resize->lcn_bitmap, &rl,
|
||||
enlarge_bitmap_data_attr(vol, &resize->lcn_bitmap, &rl,
|
||||
nr_bm_clusters, nr_clusters);
|
||||
|
||||
a->highest_vcn = cpu_to_le64(nr_bm_clusters - 1LL);
|
||||
a->allocated_size = cpu_to_le64(nr_bm_clusters * vol->cluster_size);
|
||||
a->data_size = cpu_to_le64(bm_bsize);
|
||||
a->initialized_size = cpu_to_le64(bm_bsize);
|
||||
|
||||
|
||||
replace_attribute_runlist(vol, resize->ctx, rl);
|
||||
|
||||
/*
|
||||
|
@ -1867,8 +1867,8 @@ static void truncate_bitmap_data_attr(ntfs_resize_t *resize)
|
|||
* (inode number).
|
||||
*/
|
||||
static void lookup_data_attr(ntfs_volume *vol,
|
||||
MFT_REF mref,
|
||||
const char *aname,
|
||||
MFT_REF mref,
|
||||
const char *aname,
|
||||
ntfs_attr_search_ctx **ctx)
|
||||
{
|
||||
ntfs_inode *ni;
|
||||
|
@ -1907,7 +1907,7 @@ static void truncate_badclust_file(ntfs_resize_t *resize)
|
|||
/* FIXME: sanity_check_attr(ctx->attr); */
|
||||
truncate_badclust_bad_attr(resize);
|
||||
|
||||
if (write_mft_record(resize->vol, resize->ctx->ntfs_ino->mft_no,
|
||||
if (write_mft_record(resize->vol, resize->ctx->ntfs_ino->mft_no,
|
||||
resize->ctx->mrec))
|
||||
perr_exit("Couldn't update $BadClust");
|
||||
|
||||
|
@ -1926,7 +1926,7 @@ static void truncate_bitmap_file(ntfs_resize_t *resize)
|
|||
lookup_data_attr(resize->vol, FILE_Bitmap, NULL, &resize->ctx);
|
||||
truncate_bitmap_data_attr(resize);
|
||||
|
||||
if (write_mft_record(resize->vol, resize->ctx->ntfs_ino->mft_no,
|
||||
if (write_mft_record(resize->vol, resize->ctx->ntfs_ino->mft_no,
|
||||
resize->ctx->mrec))
|
||||
perr_exit("Couldn't update $Bitmap");
|
||||
|
||||
|
@ -1976,7 +1976,7 @@ static void update_bootsector(ntfs_resize_t *r)
|
|||
|
||||
if (r->mftmir_old) {
|
||||
r->progress.flags |= NTFS_PROGBAR_SUPPRESS;
|
||||
copy_clusters(r, r->mftmir_rl.lcn, r->mftmir_old,
|
||||
copy_clusters(r, r->mftmir_rl.lcn, r->mftmir_old,
|
||||
r->mftmir_rl.length);
|
||||
bs.mftmirr_lcn = cpu_to_le64(r->mftmir_rl.lcn);
|
||||
r->progress.flags &= ~NTFS_PROGBAR_SUPPRESS;
|
||||
|
@ -2031,7 +2031,7 @@ static void print_disk_usage(ntfs_volume *vol, s64 nr_used_clusters)
|
|||
static void print_num_of_relocations(ntfs_resize_t *resize)
|
||||
{
|
||||
s64 relocations = resize->relocations * resize->vol->cluster_size;
|
||||
|
||||
|
||||
printf("Needed relocations : %lld (%lld MB)\n",
|
||||
(long long)resize->relocations, (long long)
|
||||
rounded_up_division(relocations, NTFS_MBYTE));
|
||||
|
@ -2082,7 +2082,7 @@ static ntfs_volume *mount_volume(void)
|
|||
if (opt.force-- <= 0)
|
||||
err_exit("Volume is dirty. Run chkdsk /f and "
|
||||
"please try again (or see -f option).\n");
|
||||
|
||||
|
||||
if (NTFS_MAX_CLUSTER_SIZE < vol->cluster_size)
|
||||
err_exit("Cluster size %u is too large!\n",
|
||||
(unsigned int)vol->cluster_size);
|
||||
|
@ -2136,7 +2136,7 @@ static void set_disk_usage_constraint(ntfs_resize_t *resize)
|
|||
{
|
||||
/* last lcn for a filled up volume (no empty space) */
|
||||
s64 last = resize->inuse - 1;
|
||||
|
||||
|
||||
if (resize->last_unsupp < last)
|
||||
resize->last_unsupp = last;
|
||||
}
|
||||
|
@ -2152,7 +2152,7 @@ static void check_shrink_constraints(ntfs_resize_t *resize)
|
|||
if (resize->inuse == resize->vol->nr_clusters)
|
||||
err_exit("Volume is full. To shrink it, "
|
||||
"delete unused files.\n");
|
||||
|
||||
|
||||
if (opt.info)
|
||||
return;
|
||||
|
||||
|
@ -2250,7 +2250,7 @@ int main(int argc, char **argv)
|
|||
compare_bitmaps(vol, &fsck.lcn_bitmap);
|
||||
|
||||
print_disk_usage(vol, fsck.inuse);
|
||||
|
||||
|
||||
memset(&resize, 0, sizeof(resize));
|
||||
resize.new_volume_size = new_size;
|
||||
resize.inuse = fsck.inuse;
|
||||
|
@ -2258,7 +2258,7 @@ int main(int argc, char **argv)
|
|||
resize.vol = vol;
|
||||
if (opt.show_progress)
|
||||
resize.progress.flags |= NTFS_PROGBAR;
|
||||
|
||||
|
||||
/* This is also true if --info was used w/o --size (new_size = 0) */
|
||||
if (new_size < vol->nr_clusters)
|
||||
resize.shrink = 1;
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <getopt.h>
|
||||
|
@ -44,6 +43,8 @@ GEN_PRINTF (Eprintf, stderr, NULL, FALSE)
|
|||
GEN_PRINTF (Vprintf, stdout, &opts.verbose, TRUE)
|
||||
GEN_PRINTF (Qprintf, stdout, &opts.quiet, FALSE)
|
||||
|
||||
//#define RM_WRITE 1
|
||||
|
||||
static int ntfs_inode_close2 (ntfs_inode *ni);
|
||||
|
||||
/**
|
||||
|
@ -207,7 +208,7 @@ static void ntfs_name_print (ntfschar *name, int name_len)
|
|||
if (name_len) {
|
||||
ntfs_ucstombs (name, name_len, &buffer, 0);
|
||||
printf ("%s", buffer);
|
||||
ntfs_free (buffer);
|
||||
free (buffer);
|
||||
} else {
|
||||
printf ("!");
|
||||
}
|
||||
|
@ -268,31 +269,44 @@ static const char *ntfsinfo_time_to_str(const s64 sle_ntfs_clock)
|
|||
static int ntfs_bmp_commit (struct ntfs_bmp *bmp)
|
||||
{
|
||||
int i;
|
||||
u32 cs;
|
||||
|
||||
if (!bmp)
|
||||
return 0;
|
||||
if (bmp->count == 0)
|
||||
return 0;
|
||||
|
||||
//printf ("\ta size = %lld\n", bmp->attr->allocated_size);
|
||||
//printf ("\td size = %lld\n", bmp->attr->data_size);
|
||||
//printf ("\ti size = %lld\n", bmp->attr->initialized_size);
|
||||
|
||||
cs = bmp->vol->cluster_size;
|
||||
|
||||
printf ("commit bmp 0x%02X (%sresident)\n", bmp->attr->type, bmp->attr->rl ? "non-" : "");
|
||||
|
||||
printf ("\ta size = %lld\n", bmp->attr->allocated_size);
|
||||
printf ("\td size = %lld\n", bmp->attr->data_size);
|
||||
//printf ("\ti size = %lld\n", bmp->attr->initialized_size);
|
||||
for (i = 0; i < bmp->count; i++) {
|
||||
printf ("\tvcn = %lld\n", bmp->data_vcn[i]);
|
||||
}
|
||||
#if 0
|
||||
ntfs_attr *attr;
|
||||
u8 **data;
|
||||
VCN *data_vcn;
|
||||
int count;
|
||||
if (bmp->attr->rl) {
|
||||
// non-resident
|
||||
for (i = 0; i < bmp->count; i++) {
|
||||
#ifdef RM_WRITE
|
||||
ntfs_attr_pwrite (bmp->attr, bmp->data_vcn[i] * cs, cs, bmp->data[i]); // XXX retval
|
||||
#else
|
||||
printf (RED "\tntfs_attr_pwrite (vcn %lld)\n" END, bmp->data_vcn[i]);
|
||||
#endif
|
||||
for (i = 0; i < bmp->count; i++)
|
||||
ntfs_free (bmp->data[i]);
|
||||
}
|
||||
} else {
|
||||
// resident
|
||||
#ifdef RM_WRITE
|
||||
ntfs_attr_pwrite (bmp->attr, bmp->data_vcn[0], bmp->attr->data_size, bmp->data[0]); // XXX retval
|
||||
#else
|
||||
printf (RED "\tntfs_attr_pwrite resident\n" END);
|
||||
#endif
|
||||
}
|
||||
|
||||
ntfs_free (bmp->data);
|
||||
ntfs_free (bmp->data_vcn);
|
||||
for (i = 0; i < bmp->count; i++)
|
||||
free (bmp->data[i]);
|
||||
|
||||
free (bmp->data); // XXX wipe ->data and ->data_vcn
|
||||
free (bmp->data_vcn);
|
||||
bmp->count = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -311,10 +325,10 @@ static int ntfs_bmp_rollback (struct ntfs_bmp *bmp)
|
|||
printf ("rollback bmp\n");
|
||||
|
||||
for (i = 0; i < bmp->count; i++)
|
||||
ntfs_free (bmp->data[i]);
|
||||
free (bmp->data[i]);
|
||||
|
||||
ntfs_free (bmp->data);
|
||||
ntfs_free (bmp->data_vcn);
|
||||
free (bmp->data);
|
||||
free (bmp->data_vcn);
|
||||
bmp->count = 0;
|
||||
|
||||
return 0;
|
||||
|
@ -332,8 +346,8 @@ static void ntfs_bmp_free (struct ntfs_bmp *bmp)
|
|||
|
||||
ntfs_attr_close (bmp->attr);
|
||||
|
||||
ntfs_free (bmp->cache);
|
||||
ntfs_free (bmp);
|
||||
free (bmp->cache);
|
||||
free (bmp);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -351,7 +365,7 @@ static struct ntfs_bmp * ntfs_bmp_alloc (ntfs_inode *inode, ATTR_TYPES type, ntf
|
|||
if (!attr)
|
||||
return NULL;
|
||||
|
||||
bmp = ntfs_calloc (1, sizeof (*bmp));
|
||||
bmp = calloc (1, sizeof (*bmp));
|
||||
if (!bmp) {
|
||||
ntfs_attr_close (attr);
|
||||
return NULL;
|
||||
|
@ -385,8 +399,8 @@ static int ntfs_bmp_add_data (struct ntfs_bmp *bmp, VCN vcn, u8 *data)
|
|||
new = ROUND_UP (bmp->count, 16);
|
||||
|
||||
if (old != new) {
|
||||
bmp->data = ntfs_realloc (bmp->data, new * sizeof (*bmp->data));
|
||||
bmp->data_vcn = ntfs_realloc (bmp->data_vcn , new * sizeof (*bmp->data_vcn));
|
||||
bmp->data = realloc (bmp->data, new * sizeof (*bmp->data));
|
||||
bmp->data_vcn = realloc (bmp->data_vcn , new * sizeof (*bmp->data_vcn));
|
||||
}
|
||||
|
||||
for (i = 0; i < bmp->count-1; i++)
|
||||
|
@ -432,13 +446,13 @@ static u8 * ntfs_bmp_get_data (struct ntfs_bmp *bmp, VCN vcn)
|
|||
}
|
||||
}
|
||||
|
||||
buffer = ntfs_malloc (cs); // XXX could be smaller if attr size < cluster size
|
||||
buffer = calloc (1, cs); // XXX could be smaller if attr size < cluster size
|
||||
if (!buffer)
|
||||
return NULL;
|
||||
|
||||
//printf ("loading from bitmap cluster %lld\n", vcn);
|
||||
if (ntfs_attr_pread (bmp->attr, vcn, cs, buffer) < 0) {
|
||||
ntfs_free (buffer);
|
||||
free (buffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -547,9 +561,9 @@ static int ntfs_bmp_set_range (struct ntfs_bmp *bmp, VCN vcn, s64 length, int va
|
|||
|
||||
printf (GREEN "Modified: inode %lld, ", bmp->attr->ni->mft_no);
|
||||
switch (bmp->attr->type) {
|
||||
case AT_BITMAP: printf("$BITMAP"); break;
|
||||
case AT_DATA: printf("$DATA"); break;
|
||||
default: printf("???"); break;
|
||||
case AT_BITMAP: printf ("$BITMAP"); break;
|
||||
case AT_DATA: printf ("$DATA"); break;
|
||||
default: break;
|
||||
}
|
||||
printf (" vcn %lld-%lld\n" END, vcn>>12, (vcn+length-1)>>12);
|
||||
|
||||
|
@ -633,7 +647,7 @@ static INDEX_ENTRY * ntfs_ie_create (void)
|
|||
INDEX_ENTRY *ie;
|
||||
|
||||
length = 16;
|
||||
ie = ntfs_malloc (length);
|
||||
ie = malloc (length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -655,7 +669,7 @@ static INDEX_ENTRY * ntfs_ie_copy (INDEX_ENTRY *ie)
|
|||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
copy = ntfs_malloc (ie->length);
|
||||
copy = malloc (ie->length);
|
||||
if (!copy)
|
||||
return NULL;
|
||||
memcpy (copy, ie, ie->length);
|
||||
|
@ -673,7 +687,7 @@ static INDEX_ENTRY * ntfs_ie_set_vcn (INDEX_ENTRY *ie, VCN vcn)
|
|||
|
||||
if (!(ie->flags & INDEX_ENTRY_NODE)) {
|
||||
ie->length += 8;
|
||||
ie = ntfs_realloc (ie, ie->length);
|
||||
ie = realloc (ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -696,7 +710,7 @@ static INDEX_ENTRY * ntfs_ie_remove_vcn (INDEX_ENTRY *ie)
|
|||
|
||||
ie->length -= 8;
|
||||
ie->flags &= ~INDEX_ENTRY_NODE;
|
||||
ie = ntfs_realloc (ie, ie->length);
|
||||
ie = realloc (ie, ie->length);
|
||||
return ie;
|
||||
}
|
||||
|
||||
|
@ -753,7 +767,7 @@ static INDEX_ENTRY * ntfs_ie_set_name (INDEX_ENTRY *ie, ntfschar *name, int name
|
|||
|
||||
ie->length = 16 + need;
|
||||
ie->key_length = sizeof (FILE_NAME_ATTR) + (namelen * sizeof (ntfschar));
|
||||
ie = ntfs_realloc (ie, ie->length + ie->key_length);
|
||||
ie = realloc (ie, ie->length + ie->key_length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -788,7 +802,7 @@ static INDEX_ENTRY * ntfs_ie_remove_name (INDEX_ENTRY *ie)
|
|||
ie->key_length = 0;
|
||||
ie->flags |= INDEX_ENTRY_END;
|
||||
|
||||
ie = ntfs_realloc (ie, ie->length);
|
||||
ie = realloc (ie, ie->length);
|
||||
if (!ie)
|
||||
return NULL;
|
||||
|
||||
|
@ -820,7 +834,7 @@ static int ntfs_ie_test (void)
|
|||
if (1) {
|
||||
namelen = ntfs_mbstoucs("richard", &name, 0);
|
||||
ie1 = ntfs_ie_set_name (ie1, name, namelen, FILE_NAME_WIN32);
|
||||
ntfs_free (name);
|
||||
free (name);
|
||||
name = NULL;
|
||||
ntfs_ie_dump (ie1);
|
||||
}
|
||||
|
@ -828,7 +842,7 @@ static int ntfs_ie_test (void)
|
|||
if (1) {
|
||||
namelen = ntfs_mbstoucs("richard2", &name, 0);
|
||||
ie1 = ntfs_ie_set_name (ie1, name, namelen, FILE_NAME_WIN32);
|
||||
ntfs_free (name);
|
||||
free (name);
|
||||
name = NULL;
|
||||
ntfs_ie_dump (ie1);
|
||||
}
|
||||
|
@ -858,9 +872,9 @@ static int ntfs_ie_test (void)
|
|||
ie1->key.file_name.data_size = 3973;
|
||||
|
||||
//ntfs_ie_dump (ie1);
|
||||
ntfs_free (name);
|
||||
ntfs_free (ie1);
|
||||
ntfs_free (ie2);
|
||||
free (name);
|
||||
free (ie1);
|
||||
free (ie2);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -877,7 +891,7 @@ static INDEX_ENTRY ** ntfs_dt_alloc_children (INDEX_ENTRY **children, int count)
|
|||
if (old == new)
|
||||
return children;
|
||||
|
||||
return ntfs_realloc (children, new * sizeof (INDEX_ENTRY*));
|
||||
return realloc (children, new * sizeof (INDEX_ENTRY*));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -893,9 +907,9 @@ static BOOL ntfs_dt_alloc_children2 (struct ntfs_dt *dt, int count)
|
|||
if (old == new)
|
||||
return TRUE;
|
||||
|
||||
dt->children = ntfs_realloc (dt->children, new * sizeof (*dt->children));
|
||||
dt->sub_nodes = ntfs_realloc (dt->sub_nodes, new * sizeof (*dt->sub_nodes));
|
||||
dt->inodes = ntfs_realloc (dt->sub_nodes, new * sizeof (*dt->inodes));
|
||||
dt->children = realloc (dt->children, new * sizeof (*dt->children));
|
||||
dt->sub_nodes = realloc (dt->sub_nodes, new * sizeof (*dt->sub_nodes));
|
||||
dt->inodes = realloc (dt->sub_nodes, new * sizeof (*dt->inodes));
|
||||
|
||||
// XXX wipe new space
|
||||
|
||||
|
@ -948,7 +962,7 @@ static int ntfs_dt_count_root (struct ntfs_dt *dt)
|
|||
if (!(entry->flags & INDEX_ENTRY_END)) {
|
||||
ntfs_ucstombs (entry->key.file_name.file_name, entry->key.file_name.file_name_length, &name, entry->key.file_name.file_name_length);
|
||||
//printf ("\tinode %8lld %s\n", MREF (entry->indexed_file), name);
|
||||
ntfs_free (name);
|
||||
free (name);
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
|
@ -962,8 +976,8 @@ static int ntfs_dt_count_root (struct ntfs_dt *dt)
|
|||
|
||||
if (dt->child_count > 0) {
|
||||
//printf ("%d subnodes\n", dt->child_count);
|
||||
dt->sub_nodes = ntfs_calloc (dt->child_count, sizeof (struct ntfs_dt *));
|
||||
dt->inodes = ntfs_calloc (dt->child_count, sizeof (struct ntfs_inode *));
|
||||
dt->sub_nodes = calloc (dt->child_count, sizeof (struct ntfs_dt *));
|
||||
dt->inodes = calloc (dt->child_count, sizeof (struct ntfs_inode *));
|
||||
}
|
||||
return dt->child_count;
|
||||
}
|
||||
|
@ -1015,7 +1029,7 @@ static int ntfs_dt_count_alloc (struct ntfs_dt *dt)
|
|||
} else {
|
||||
ntfs_ucstombs (entry->key.file_name.file_name, entry->key.file_name.file_name_length, &name, entry->key.file_name.file_name_length);
|
||||
//printf ("\tinode %8lld %s\n", MREF (entry->indexed_file), name);
|
||||
ntfs_free (name);
|
||||
free (name);
|
||||
name = NULL;
|
||||
}
|
||||
|
||||
|
@ -1025,8 +1039,8 @@ static int ntfs_dt_count_alloc (struct ntfs_dt *dt)
|
|||
|
||||
if (dt->child_count > 0) {
|
||||
//printf ("%d subnodes\n", dt->child_count);
|
||||
dt->sub_nodes = ntfs_calloc (dt->child_count, sizeof (struct ntfs_dt *));
|
||||
dt->inodes = ntfs_calloc (dt->child_count, sizeof (struct ntfs_inode *));
|
||||
dt->sub_nodes = calloc (dt->child_count, sizeof (struct ntfs_dt *));
|
||||
dt->inodes = calloc (dt->child_count, sizeof (struct ntfs_inode *));
|
||||
}
|
||||
|
||||
return dt->child_count;
|
||||
|
@ -1052,35 +1066,31 @@ static int ntfs_dt_commit (struct ntfs_dt *dt)
|
|||
vol = dir->vol; // cluster size
|
||||
|
||||
if (dt->changed) {
|
||||
printf ("commit dt ");
|
||||
printf ("commit dt\n");
|
||||
if (dt->parent) {
|
||||
attr = dt->dir->ialloc;
|
||||
} else {
|
||||
attr = dt->dir->iroot;
|
||||
}
|
||||
|
||||
printf (BOLD RED "ntfs_attr_pwrite\n" END);
|
||||
//WRITE printf ("%lld\n", ntfs_attr_pwrite (attr, dt->vcn * dt->dir->index_size, dt->dir->index_size, dt->data));
|
||||
#ifdef RM_WRITE
|
||||
ntfs_attr_pwrite (attr, dt->vcn * dt->dir->index_size, dt->dir->index_size, dt->data);
|
||||
#else
|
||||
printf (RED "\tntfs_attr_pwrite (vcn %lld)\n" END, dt->vcn);
|
||||
#endif
|
||||
|
||||
dt->changed = FALSE;
|
||||
}
|
||||
|
||||
#if 0
|
||||
//dt
|
||||
u8 *data;
|
||||
int data_len;
|
||||
ntfs_inode **inodes;
|
||||
VCN vcn;
|
||||
BOOL changed;
|
||||
|
||||
//dir
|
||||
struct ntfs_bmp *bitmap;
|
||||
ntfs_attr *iroot;
|
||||
ntfs_attr *ialloc;
|
||||
int index_size;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < dt->child_count; i++) {
|
||||
if ((dt->inodes[i]) && (NInoDirty (dt->inodes[i]))) {
|
||||
#ifdef RM_WRITE
|
||||
ntfs_inode_sync (dt->inodes[i]);
|
||||
#else
|
||||
printf (RED "\tntfs_inode_sync %llu\n" END, dt->inodes[i]->mft_no);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ntfs_dt_commit (dt->sub_nodes[i]) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -1116,11 +1126,11 @@ static void ntfs_dt_free (struct ntfs_dt *dt)
|
|||
ntfs_inode_close2 (dt->inodes[i]);
|
||||
}
|
||||
|
||||
ntfs_free (dt->sub_nodes);
|
||||
ntfs_free (dt->children);
|
||||
ntfs_free (dt->inodes);
|
||||
ntfs_free (dt->data); // XXX is this always ours?
|
||||
ntfs_free (dt);
|
||||
free (dt->sub_nodes);
|
||||
free (dt->children);
|
||||
free (dt->inodes);
|
||||
free (dt->data); // XXX is this always ours?
|
||||
free (dt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1134,7 +1144,7 @@ static struct ntfs_dt * ntfs_dt_alloc (struct ntfs_dir *dir, struct ntfs_dt *par
|
|||
if (!dir)
|
||||
return NULL;
|
||||
|
||||
dt = ntfs_calloc (1, sizeof (*dt));
|
||||
dt = calloc (1, sizeof (*dt));
|
||||
if (!dt)
|
||||
return NULL;
|
||||
|
||||
|
@ -1155,7 +1165,7 @@ static struct ntfs_dt * ntfs_dt_alloc (struct ntfs_dir *dir, struct ntfs_dt *par
|
|||
|
||||
dt->data_len = dt->dir->index_size;
|
||||
//printf ("parent size = %d\n", dt->data_len);
|
||||
dt->data = ntfs_malloc (dt->data_len);
|
||||
dt->data = malloc (dt->data_len);
|
||||
//printf ("%lld\n", ntfs_attr_mst_pread (dir->ialloc, vcn*512, 1, dt->data_len, dt->data));
|
||||
ntfs_attr_mst_pread (dir->ialloc, vcn*512, 1, dt->data_len, dt->data);
|
||||
//utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS);
|
||||
|
@ -1185,7 +1195,7 @@ static struct ntfs_dt * ntfs_dt_alloc (struct ntfs_dir *dir, struct ntfs_dt *par
|
|||
//printf ("root i = %lld\n", dir->iroot->initialized_size);
|
||||
|
||||
dt->data_len = dir->iroot->allocated_size;
|
||||
dt->data = ntfs_malloc (dt->data_len);
|
||||
dt->data = malloc (dt->data_len);
|
||||
//printf ("%lld\n", ntfs_attr_pread (dir->iroot, 0, dt->data_len, dt->data));
|
||||
ntfs_attr_pread (dir->iroot, 0, dt->data_len, dt->data);
|
||||
//utils_dump_mem (dt->data, 0, dt->data_len, DM_DEFAULTS);
|
||||
|
@ -1602,8 +1612,8 @@ static int ntfs_dt_initialise (struct ntfs_dt *dt, VCN vcn)
|
|||
memset (dt->data, 0, dt->data_len);
|
||||
|
||||
// Ought to check these are empty
|
||||
ntfs_free (dt->children);
|
||||
ntfs_free (dt->sub_nodes);
|
||||
free (dt->children);
|
||||
free (dt->sub_nodes);
|
||||
|
||||
dt->children = NULL;
|
||||
dt->sub_nodes = NULL;
|
||||
|
@ -1899,7 +1909,15 @@ static int ntfs_dir_commit (struct ntfs_dir *dir)
|
|||
if (!dir)
|
||||
return 0;
|
||||
|
||||
printf ("commit dir\n");
|
||||
printf ("commit dir inode %llu\n", dir->inode->mft_no);
|
||||
if (NInoDirty (dir->inode)) {
|
||||
#ifdef RM_WRITE
|
||||
ntfs_inode_sync (dir->inode);
|
||||
#else
|
||||
printf (RED "\tntfs_inode_sync %llu\n" END, dir->inode->mft_no);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (ntfs_dt_commit (dir->index) < 0)
|
||||
return -1;
|
||||
|
||||
|
@ -1970,8 +1988,8 @@ static void ntfs_dir_free (struct ntfs_dir *dir)
|
|||
for (i = 0; i < dir->child_count; i++)
|
||||
ntfs_dir_free (dir->children[i]);
|
||||
|
||||
ntfs_free (dir->children);
|
||||
ntfs_free (dir);
|
||||
free (dir->children);
|
||||
free (dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1992,7 +2010,7 @@ static struct ntfs_dir * ntfs_dir_alloc (ntfs_volume *vol, MFT_REF mft_num)
|
|||
if (!inode)
|
||||
return NULL;
|
||||
|
||||
dir = ntfs_calloc (1, sizeof (*dir));
|
||||
dir = calloc (1, sizeof (*dir));
|
||||
if (!dir) {
|
||||
ntfs_inode_close2 (inode);
|
||||
return NULL;
|
||||
|
@ -2040,7 +2058,7 @@ static void ntfs_dir_add (struct ntfs_dir *parent, struct ntfs_dir *child)
|
|||
|
||||
parent->child_count++;
|
||||
//printf ("child count = %d\n", parent->child_count);
|
||||
parent->children = ntfs_realloc (parent->children, parent->child_count * sizeof (struct ntfs_dir*));
|
||||
parent->children = realloc (parent->children, parent->child_count * sizeof (struct ntfs_dir*));
|
||||
child->parent = parent;
|
||||
|
||||
parent->children[parent->child_count-1] = child;
|
||||
|
@ -2070,7 +2088,7 @@ static MFT_REF ntfs_dir_find (struct ntfs_dir *dir, char *name)
|
|||
//printf ("uname = %p\n", uname);
|
||||
mft_num = ntfs_dt_find (dir->index, uname, len);
|
||||
|
||||
ntfs_free (uname);
|
||||
free (uname);
|
||||
return mft_num;
|
||||
}
|
||||
|
||||
|
@ -2151,7 +2169,7 @@ static int ntfs_dir_truncate (ntfs_volume *vol, struct ntfs_dir *dir)
|
|||
if (!buffer)
|
||||
return -1;
|
||||
|
||||
utils_dump_mem (buffer, 0, 8, DM_NO_ASCII);
|
||||
//utils_dump_mem (buffer, 0, 8, DM_NO_ASCII);
|
||||
for (i = 0; i < 1; i++) {
|
||||
if (buffer[i]) {
|
||||
//printf ("alloc in use\n");
|
||||
|
@ -2592,7 +2610,9 @@ static int utils_mftrec_mark_free5 (ntfs_inode *inode, struct ntfs_bmp *bmp, MFT
|
|||
}
|
||||
|
||||
rec->flags &= ~MFT_RECORD_IN_USE;
|
||||
//printf ("inode %llu, %lu\n", inode->mft_no, inode->state);
|
||||
NInoSetDirty(inode);
|
||||
//printf ("inode %llu, %lu\n", inode->mft_no, inode->state);
|
||||
|
||||
//printf ("\n");
|
||||
//utils_dump_mem (buffer, 0, 1024, DM_DEFAULTS);
|
||||
|
@ -2721,7 +2741,7 @@ static BOOL utils_pathname_to_inode2 (ntfs_volume *vol, struct ntfs_dir *parent,
|
|||
}
|
||||
}
|
||||
|
||||
unicode = ntfs_malloc (MAX_PATH * sizeof (ntfschar));
|
||||
unicode = malloc (MAX_PATH * sizeof (ntfschar));
|
||||
ascii = strdup (pathname); // Work with a r/w copy
|
||||
if (!unicode || !ascii) {
|
||||
Eprintf ("Out of memory.\n");
|
||||
|
@ -2759,7 +2779,7 @@ static BOOL utils_pathname_to_inode2 (ntfs_volume *vol, struct ntfs_dir *parent,
|
|||
if (dt->inodes[dt_num] == NULL) {
|
||||
dt->inodes[dt_num] = ntfs_inode_open (dir->vol, dt->children[dt_num]->indexed_file);
|
||||
if (!dt->inodes[dt_num]) {
|
||||
printf ("Can't open inode %lld\n", dt->children[dt_num]->indexed_file);
|
||||
printf ("Can't open inode %lld\n", MREF (dt->children[dt_num]->indexed_file));
|
||||
goto close;
|
||||
}
|
||||
dt->inodes[dt_num]->ref_count = 2;
|
||||
|
@ -2787,7 +2807,7 @@ static BOOL utils_pathname_to_inode2 (ntfs_volume *vol, struct ntfs_dir *parent,
|
|||
//printf ("dir %p, dt %p, num %d, ino %p, %lld\n", dir, dt, dt_num, dt->inodes[dt_num], MREF (found->inode->mft_no));
|
||||
close:
|
||||
free (ascii); // from strdup
|
||||
ntfs_free (unicode);
|
||||
free (unicode);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2922,7 +2942,7 @@ static int ntfs_dt_root_replace (struct ntfs_dt *del, int del_num, INDEX_ENTRY *
|
|||
//utils_dump_mem (del->data, 0, del->data_len, DM_DEFAULTS);
|
||||
//printf ("\n");
|
||||
|
||||
attr = ntfs_malloc (del->data_len + suc_ie->length - del_ie->length);
|
||||
attr = malloc (del->data_len + suc_ie->length - del_ie->length);
|
||||
|
||||
dst = attr;
|
||||
src = del->data;
|
||||
|
@ -2946,7 +2966,7 @@ static int ntfs_dt_root_replace (struct ntfs_dt *del, int del_num, INDEX_ENTRY *
|
|||
dst = attr;
|
||||
|
||||
len = del->data_len + suc_ie->length - del_ie->length;
|
||||
ntfs_free (del->data);
|
||||
free (del->data);
|
||||
del->data = attr;
|
||||
del->data_len = len;
|
||||
|
||||
|
@ -3104,7 +3124,7 @@ static BOOL ntfs_dt_root_remove (struct ntfs_dt *del, int del_num)
|
|||
|
||||
ntfs_mft_resize_resident (del->dir->inode, AT_INDEX_ROOT, I30, 4, del->data, del->data_len);
|
||||
old = del->data;
|
||||
del->data = ntfs_realloc (del->data, del->data_len);
|
||||
del->data = realloc (del->data, del->data_len);
|
||||
del->header = (INDEX_HEADER*) (del->data + 0x10);
|
||||
|
||||
del->header->index_length -= del_len;
|
||||
|
@ -3322,7 +3342,7 @@ static int ntfs_dt_root_add (struct ntfs_dt *add, INDEX_ENTRY *add_ie)
|
|||
return 0;
|
||||
}
|
||||
|
||||
attr = ntfs_malloc (add->data_len + need);
|
||||
attr = malloc (add->data_len + need);
|
||||
|
||||
src = add->data;
|
||||
dst = attr;
|
||||
|
@ -3342,7 +3362,7 @@ static int ntfs_dt_root_add (struct ntfs_dt *add, INDEX_ENTRY *add_ie)
|
|||
|
||||
memcpy (dst, src, len);
|
||||
|
||||
ntfs_free (add->data);
|
||||
free (add->data);
|
||||
add->data = attr;
|
||||
add->data_len += need;
|
||||
|
||||
|
@ -3493,9 +3513,9 @@ static int ntfs_dt_remove_alloc (struct ntfs_dt *dt, int index_num)
|
|||
}
|
||||
}
|
||||
|
||||
ntfs_free (dt->sub_nodes);
|
||||
free (dt->sub_nodes);
|
||||
dt->sub_nodes = NULL;
|
||||
ntfs_free (dt->children);
|
||||
free (dt->children);
|
||||
dt->children = NULL;
|
||||
dt->child_count = 0;
|
||||
|
||||
|
@ -3596,7 +3616,7 @@ static int ntfs_dt_remove_root (struct ntfs_dt *dt, int index_num)
|
|||
ir->index.allocated_size = dt->data_len - 16;
|
||||
|
||||
ntfs_mft_resize_resident (dt->dir->inode, AT_INDEX_ROOT, I30, 4, dt->data, dt->data_len);
|
||||
dt->data = ntfs_realloc (dt->data, dt->data_len);
|
||||
dt->data = realloc (dt->data, dt->data_len);
|
||||
|
||||
//printf ("ih->index_length = %d\n", ir->index.index_length);
|
||||
//printf ("ih->allocated_size = %d\n", ir->index.allocated_size);
|
||||
|
@ -3612,9 +3632,9 @@ static int ntfs_dt_remove_root (struct ntfs_dt *dt, int index_num)
|
|||
}
|
||||
}
|
||||
|
||||
ntfs_free (dt->sub_nodes);
|
||||
free (dt->sub_nodes);
|
||||
dt->sub_nodes = NULL;
|
||||
ntfs_free (dt->children);
|
||||
free (dt->children);
|
||||
dt->children = NULL;
|
||||
dt->child_count = 0;
|
||||
|
||||
|
@ -3910,7 +3930,7 @@ static int ntfs_dt_add_root (struct ntfs_dt *parent, int index_num, INDEX_ENTRY
|
|||
return 0;
|
||||
}
|
||||
|
||||
attr = ntfs_malloc (parent->data_len + need);
|
||||
attr = malloc (parent->data_len + need);
|
||||
|
||||
src = parent->data;
|
||||
dst = attr;
|
||||
|
@ -3930,7 +3950,7 @@ static int ntfs_dt_add_root (struct ntfs_dt *parent, int index_num, INDEX_ENTRY
|
|||
|
||||
memcpy (dst, src, len);
|
||||
|
||||
ntfs_free (parent->data);
|
||||
free (parent->data);
|
||||
parent->data = attr;
|
||||
parent->data_len += need;
|
||||
|
||||
|
@ -4209,7 +4229,7 @@ static int ntfsrm (ntfs_volume *vol, char *name)
|
|||
ntfs_dt_del_child (finddir->index, uname, len);
|
||||
|
||||
ntfs_dir_free (dir);
|
||||
ntfs_free (uname);
|
||||
free (uname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4354,7 +4374,7 @@ static int ntfs_file_add (ntfs_volume *vol, char *name)
|
|||
if (!ie)
|
||||
goto done;
|
||||
|
||||
ntfs_free (uname);
|
||||
free (uname);
|
||||
uname = NULL;
|
||||
|
||||
len = ntfs_mbstoucs ("file26a", &uname, 0);
|
||||
|
@ -4380,8 +4400,8 @@ static int ntfs_file_add (ntfs_volume *vol, char *name)
|
|||
|
||||
done:
|
||||
ntfs_dir_free (dir);
|
||||
ntfs_free (uname);
|
||||
ntfs_free (ie);
|
||||
free (uname);
|
||||
free (ie);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -4468,7 +4488,7 @@ static int ntfs_file_remove (ntfs_volume *vol, struct ntfs_dt *del, int del_num)
|
|||
//printf ("\n");
|
||||
//utils_dump_mem (del->data, 0, del->data_len, DM_BLUE|DM_GREEN|DM_INDENT);
|
||||
|
||||
ntfs_free (suc_ie);
|
||||
free (suc_ie);
|
||||
|
||||
if (res == FALSE)
|
||||
goto done;
|
||||
|
@ -4664,7 +4684,7 @@ static int ntfs_file_remove (ntfs_volume *vol, struct ntfs_dt *del, int del_num)
|
|||
freedts:
|
||||
|
||||
commit:
|
||||
printf ("commit\n");
|
||||
//printf ("commit\n");
|
||||
|
||||
done:
|
||||
return 0;
|
||||
|
@ -4799,4 +4819,3 @@ done:
|
|||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,6 @@
|
|||
#include "types.h"
|
||||
#include "layout.h"
|
||||
|
||||
#define ntfs_malloc malloc
|
||||
#define ntfs_realloc realloc
|
||||
#define ntfs_calloc calloc
|
||||
#define ntfs_free free
|
||||
|
||||
/**
|
||||
* struct options
|
||||
*/
|
||||
|
|
|
@ -503,7 +503,8 @@ static void dump_resident_attr(ATTR_RECORD *a)
|
|||
/**
|
||||
* dump_mapping_pairs_array
|
||||
*/
|
||||
static void dump_mapping_pairs_array(char *b, unsigned int max_len)
|
||||
static void dump_mapping_pairs_array(char *b __attribute__((unused)),
|
||||
unsigned int max_len __attribute__((unused)))
|
||||
{
|
||||
// TODO
|
||||
return;
|
||||
|
|
|
@ -720,7 +720,8 @@ static void free_file (struct ufile *file)
|
|||
* Return: @rec's filename, either same name space as @name or lowest space.
|
||||
* NULL if can't determine parenthood or on error.
|
||||
*/
|
||||
static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec) {
|
||||
static FILE_NAME_ATTR* verify_parent(struct filename* name, MFT_RECORD* rec)
|
||||
{
|
||||
ATTR_RECORD *attr30;
|
||||
FILE_NAME_ATTR *filename_attr = NULL, *lowest_space_name = NULL;
|
||||
ntfs_attr_search_ctx *ctx;
|
||||
|
@ -785,7 +786,7 @@ static void get_parent_name (struct filename* name, ntfs_volume* vol)
|
|||
|
||||
if (!name || !vol)
|
||||
return;
|
||||
|
||||
|
||||
rec = calloc(1, vol->mft_record_size);
|
||||
if (!rec) {
|
||||
Eprintf ("ERROR: Couldn't allocate memory in get_parent_name()\n");
|
||||
|
|
|
@ -419,7 +419,7 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte,
|
|||
VCN cur_vcn = 0;
|
||||
runlist *rlc = na->rl;
|
||||
s64 cu_mask = na->compression_block_clusters - 1;
|
||||
|
||||
|
||||
while (rlc->length) {
|
||||
cur_vcn += rlc->length;
|
||||
if ((cur_vcn & cu_mask) ||
|
||||
|
@ -465,20 +465,20 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte,
|
|||
size = na->allocated_size - na->data_size;
|
||||
offset = (cur_vcn << vol->cluster_size_bits) - size;
|
||||
}
|
||||
|
||||
|
||||
if (size < 0) {
|
||||
Vprintf ("Internal error\n");
|
||||
Eprintf ("bug or damaged fs: we want "
|
||||
"allocate buffer size %lld bytes", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if ((act == act_info) || (!size)) {
|
||||
wiped += size;
|
||||
rlc++;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
buf = malloc (size);
|
||||
if (!buf) {
|
||||
Vprintf ("Not enough memory\n");
|
||||
|
@ -487,7 +487,7 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte,
|
|||
return -1;
|
||||
}
|
||||
memset (buf, byte, size);
|
||||
|
||||
|
||||
ret = ntfs_rl_pwrite (vol, na->rl, offset, size, buf);
|
||||
free (buf);
|
||||
if (ret != size) {
|
||||
|
@ -500,7 +500,7 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte,
|
|||
next:
|
||||
rlc++;
|
||||
}
|
||||
|
||||
|
||||
return wiped;
|
||||
}
|
||||
|
||||
|
@ -515,7 +515,7 @@ next:
|
|||
* 0 Nothing to wipe
|
||||
* -1 Error, something went wrong
|
||||
*/
|
||||
static s64 wipe_attribute (ntfs_volume *vol, int byte, enum action act,
|
||||
static s64 wipe_attribute (ntfs_volume *vol, int byte, enum action act,
|
||||
ntfs_attr *na)
|
||||
{
|
||||
unsigned char *buf;
|
||||
|
@ -528,7 +528,7 @@ static s64 wipe_attribute (ntfs_volume *vol, int byte, enum action act,
|
|||
if (NAttrEncrypted(na))
|
||||
offset = (((offset - 1) >> 10) + 1) << 10;
|
||||
size = (vol->cluster_size - offset) % vol->cluster_size;
|
||||
|
||||
|
||||
if (act == act_info)
|
||||
return size;
|
||||
|
||||
|
@ -617,7 +617,7 @@ static s64 wipe_tails (ntfs_volume *vol, int byte, enum action act)
|
|||
Eprintf (" (inode %lld)\n", inode_num);
|
||||
goto close_attr;
|
||||
}
|
||||
|
||||
|
||||
if (wiped) {
|
||||
Vprintf ("Wiped %llu bytes\n", wiped);
|
||||
total += wiped;
|
||||
|
@ -780,8 +780,10 @@ free:
|
|||
* 0 Nothing to wipe
|
||||
* -1 Error, something went wrong
|
||||
*/
|
||||
static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
||||
ntfs_attr *naa, ntfs_attr *nab, u32 indx_record_size) {
|
||||
static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act
|
||||
__attribute__((unused)), ntfs_attr *naa, ntfs_attr *nab,
|
||||
u32 indx_record_size)
|
||||
{
|
||||
s64 total = 0;
|
||||
s64 wiped = 0;
|
||||
s64 offset = 0;
|
||||
|
@ -792,14 +794,14 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
u8 mask;
|
||||
u8 *bitmap;
|
||||
u8 *buf;
|
||||
|
||||
|
||||
bitmap = malloc (nab->data_size);
|
||||
if (!bitmap) {
|
||||
Vprintf ("malloc failed\n");
|
||||
Eprintf ("Couldn't allocate %lld bytes", nab->data_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ntfs_attr_pread (nab, 0, nab->data_size, bitmap)
|
||||
!= nab->data_size) {
|
||||
Vprintf ("Internal error\n");
|
||||
|
@ -807,7 +809,7 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
total = -1;
|
||||
goto free_bitmap;
|
||||
}
|
||||
|
||||
|
||||
buf = malloc (indx_record_size);
|
||||
if (!buf) {
|
||||
Vprintf ("malloc failed\n");
|
||||
|
@ -816,12 +818,12 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
total = -1;
|
||||
goto free_bitmap;
|
||||
}
|
||||
|
||||
|
||||
while (offset < naa->allocated_size) {
|
||||
mask = 1 << obit;
|
||||
if (bitmap[obyte] & mask) {
|
||||
INDEX_ALLOCATION *indx;
|
||||
|
||||
|
||||
s64 ret = ntfs_rl_pread (vol, naa->rl,
|
||||
offset, indx_record_size, buf);
|
||||
if (ret != indx_record_size) {
|
||||
|
@ -830,13 +832,13 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
total = -1;
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
|
||||
indx = (INDEX_ALLOCATION *) buf;
|
||||
if (ntfs_mst_post_read_fixup ((NTFS_RECORD *)buf,
|
||||
indx_record_size))
|
||||
Eprintf ("damaged fs: mst_post_read_fixup failed");
|
||||
|
||||
if ((le32_to_cpu(indx->index.allocated_size) + 0x18) !=
|
||||
|
||||
if ((le32_to_cpu(indx->index.allocated_size) + 0x18) !=
|
||||
indx_record_size) {
|
||||
Vprintf ("Internal error\n");
|
||||
Eprintf ("INDX record should be %u bytes",
|
||||
|
@ -844,7 +846,7 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
total = -1;
|
||||
goto free_buf;
|
||||
}
|
||||
|
||||
|
||||
wipe_offset = le32_to_cpu(indx->index.index_length) + 0x18;
|
||||
wipe_size = indx_record_size - wipe_offset;
|
||||
memset (buf + wipe_offset, byte, wipe_size);
|
||||
|
@ -859,7 +861,7 @@ static s64 wipe_index_allocation (ntfs_volume *vol, int byte, enum action act,
|
|||
if (opts.verbose > 1)
|
||||
Vprintf ("x");
|
||||
}
|
||||
|
||||
|
||||
wiped = ntfs_rl_pwrite (vol, naa->rl, offset, indx_record_size, buf);
|
||||
if (wiped != indx_record_size) {
|
||||
Vprintf ("ntfs_rl_pwrite failed\n");
|
||||
|
@ -895,13 +897,13 @@ free_bitmap:
|
|||
static u32 get_indx_record_size (ntfs_attr *nar)
|
||||
{
|
||||
u32 indx_record_size;
|
||||
|
||||
|
||||
if (ntfs_attr_pread (nar, 8, 4, &indx_record_size) != 4) {
|
||||
Vprintf ("Couldn't determine size of INDX record\n");
|
||||
Eprintf ("ntfs_attr_pread failed");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
indx_record_size = le32_to_cpu (indx_record_size);
|
||||
if (!indx_record_size) {
|
||||
Vprintf ("Internal error\n");
|
||||
|
@ -968,7 +970,7 @@ static s64 wipe_directory (ntfs_volume *vol, int byte, enum action act)
|
|||
Vprintf ("\r");
|
||||
goto close_inode;
|
||||
}
|
||||
|
||||
|
||||
if (!NAttrNonResident(naa)) {
|
||||
Vprintf ("Resident $INDEX_ALLOCATION\n");
|
||||
Eprintf ("damaged fs: Resident $INDEX_ALLOCATION "
|
||||
|
@ -991,7 +993,7 @@ static s64 wipe_directory (ntfs_volume *vol, int byte, enum action act)
|
|||
"name (inode %lld)\n", inode_num);
|
||||
goto close_attr_allocation;
|
||||
}
|
||||
|
||||
|
||||
nar = ntfs_attr_open (ni, AT_INDEX_ROOT, I30, 4);
|
||||
if (!nar) {
|
||||
Vprintf ("Couldn't open $INDEX_ROOT\n");
|
||||
|
@ -1000,27 +1002,27 @@ static s64 wipe_directory (ntfs_volume *vol, int byte, enum action act)
|
|||
" (inode %lld)\n", inode_num);
|
||||
goto close_attr_bitmap;
|
||||
}
|
||||
|
||||
|
||||
if (NAttrNonResident(nar)) {
|
||||
Vprintf ("Not resident $INDEX_ROOT\n");
|
||||
Eprintf ("damaged fs: Not resident $INDEX_ROOT "
|
||||
"(inode %lld)\n", inode_num);
|
||||
goto close_attr_root;
|
||||
}
|
||||
|
||||
|
||||
indx_record_size = get_indx_record_size (nar);
|
||||
if (!indx_record_size) {
|
||||
Eprintf (" (inode %lld)\n", inode_num);
|
||||
goto close_attr_root;
|
||||
}
|
||||
|
||||
|
||||
wiped = wipe_index_allocation (vol, byte, act,
|
||||
naa, nab, indx_record_size);
|
||||
if (wiped == -1) {
|
||||
Eprintf (" (inode %lld)\n", inode_num);
|
||||
goto close_attr_root;
|
||||
}
|
||||
|
||||
|
||||
if (wiped) {
|
||||
Vprintf ("Wiped %llu bytes\n", wiped);
|
||||
total += wiped;
|
||||
|
@ -1053,7 +1055,8 @@ close_inode:
|
|||
* 0 Nothing to wipe
|
||||
* -1 Error, something went wrong
|
||||
*/
|
||||
static s64 wipe_logfile (ntfs_volume *vol, int byte, enum action act)
|
||||
static s64 wipe_logfile (ntfs_volume *vol, int byte, enum action act
|
||||
__attribute__((unused)))
|
||||
{
|
||||
const int NTFS_BUF_SIZE2 = 8192;
|
||||
//FIXME(?): We might need to zero the LSN field of every single mft
|
||||
|
@ -1064,7 +1067,7 @@ static s64 wipe_logfile (ntfs_volume *vol, int byte, enum action act)
|
|||
s64 len, pos, count;
|
||||
char buf[NTFS_BUF_SIZE2];
|
||||
int eo;
|
||||
|
||||
|
||||
/* We can wipe logfile only with 0xff. */
|
||||
byte = 0xff;
|
||||
|
||||
|
@ -1160,7 +1163,8 @@ error_exit:
|
|||
* 0 Nothing to wipe
|
||||
* -1 Error, something went wrong
|
||||
*/
|
||||
static s64 wipe_pagefile (ntfs_volume *vol, int byte, enum action act)
|
||||
static s64 wipe_pagefile (ntfs_volume *vol, int byte, enum action act
|
||||
__attribute__((unused)))
|
||||
{
|
||||
// wipe completely, chkdsk doesn't do anything, booting writes header
|
||||
const int NTFS_BUF_SIZE2 = 4096;
|
||||
|
@ -1174,7 +1178,7 @@ static s64 wipe_pagefile (ntfs_volume *vol, int byte, enum action act)
|
|||
return -1;
|
||||
|
||||
//Qprintf ("wipe_pagefile (not implemented) 0x%02x\n", byte);
|
||||
|
||||
|
||||
ni = ntfs_pathname_to_inode(vol, NULL, "pagefile.sys");
|
||||
if (!ni) {
|
||||
Dprintf("Failed to open inode of pagefile.sys.\n");
|
||||
|
|
|
@ -27,10 +27,10 @@
|
|||
* Do NOT free *@sd_val as it is static memory. This also means that you can
|
||||
* only use *@sd_val until the next call to this function.
|
||||
*/
|
||||
void init_system_file_sd(int sys_file_no, char **sd_val, int *sd_val_len);
|
||||
void init_system_file_sd(int sys_file_no, char **sd_val, int *sd_val_len)
|
||||
void init_system_file_sd(int sys_file_no, u8 **sd_val, int *sd_val_len);
|
||||
void init_system_file_sd(int sys_file_no, u8 **sd_val, int *sd_val_len)
|
||||
{
|
||||
static char sd_array[0x68];
|
||||
static u8 sd_array[0x68];
|
||||
SECURITY_DESCRIPTOR_RELATIVE *sd;
|
||||
ACL *acl;
|
||||
ACCESS_ALLOWED_ACE *aa_ace;
|
||||
|
@ -41,7 +41,7 @@ void init_system_file_sd(int sys_file_no, char **sd_val, int *sd_val_len)
|
|||
*sd_val_len = 0;
|
||||
return;
|
||||
}
|
||||
*sd_val = (char*)&sd_array;
|
||||
*sd_val = sd_array;
|
||||
sd = (SECURITY_DESCRIPTOR_RELATIVE*)&sd_array;
|
||||
sd->revision = 1;
|
||||
sd->alignment = 0;
|
||||
|
|
Loading…
Reference in New Issue