wipe_tails:
* proper implementation of wipe_compressed_attribute * various fixes (Logical change 1.444)edge.strict_endians
parent
2e579e14a7
commit
07ef30bdf6
|
|
@ -398,64 +398,47 @@ free:
|
||||||
* wipe_compressed_attribute - Wipe compressed $DATA attribute
|
* wipe_compressed_attribute - Wipe compressed $DATA attribute
|
||||||
* @vol: An ntfs volume obtained from ntfs_mount
|
* @vol: An ntfs volume obtained from ntfs_mount
|
||||||
* @byte: Overwrite with this value
|
* @byte: Overwrite with this value
|
||||||
|
* @na: Opened ntfs attribute
|
||||||
* @act: Wipe, test or info
|
* @act: Wipe, test or info
|
||||||
* @attr: A vaild $DATA attribute record
|
|
||||||
* @compr_unit: Compression unit obtained from first $DATA attribute (because in other
|
|
||||||
* it 0)
|
|
||||||
* @tail: If last is not compressed, how many we have to wipe in it end
|
|
||||||
*
|
*
|
||||||
* Return: >0 Success, the atrribute was wiped
|
* Return: >0 Success, the atrribute was wiped
|
||||||
* 0 Nothing to wipe
|
* 0 Nothing to wipe
|
||||||
* -1 Error, something went wrong
|
* -1 Error, something went wrong
|
||||||
*/
|
*/
|
||||||
static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte, enum action act,
|
static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte, ntfs_attr *na,
|
||||||
ATTR_RECORD *attr, u8 compr_unit, u32 tail)
|
enum action act)
|
||||||
{
|
{
|
||||||
runlist *rl;
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
s64 size;
|
s64 size;
|
||||||
u64 offset;
|
u64 offset;
|
||||||
u16 block_size;
|
u16 block_size;
|
||||||
u64 wiped = 0;
|
|
||||||
s64 ret;
|
s64 ret;
|
||||||
runlist *rlc;
|
u64 wiped = 0;
|
||||||
u64 cu_mask;
|
VCN cur_vcn = 0;
|
||||||
|
runlist *rlc = na->rl;
|
||||||
if (compr_unit != 4)
|
u64 cu_mask = na->compression_block_clusters - 1;
|
||||||
Eprintf ("strange: compression unit is %u (not 4)\n", compr_unit);
|
|
||||||
|
|
||||||
if (!compr_unit) {
|
|
||||||
Vprintf ("Internal error\n");
|
|
||||||
Eprintf ("Compression unit could not be 0");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
cu_mask = (1 << compr_unit) - 1;
|
|
||||||
|
|
||||||
rl = ntfs_mapping_pairs_decompress(vol, attr, 0);
|
|
||||||
if (!rl) {
|
|
||||||
Vprintf ("Internal error\n");
|
|
||||||
Eprintf ("Could not decompress mapping pairs inode");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
rlc = rl;
|
|
||||||
while (rlc->length) {
|
while (rlc->length) {
|
||||||
if ((!(rlc->length & cu_mask) && ((rlc+1)->length || !tail))
|
cur_vcn += rlc->length;
|
||||||
|| (rlc->lcn < 0)) {
|
if ((cur_vcn & cu_mask) ||
|
||||||
|
(((rlc + 1)->length) && (rlc->lcn != LCN_HOLE))) {
|
||||||
rlc++;
|
rlc++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rlc->length & cu_mask) {
|
if (rlc->lcn == LCN_HOLE) {
|
||||||
offset = (rlc->length & (~cu_mask)) << vol->cluster_size_bits;
|
offset = cur_vcn - rlc->length;
|
||||||
|
if (offset == (offset & (~cu_mask))) {
|
||||||
|
rlc++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
offset = (offset & (~cu_mask)) << vol->cluster_size_bits;
|
||||||
while (1) {
|
while (1) {
|
||||||
ret = ntfs_rl_pread (vol, rlc, offset, 2, &block_size);
|
ret = ntfs_rl_pread (vol, na->rl, offset, 2, &block_size);
|
||||||
if (ret != 2) {
|
if (ret != 2) {
|
||||||
Vprintf ("Internal error\n");
|
Vprintf ("Internal error\n");
|
||||||
Eprintf ("ntfs_rl_pread failed");
|
Eprintf ("ntfs_rl_pread failed");
|
||||||
wiped = -1;
|
return -1;
|
||||||
goto free_rl;
|
|
||||||
}
|
}
|
||||||
if (block_size == 0) {
|
if (block_size == 0) {
|
||||||
offset += 2;
|
offset += 2;
|
||||||
|
|
@ -464,15 +447,24 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte, enum action ac
|
||||||
block_size &= 0x0FFF;
|
block_size &= 0x0FFF;
|
||||||
block_size += 3;
|
block_size += 3;
|
||||||
offset += block_size;
|
offset += block_size;
|
||||||
if (offset >= (rlc->length << vol->cluster_size_bits) - 2)
|
if (offset >= (((cur_vcn - rlc->length)
|
||||||
|
<< vol->cluster_size_bits) - 2))
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
size = (rlc->length << vol->cluster_size_bits) - offset;
|
size = ((cur_vcn - rlc->length)
|
||||||
|
<< vol->cluster_size_bits) - offset;
|
||||||
} else {
|
} else {
|
||||||
size = tail;
|
size = na->allocated_size - na->data_size;
|
||||||
offset = (rlc->length << vol->cluster_size_bits) - tail;
|
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)) {
|
if ((act == act_info) || (!size)) {
|
||||||
wiped += size;
|
wiped += size;
|
||||||
rlc++;
|
rlc++;
|
||||||
|
|
@ -483,26 +475,22 @@ static s64 wipe_compressed_attribute (ntfs_volume *vol, int byte, enum action ac
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
Vprintf ("Not enough memory\n");
|
Vprintf ("Not enough memory\n");
|
||||||
Eprintf ("Not enough memory to allocate %lld bytes", size);
|
Eprintf ("Not enough memory to allocate %lld bytes", size);
|
||||||
wiped = -1;
|
return -1;
|
||||||
goto free_rl;
|
|
||||||
}
|
}
|
||||||
memset (buf, byte, size);
|
memset (buf, byte, size);
|
||||||
|
|
||||||
ret = ntfs_rl_pwrite (vol, rlc, offset, size, buf);
|
ret = ntfs_rl_pwrite (vol, na->rl, offset, size, buf);
|
||||||
|
free (buf);
|
||||||
if (ret != size) {
|
if (ret != size) {
|
||||||
Vprintf ("Internal error\n");
|
Vprintf ("Internal error\n");
|
||||||
Eprintf ("ntfs_rl_pwrite failed");
|
Eprintf ("ntfs_rl_pwrite failed");
|
||||||
free (buf);
|
return -1;
|
||||||
wiped = -1;
|
|
||||||
goto free_rl;
|
|
||||||
}
|
}
|
||||||
free (buf);
|
|
||||||
wiped += ret;
|
wiped += ret;
|
||||||
next:
|
next:
|
||||||
rlc++;
|
rlc++;
|
||||||
}
|
}
|
||||||
free_rl:
|
|
||||||
free (rl);
|
|
||||||
return wiped;
|
return wiped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -510,19 +498,28 @@ free_rl:
|
||||||
* wipe_attribute - Wipe not compressed $DATA attribute
|
* wipe_attribute - Wipe not compressed $DATA attribute
|
||||||
* @vol: An ntfs volume obtained from ntfs_mount
|
* @vol: An ntfs volume obtained from ntfs_mount
|
||||||
* @byte: Overwrite with this value
|
* @byte: Overwrite with this value
|
||||||
* @attr: A vaild $DATA attribute record
|
* @na: Opened ntfs attribute
|
||||||
* @size: How many bytes to wipe
|
* @act: Wipe, test or info
|
||||||
* @offset: Offset where start wiping
|
|
||||||
*
|
*
|
||||||
* Return: >0 Success, the atrribute was wiped
|
* Return: >0 Success, the atrribute was wiped
|
||||||
|
* 0 Nothing to wipe
|
||||||
* -1 Error, something went wrong
|
* -1 Error, something went wrong
|
||||||
*/
|
*/
|
||||||
static s64 wipe_attribute (ntfs_volume *vol, int byte, ATTR_RECORD *attr,
|
static s64 wipe_attribute (ntfs_volume *vol, int byte, ntfs_attr *na, enum action act)
|
||||||
s64 size, u64 offset)
|
|
||||||
{
|
{
|
||||||
runlist *rl;
|
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
s64 wiped;
|
s64 wiped;
|
||||||
|
s64 size;
|
||||||
|
u64 offset = na->data_size;
|
||||||
|
|
||||||
|
if (!offset)
|
||||||
|
return 0;
|
||||||
|
if (NAttrEncrypted(na))
|
||||||
|
offset = (((offset - 1) >> 10) + 1) << 10;
|
||||||
|
size = (vol->cluster_size - offset) % vol->cluster_size;
|
||||||
|
|
||||||
|
if (act == act_info)
|
||||||
|
return size;
|
||||||
|
|
||||||
buf = malloc (size);
|
buf = malloc (size);
|
||||||
if (!buf) {
|
if (!buf) {
|
||||||
|
|
@ -532,22 +529,12 @@ static s64 wipe_attribute (ntfs_volume *vol, int byte, ATTR_RECORD *attr,
|
||||||
}
|
}
|
||||||
memset (buf, byte, size);
|
memset (buf, byte, size);
|
||||||
|
|
||||||
rl = ntfs_mapping_pairs_decompress(vol, attr, 0);
|
wiped = ntfs_rl_pwrite (vol, na->rl, offset, size, buf);
|
||||||
if (!rl) {
|
|
||||||
Vprintf ("Internal error\n");
|
|
||||||
Eprintf ("Could not decompress mapping pairs");
|
|
||||||
wiped = -1;
|
|
||||||
goto free_buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
wiped = ntfs_rl_pwrite (vol, rl, offset, size, buf);
|
|
||||||
if (wiped == -1) {
|
if (wiped == -1) {
|
||||||
Vprintf ("Internal error\n");
|
Vprintf ("Internal error\n");
|
||||||
Eprintf ("Couldn't wipe tail");
|
Eprintf ("Couldn't wipe tail");
|
||||||
}
|
}
|
||||||
|
|
||||||
free (rl);
|
|
||||||
free_buf:
|
|
||||||
free (buf);
|
free (buf);
|
||||||
return wiped;
|
return wiped;
|
||||||
}
|
}
|
||||||
|
|
@ -569,9 +556,8 @@ static s64 wipe_tails (ntfs_volume *vol, int byte, enum action act)
|
||||||
{
|
{
|
||||||
s64 total = 0;
|
s64 total = 0;
|
||||||
s64 inode_num;
|
s64 inode_num;
|
||||||
ntfs_attr_search_ctx *ctx;
|
|
||||||
ntfs_inode *ni;
|
ntfs_inode *ni;
|
||||||
ATTR_RECORD *attr;
|
ntfs_attr *na;
|
||||||
|
|
||||||
if (!vol || (byte < 0))
|
if (!vol || (byte < 0))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
@ -583,94 +569,51 @@ static s64 wipe_tails (ntfs_volume *vol, int byte, enum action act)
|
||||||
Vprintf ("Could not open inode\n");
|
Vprintf ("Could not open inode\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ni->mrec->base_mft_record) {
|
if (ni->mrec->base_mft_record) {
|
||||||
Vprintf ("Not base mft record. Skipping\n");
|
Vprintf ("Not base mft record. Skipping\n");
|
||||||
goto close_inode;
|
goto close_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = ntfs_attr_get_search_ctx(ni, 0);
|
na = ntfs_attr_open (ni, AT_DATA, AT_UNNAMED, 0);
|
||||||
if (!ctx) {
|
if (!na) {
|
||||||
Vprintf ("Internal error\n");
|
Vprintf ("Couldn't open $DATA attribute\n");
|
||||||
Eprintf ("Could not get search context (inode %lld)\n",inode_num);
|
|
||||||
goto close_inode;
|
goto close_inode;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 wiped_in_file = 0;
|
if (!NAttrNonResident(na)) {
|
||||||
u8 compr_unit;
|
Vprintf ("Resident $DATA atrribute. Skipping.\n");
|
||||||
s64 size = -1;
|
goto close_attr;
|
||||||
u64 offset;
|
|
||||||
VCN last_vcn;
|
|
||||||
u32 tail;
|
|
||||||
ATTR_RECORD *first_attr = 0;
|
|
||||||
while (!ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
|
|
||||||
attr = ctx->attr;
|
|
||||||
|
|
||||||
if (!attr->non_resident) {
|
|
||||||
Vprintf ("Resident $DATA atrribute. Skipping.\n");
|
|
||||||
goto put_search_ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!first_attr) {
|
|
||||||
first_attr = attr;
|
|
||||||
if (attr->compression_unit) {
|
|
||||||
compr_unit = attr->compression_unit;
|
|
||||||
tail = attr->allocated_size - attr->data_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s64 wiped;
|
|
||||||
if (first_attr->flags & ATTR_IS_COMPRESSED) {
|
|
||||||
Vprintf ("Compressed $DATA attribute. Not supported yet ;(\n");
|
|
||||||
goto put_search_ctx;
|
|
||||||
// wiped = wipe_compressed_attribute (vol, byte, act,
|
|
||||||
// attr, compr_unit, tail);
|
|
||||||
} else {
|
|
||||||
if (size == -1) {
|
|
||||||
offset = attr->data_size;
|
|
||||||
if (!offset)
|
|
||||||
break;
|
|
||||||
if (attr->flags & ATTR_IS_ENCRYPTED)
|
|
||||||
offset = (((offset - 1) >> 10) + 1) << 10;
|
|
||||||
size = (vol->cluster_size - offset) %
|
|
||||||
vol->cluster_size;
|
|
||||||
last_vcn = attr->data_size >>
|
|
||||||
vol->cluster_size_bits;
|
|
||||||
}
|
|
||||||
if (!size) {
|
|
||||||
wiped_in_file = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (act == act_info) {
|
|
||||||
wiped_in_file = size;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (attr->highest_vcn == last_vcn)
|
|
||||||
wiped = wipe_attribute (vol, byte, attr,
|
|
||||||
size, offset);
|
|
||||||
else
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (wiped != -1)
|
|
||||||
wiped_in_file += wiped;
|
|
||||||
else {
|
|
||||||
Eprintf (" (inode %lld)\n", inode_num);
|
|
||||||
goto put_search_ctx;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wiped_in_file) {
|
if (ntfs_attr_map_whole_runlist(na)) {
|
||||||
Vprintf ("Wiped %llu bytes\n", wiped_in_file);
|
Vprintf ("Internal error\n");
|
||||||
total += wiped_in_file;
|
Eprintf ("Couldn't map runlist (inode %lld)", inode_num);
|
||||||
|
goto close_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
s64 wiped;
|
||||||
|
if (NAttrCompressed(na))
|
||||||
|
wiped = wipe_compressed_attribute (vol, byte, na, act);
|
||||||
|
else
|
||||||
|
wiped = wipe_attribute (vol, byte, na, act);
|
||||||
|
|
||||||
|
if (wiped == -1) {
|
||||||
|
Eprintf (" (inode %lld)\n", inode_num);
|
||||||
|
goto close_attr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (wiped) {
|
||||||
|
Vprintf ("Wiped %llu bytes\n", wiped);
|
||||||
|
total += wiped;
|
||||||
} else
|
} else
|
||||||
Vprintf ("Nothing to wipe\n");
|
Vprintf ("Nothing to wipe\n");
|
||||||
put_search_ctx:
|
close_attr:
|
||||||
ntfs_attr_put_search_ctx (ctx);
|
ntfs_attr_close (na);
|
||||||
close_inode:
|
close_inode:
|
||||||
ntfs_inode_close (ni);
|
ntfs_inode_close (ni);
|
||||||
}
|
}
|
||||||
Qprintf ("wipe_tails 0x%02x, %lld bytes\n", byte, (long long)total);
|
Qprintf ("wipe_tails 0x%02x, %lld bytes\n", byte, total);
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue