NTFS: Merge changes to the utils from upstream.
This commit is contained in:
parent
01339a54db
commit
763047bfb1
@ -6,7 +6,7 @@
|
|||||||
* Copyright (c) 2002-2006 Szabolcs Szakacsits
|
* Copyright (c) 2002-2006 Szabolcs Szakacsits
|
||||||
* Copyright (c) 2005 Erik Sornes
|
* Copyright (c) 2005 Erik Sornes
|
||||||
* Copyright (c) 2007 Yura Pakhuchiy
|
* Copyright (c) 2007 Yura Pakhuchiy
|
||||||
* Copyright (c) 2010 Jean-Pierre Andre
|
* Copyright (c) 2010-2014 Jean-Pierre Andre
|
||||||
*
|
*
|
||||||
* This utility will create an NTFS 1.2 or 3.1 volume on a user
|
* This utility will create an NTFS 1.2 or 3.1 volume on a user
|
||||||
* specified (block) device.
|
* specified (block) device.
|
||||||
@ -161,6 +161,18 @@ struct BITMAP_ALLOCATION {
|
|||||||
s64 length; /* count of consecutive clusters */
|
s64 length; /* count of consecutive clusters */
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
/* Upcase $Info, used since Windows 8 */
|
||||||
|
struct UPCASEINFO {
|
||||||
|
le32 len;
|
||||||
|
le32 filler;
|
||||||
|
le64 crc;
|
||||||
|
le32 osmajor;
|
||||||
|
le32 osminor;
|
||||||
|
le32 build;
|
||||||
|
le16 packmajor;
|
||||||
|
le16 packminor;
|
||||||
|
} ;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* global variables
|
* global variables
|
||||||
*/
|
*/
|
||||||
@ -170,6 +182,7 @@ static u8 *g_mft_bitmap = NULL;
|
|||||||
static int g_lcn_bitmap_byte_size = 0;
|
static int g_lcn_bitmap_byte_size = 0;
|
||||||
static int g_dynamic_buf_size = 0;
|
static int g_dynamic_buf_size = 0;
|
||||||
static u8 *g_dynamic_buf = NULL;
|
static u8 *g_dynamic_buf = NULL;
|
||||||
|
static struct UPCASEINFO *g_upcaseinfo = NULL;
|
||||||
static runlist *g_rl_mft = NULL;
|
static runlist *g_rl_mft = NULL;
|
||||||
static runlist *g_rl_mft_bmp = NULL;
|
static runlist *g_rl_mft_bmp = NULL;
|
||||||
static runlist *g_rl_mftmirr = NULL;
|
static runlist *g_rl_mftmirr = NULL;
|
||||||
@ -211,6 +224,53 @@ static struct mkntfs_options {
|
|||||||
char *label; /* -L, volume label */
|
char *label; /* -L, volume label */
|
||||||
} opts;
|
} opts;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* crc64, adapted from http://rpm5.org/docs/api/digest_8c-source.html
|
||||||
|
* ECMA-182 polynomial, see
|
||||||
|
* http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-182.pdf
|
||||||
|
*/
|
||||||
|
/* make sure the needed types are defined */
|
||||||
|
#undef byte
|
||||||
|
#undef uint32_t
|
||||||
|
#undef uint64_t
|
||||||
|
#define byte u8
|
||||||
|
#define uint32_t u32
|
||||||
|
#define uint64_t u64
|
||||||
|
static uint64_t crc64(uint64_t crc, const byte * data, size_t size)
|
||||||
|
/*@*/
|
||||||
|
{
|
||||||
|
static uint64_t polynomial = 0x9a6c9329ac4bc9b5ULL;
|
||||||
|
static uint64_t xorout = 0xffffffffffffffffULL;
|
||||||
|
static uint64_t table[256];
|
||||||
|
|
||||||
|
crc ^= xorout;
|
||||||
|
|
||||||
|
if (data == NULL) {
|
||||||
|
/* generate the table of CRC remainders for all possible bytes */
|
||||||
|
uint64_t c;
|
||||||
|
uint32_t i, j;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
c = i;
|
||||||
|
for (j = 0; j < 8; j++) {
|
||||||
|
if (c & 1)
|
||||||
|
c = polynomial ^ (c >> 1);
|
||||||
|
else
|
||||||
|
c = (c >> 1);
|
||||||
|
}
|
||||||
|
table[i] = c;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
while (size) {
|
||||||
|
crc = table[(crc ^ *data) & 0xff] ^ (crc >> 8);
|
||||||
|
size--;
|
||||||
|
data++;
|
||||||
|
}
|
||||||
|
|
||||||
|
crc ^= xorout;
|
||||||
|
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mark a run of clusters as allocated
|
* Mark a run of clusters as allocated
|
||||||
*
|
*
|
||||||
@ -1490,7 +1550,7 @@ static int insert_resident_attr_in_mft_record(MFT_RECORD *m,
|
|||||||
}
|
}
|
||||||
a = ctx->attr;
|
a = ctx->attr;
|
||||||
/* sizeof(resident attribute record header) == 24 */
|
/* sizeof(resident attribute record header) == 24 */
|
||||||
asize = ((24 + ((name_len + 7) & ~7) + val_len) + 7) & ~7;
|
asize = ((24 + ((name_len*2 + 7) & ~7) + val_len) + 7) & ~7;
|
||||||
err = make_room_for_attribute(m, (char*)a, asize);
|
err = make_room_for_attribute(m, (char*)a, asize);
|
||||||
if (err == -ENOSPC) {
|
if (err == -ENOSPC) {
|
||||||
/*
|
/*
|
||||||
@ -4212,6 +4272,14 @@ static BOOL mkntfs_create_root_structures(void)
|
|||||||
m = (MFT_RECORD*)(g_buf + 4 * g_vol->mft_record_size);
|
m = (MFT_RECORD*)(g_buf + 4 * g_vol->mft_record_size);
|
||||||
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE, const_cpu_to_le16(0),
|
err = add_attr_data(m, NULL, 0, CASE_SENSITIVE, const_cpu_to_le16(0),
|
||||||
(u8*)g_vol->attrdef, g_vol->attrdef_len);
|
(u8*)g_vol->attrdef, g_vol->attrdef_len);
|
||||||
|
/*
|
||||||
|
* The $Info only exists since Windows 8, but it apparently
|
||||||
|
* does not disturb chkdsk from earlier versions.
|
||||||
|
*/
|
||||||
|
if (!err)
|
||||||
|
err = add_attr_data(m, "$Info", 5, CASE_SENSITIVE,
|
||||||
|
const_cpu_to_le16(0),
|
||||||
|
(u8*)g_upcaseinfo, sizeof(struct UPCASEINFO));
|
||||||
if (!err)
|
if (!err)
|
||||||
err = create_hardlink(g_index_block, root_ref, m,
|
err = create_hardlink(g_index_block, root_ref, m,
|
||||||
MK_LE_MREF(FILE_AttrDef, FILE_AttrDef),
|
MK_LE_MREF(FILE_AttrDef, FILE_AttrDef),
|
||||||
@ -4572,6 +4640,7 @@ static BOOL mkntfs_create_root_structures(void)
|
|||||||
*/
|
*/
|
||||||
static int mkntfs_redirect(struct mkntfs_options *opts2)
|
static int mkntfs_redirect(struct mkntfs_options *opts2)
|
||||||
{
|
{
|
||||||
|
u64 upcase_crc;
|
||||||
int result = 1;
|
int result = 1;
|
||||||
ntfs_attr_search_ctx *ctx = NULL;
|
ntfs_attr_search_ctx *ctx = NULL;
|
||||||
long long lw, pos;
|
long long lw, pos;
|
||||||
@ -4605,12 +4674,20 @@ static int mkntfs_redirect(struct mkntfs_options *opts2)
|
|||||||
if (opts.cluster_size >= 0)
|
if (opts.cluster_size >= 0)
|
||||||
g_vol->cluster_size = opts.cluster_size;
|
g_vol->cluster_size = opts.cluster_size;
|
||||||
/* Length is in unicode characters. */
|
/* Length is in unicode characters. */
|
||||||
g_vol->upcase_len = 65536;
|
g_vol->upcase_len = ntfs_upcase_build_default(&g_vol->upcase);
|
||||||
g_vol->upcase = ntfs_malloc(g_vol->upcase_len * sizeof(ntfschar));
|
/* Since Windows 8, there is a $Info stream in $UpCase */
|
||||||
if (!g_vol->upcase)
|
g_upcaseinfo =
|
||||||
|
(struct UPCASEINFO*)ntfs_malloc(sizeof(struct UPCASEINFO));
|
||||||
|
if (!g_vol->upcase_len || !g_upcaseinfo)
|
||||||
goto done;
|
goto done;
|
||||||
ntfs_upcase_table_build(g_vol->upcase,
|
/* If the CRC is correct, chkdsk does not warn about obsolete table */
|
||||||
|
crc64(0,(byte*)NULL,0); /* initialize the crc computation */
|
||||||
|
upcase_crc = crc64(0,(byte*)g_vol->upcase,
|
||||||
g_vol->upcase_len * sizeof(ntfschar));
|
g_vol->upcase_len * sizeof(ntfschar));
|
||||||
|
/* keep the version fields as zero */
|
||||||
|
memset(g_upcaseinfo, 0, sizeof(struct UPCASEINFO));
|
||||||
|
g_upcaseinfo->len = const_cpu_to_le32(sizeof(struct UPCASEINFO));
|
||||||
|
g_upcaseinfo->crc = cpu_to_le64(upcase_crc);
|
||||||
g_vol->attrdef = ntfs_malloc(sizeof(attrdef_ntfs3x_array));
|
g_vol->attrdef = ntfs_malloc(sizeof(attrdef_ntfs3x_array));
|
||||||
if (!g_vol->attrdef) {
|
if (!g_vol->attrdef) {
|
||||||
ntfs_log_perror("Could not create attrdef structure");
|
ntfs_log_perror("Could not create attrdef structure");
|
||||||
@ -4805,4 +4882,3 @@ int mkntfs_main(const char *devpath, const char *label)
|
|||||||
|
|
||||||
return mkntfs_redirect(&opts);
|
return mkntfs_redirect(&opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1026,8 +1026,26 @@ int mft_next_record(struct mft_search_ctx *ctx)
|
|||||||
|
|
||||||
ctx->inode = ntfs_inode_open(ctx->vol, (MFT_REF) ctx->mft_num);
|
ctx->inode = ntfs_inode_open(ctx->vol, (MFT_REF) ctx->mft_num);
|
||||||
if (ctx->inode == NULL) {
|
if (ctx->inode == NULL) {
|
||||||
ntfs_log_error("Error reading inode %llu.\n", (unsigned
|
MFT_RECORD *mrec;
|
||||||
long long) ctx->mft_num);
|
int r;
|
||||||
|
MFT_REF base_inode;
|
||||||
|
|
||||||
|
mrec = (MFT_RECORD*)NULL;
|
||||||
|
r = ntfs_file_record_read(ctx->vol,
|
||||||
|
(MFT_REF) ctx->mft_num, &mrec, NULL);
|
||||||
|
if (r || !mrec || !mrec->base_mft_record)
|
||||||
|
ntfs_log_error(
|
||||||
|
"Error reading inode %lld.\n",
|
||||||
|
(long long)ctx->mft_num);
|
||||||
|
else {
|
||||||
|
base_inode = le64_to_cpu(
|
||||||
|
mrec->base_mft_record);
|
||||||
|
ntfs_log_error("Inode %lld is an "
|
||||||
|
"extent of inode %lld.\n",
|
||||||
|
(long long)ctx->mft_num,
|
||||||
|
(long long)MREF(base_inode));
|
||||||
|
}
|
||||||
|
free (mrec);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user