Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/ntfstools
In directory usw-pr-cvs1:/tmp/cvs-serv22856/ntfstools
Modified Files:
mkntfs.c
Log Message:
getting closer to mkntfs alpha.
Index: mkntfs.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/mkntfs.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -U2 -r1.15 -r1.16
--- mkntfs.c 2001/06/08 14:09:52 1.15
+++ mkntfs.c 2001/06/08 19:58:25 1.16
@@ -1008,5 +1008,5 @@
a->length = cpu_to_le32(new_alen);
a->value_length = cpu_to_le32(new_vsize);
- return -ENOTSUP;
+ return 0;
}
@@ -1601,5 +1601,5 @@
if (!fn)
return -errno;
- fn->parent_directory = cpu_to_le64(parent_dir);
+ fn->parent_directory = parent_dir;
// FIXME: Is this correct? Or do we have to copy the creation_time
// from the std info?
@@ -1765,5 +1765,5 @@
if (err < 0)
Eprintf("add_attr_vol_info failed: %s\n", strerror(-err));
- return err;;
+ return err;
}
@@ -1937,5 +1937,6 @@
index_block_size = le32_to_cpu(r->index_block_size);
memset(bmp, 0, sizeof(bmp));
- ntfs_set_bit(&bmp, 0, 1);
+ ntfs_set_bit(&bmp, 0ULL, 1);
+ Dprintf("bmp = 0x%Lx\n", *(__u64*)&bmp);
/* Bitmap has to be at least 8 bytes in size. */
err = add_attr_bitmap(m, name, name_len, ic, upcase, upcase_len,
@@ -1980,6 +1981,6 @@
/* Copy all the entries including the termination entry. */
i = (char*)re - re_start + le16_to_cpu(re->length);
- memcpy((char*)ia_val + le32_to_cpu(ia_val->index.entries_offset),
- re_start, i);
+ memcpy((char*)&ia_val->index +
+ le32_to_cpu(ia_val->index.entries_offset), re_start, i);
/* Finish setting up index allocation. */
ia_val->index.index_length = cpu_to_le32(i +
@@ -2020,7 +2021,7 @@
err = add_attr_index_alloc(m, name, name_len, ic, upcase, upcase_len,
(char*)ia_val, index_block_size);
+ __post_read_mst_fixup((NTFS_RECORD*)ia_val, index_block_size);
if (err) {
// TODO: Remove the added bitmap!
- __post_read_mst_fixup((NTFS_RECORD*)ia_val, index_block_size);
// Revert index root from index allocation.
free(ia_val);
@@ -2064,5 +2065,6 @@
return -EINVAL;
/* The - sizeof(INDEX_ENTRY_HEADER) is for the index terminator. */
- if ((char*)pos - (char*)index > le32_to_cpu(index->index.index_length)
+ if ((char*)pos - (char*)&index->index >
+ le32_to_cpu(index->index.index_length)
- sizeof(INDEX_ENTRY_HEADER))
return -EINVAL;
@@ -2134,8 +2136,12 @@
do_next:
/* Next entry. */
+ if (!ie->length) {
+ Dprintf("ie->length is zero, breaking out of loop.\n");
+ break;
+ }
ie = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
};
- err = make_room_for_index_entry_in_index_block(index, ie,
- file_name_size);
+ i = sizeof(INDEX_ENTRY_HEADER) + file_name_size + 7 & ~7;
+ err = make_room_for_index_entry_in_index_block(index, ie, i);
if (err) {
Eprintf("make_room_for_index_entry_in_index_block failed: "
@@ -2145,8 +2151,7 @@
/* Create entry in place and copy file name attribute value. */
ie->indexed_file = file_ref;
- ie->length = cpu_to_le16(sizeof(INDEX_ENTRY_HEADER) + file_name_size +
- 7 & ~7);
+ ie->length = cpu_to_le16(i);
ie->key_length = cpu_to_le16(file_name_size);
- ie->flags = 0;
+ ie->flags = cpu_to_le16(0);
ie->reserved = cpu_to_le16(0);
memcpy((char*)&ie->key.file_name, (char*)file_name, file_name_size);
@@ -2154,4 +2159,87 @@
}
+/*
+ * Create a file_name_attribute in the mft record @m_file which points to the
+ * parent directory with mft reference @ref_parent.
+ *
+ * Then, insert an index entry with this file_name_attribute in the index
+ * block @index of the index allocation attribute of the parent directory.
+ *
+ * @ref_file is the mft reference of @m_file.
+ *
+ * Return 0 on success or -errno on error.
+ */
+int create_hardlink(INDEX_BLOCK *index, const MFT_REF ref_parent,
+ MFT_RECORD *m_file, const MFT_REF ref_file,
+ const __s64 allocated_size, const __s64 data_size,
+ const FILE_ATTR_FLAGS flags, const __u16 packed_ea_size,
+ const __u32 reparse_point_tag, const char *file_name,
+ const FILE_NAME_TYPE_FLAGS file_name_type)
+{
+ FILE_NAME_ATTR *fn;
+ int i, fn_size;
+
+ /* Create the file_name attribute. */
+ i = (strlen(file_name) + 1) * sizeof(uchar_t);
+ fn_size = sizeof(FILE_NAME_ATTR) + i;
+ fn = (FILE_NAME_ATTR*)malloc(fn_size);
+ if (!fn)
+ return -errno;
+ fn->parent_directory = ref_parent;
+ // FIXME: Is this correct? Or do we have to copy the creation_time
+ // from the std info?
+ fn->creation_time = time2ntfs(time(NULL));
+ fn->last_data_change_time = fn->creation_time;
+ fn->last_mft_change_time = fn->creation_time;
+ fn->last_access_time = fn->creation_time;
+ fn->allocated_size = cpu_to_le64(allocated_size);
+ fn->data_size = cpu_to_le64(data_size);
+ fn->file_attributes = flags;
+ /* These are in a union so can't have both. */
+ if (packed_ea_size && reparse_point_tag) {
+ free(fn);
+ return -EINVAL;
+ }
+ if (packed_ea_size) {
+ fn->packed_ea_size = cpu_to_le16(packed_ea_size);
+ fn->reserved = cpu_to_le16(0);
+ } else
+ fn->reparse_point_tag = cpu_to_le32(reparse_point_tag);
+ fn->file_name_type = file_name_type;
+ i = stoucs(fn->file_name, file_name, i);
+ if (i < 1) {
+ free(fn);
+ return -EINVAL;
+ }
+ if (i > 0xff) {
+ free(fn);
+ return -ENAMETOOLONG;
+ }
+ /* No terminating null in file names. */
+ fn->file_name_length = i;
+ fn_size = sizeof(FILE_NAME_ATTR) + i * sizeof(uchar_t);
+ /* Add the file_name to @m_file. */
+ i = insert_resident_attr_in_mft_record(m_file, $FILE_NAME, NULL, 0, 0,
+ NULL, 0, 0, RESIDENT_ATTR_IS_INDEXED, (char*)fn,
+ fn_size);
+ if (i < 0) {
+ Eprintf("create_hardlink failed adding file name attribute: "
+ "%s\n", strerror(-i));
+ free(fn);
+ return i;
+ }
+ /* Insert the index entry for file_name in @index. */
+ i = insert_file_link_in_dir_index(index, ref_file, fn, fn_size);
+ if (i < 0) {
+ Eprintf("create_hardlink failed inserting index entry: %s\n",
+ strerror(-i));
+ /* FIXME: Remove the file name attribute from @m_file. */
+ free(fn);
+ return i;
+ }
+ free(fn);
+ return 0;
+}
+
void init_options(void)
{
@@ -2648,9 +2736,8 @@
m = (MFT_RECORD*)(buf + 5 * opt.mft_record_size);
m->flags |= MFT_RECORD_IS_DIRECTORY;
- if (!err)
- err = add_attr_file_name(m, root_ref, 0LL, 0LL,
- FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
- FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT, 0, 0,
- ".", FILE_NAME_WIN32_AND_DOS);
+ err = add_attr_file_name(m, root_ref, 0LL, 0LL,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM |
+ FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT, 0, 0,
+ ".", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$root, &sd, &i);
@@ -2661,8 +2748,7 @@
opt.upcase_len, $FILE_NAME, COLLATION_FILE_NAME,
opt.index_block_size);
- if (!err) {
+ if (!err)
err = upgrade_to_large_index(m, "$I30", 4, IGNORE_CASE,
opt.upcase, opt.upcase_len, &index_block);
- }
if (!err) {
memset(&ctx, 0, sizeof(ctx));
@@ -2681,36 +2767,5 @@
err_exit("Couldn't create root directory: %s\n",
strerror(-err));
- // move this to the end after verifying it works ok so far
- /* Sync the root directory's index block @index to disk. */
- Dprintf("Syncing root directory index record.\n");
- i = 5 * sizeof(uchar_t);
- ustr = (uchar_t*)calloc(1, i);
- if (!ustr)
- err_exit("Not enough memory to allocate internal buffer.\n");;
- j = stoucs(ustr, "$I30", i);
- memset(&ctx, 0, sizeof(ctx));
- ctx.mrec = m;
- if (!find_first_attr($INDEX_ALLOCATION, ustr, j, IGNORE_CASE,
- opt.upcase, opt.upcase_len, NULL, 0, &ctx))
- err_exit("BUG: $INDEX_ALLOCATION attribute not found.\n");
- a = ctx.attr;
- i = sizeof(INDEX_BLOCK) - sizeof(INDEX_HEADER) +
- le32_to_cpu(index_block->index.allocated_size);
- if (sle64_to_cpu(a->initialized_size) < i)
- err_exit("BUG: $INDEX_ALLOCATION attribute too short.\n");
- rl_index = decompress_run_list(a);
- if (!rl_index)
- err_exit("Failed to decompress run list of $INDEX_ALLOCATION "
- "attribute.\n");
- err = pre_write_mst_fixup((NTFS_RECORD*)index_block, i);
- if (err)
- err_exit("pre_write_mst_fixup() failed while syncing root "
- "directory index block.\n");
- lw = ntfs_rlwrite(f, rl_index, (char*)index_block, i, NULL);
- if (lw != i)
- err_exit("Error writing $INDEX_ALLOCATION.\n");
- __post_read_mst_fixup((NTFS_RECORD*)index_block, i);
- // move down up to here
- dump_mft_record(m);
+ // dump_mft_record(m);
/* Add all other attributes, on a per-file basis for clarity. */
Dprintf("Creating $MFT (mft record 0)\n");
@@ -3010,4 +3065,34 @@
// applicable). Possibly should move this as far to the top as possible and
// update during each subsequent c&w of each system file.
+ Dprintf("Syncing root directory index record.\n");
+ m = (MFT_RECORD*)(buf + 5 * opt.mft_record_size);
+ i = 5 * sizeof(uchar_t);
+ ustr = (uchar_t*)calloc(1, i);
+ if (!ustr)
+ err_exit("Not enough memory to allocate internal buffer.\n");;
+ j = stoucs(ustr, "$I30", i);
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.mrec = m;
+ if (!find_first_attr($INDEX_ALLOCATION, ustr, j, IGNORE_CASE,
+ opt.upcase, opt.upcase_len, NULL, 0, &ctx))
+ err_exit("BUG: $INDEX_ALLOCATION attribute not found.\n");
+ a = ctx.attr;
+ rl_index = decompress_run_list(a);
+ if (!rl_index)
+ err_exit("Failed to decompress run list of $INDEX_ALLOCATION "
+ "attribute.\n");
+ if (sle64_to_cpu(a->initialized_size) < i)
+ err_exit("BUG: $INDEX_ALLOCATION attribute too short.\n");
+ i = sizeof(INDEX_BLOCK) - sizeof(INDEX_HEADER) +
+ le32_to_cpu(index_block->index.allocated_size);
+ err = pre_write_mst_fixup((NTFS_RECORD*)index_block, i);
+ if (!err)
+ err_exit("pre_write_mst_fixup() failed while syncing root "
+ "directory index block.\n");
+ lw = ntfs_rlwrite(f, rl_index, (char*)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: */
+ // __post_read_mst_fixup((NTFS_RECORD*)index_block, i);
Dprintf("Syncing $Bitmap.\n");
m = (MFT_RECORD*)(buf + 6 * opt.mft_record_size);
|