Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/ntfstools
In directory usw-pr-cvs1:/tmp/cvs-serv5692/ntfstools
Modified Files:
mkntfs.c
Log Message:
mkntfs alpha release is here! Yey!
The only thing I am worried about is the fact that the system call to get the
number of sectors on the device returns a value rounded to the nearest 1024
bytes (converted to 512 byte blocks) thus we might be writting the backup boot
sector too early instead of on the real last sector but there is nothing I can
do apart from starting to play games like accessing the main device for hds
instead of the partition device which wouldn't help in the case of the last
partition though... Alternatively have to place the backup boot sector in the
middle of the disk like WinNT3.51 and earlier did but I need an image to see
exactly how they did it and even then we have the problem of not knowing where
the middle of the disk is as we don't really know how many sectors there are
for real with Linux kernel lying to us.
Index: mkntfs.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/mkntfs.c,v
retrieving revision 1.17
retrieving revision 1.18
diff -U2 -r1.17 -r1.18
--- mkntfs.c 2001/06/09 00:25:56 1.17
+++ mkntfs.c 2001/06/09 16:31:13 1.18
@@ -669,5 +669,5 @@
if ((u & ATTR_COMPRESSION_MASK) & ~ATTR_IS_COMPRESSED) {
if (!first)
- printf(" || ");
+ printf(" | ");
else
first = FALSE;
@@ -677,5 +677,5 @@
if (u & ATTR_IS_ENCRYPTED) {
if (!first)
- printf(" || ");
+ printf(" | ");
else
first = FALSE;
@@ -684,5 +684,5 @@
if (u & ATTR_IS_SPARSE) {
if (!first)
- printf(" || ");
+ printf(" | ");
else
first = FALSE;
@@ -724,5 +724,5 @@
printf("MFT_RECORD_NOT_IN_USE");
if (m->flags & MFT_RECORD_IS_DIRECTORY)
- printf(" || MFT_RECORD_IS_DIRECTORY");
+ printf(" | MFT_RECORD_IS_DIRECTORY");
printf("\n");
u = le32_to_cpu(m->bytes_in_use);
@@ -1938,5 +1938,4 @@
memset(bmp, 0, sizeof(bmp));
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,
@@ -1961,6 +1960,4 @@
"system created was corrupt.\nThank you.");
}
- Dprintf("usa count in index block = %i\n",
- cpu_to_le16(ia_val->usa_count));
/* Set USN to 1. */
*(__u16*)((char*)ia_val + le16_to_cpu(ia_val->usa_ofs)) =
@@ -2098,11 +2095,8 @@
/*
* Lookup dir entry @file_name in dir @index to determine correct
- * insertion location.
+ * insertion location. FIXME: Using a very oversimplified lookup
+ * method which is sufficient for mkntfs but no good whatsoever in
+ * real world scenario. (AIA)
*/
- // FIXME: This is written doing a binary comparison of the
- // file_name_attr values. This might NOT be what COLLATION_FILE_NAME
- // means! Check it out!!! It quite probably is a comparison of the
- // actual names within the file_name_attributes rather than this.
- // TODO: It is not correct indeed. Reverse engineering has begun...
index_end = (char*)&index->index +
le32_to_cpu(index->index.index_length);
@@ -2114,31 +2108,83 @@
*/
while ((char*)ie < index_end && !(ie->flags & INDEX_ENTRY_END)) {
- ie_key_len = le16_to_cpu(ie->key_length);
- i = memcmp((char*)&ie->key.file_name, (char*)file_name,
- min(ie_key_len, file_name_size));
- /* Gone too far, thus found insertion location. */
- if (i > 0)
- break;
- /* Perfect match. But what about the lengths? */
- if (!i) {
- /* Gone too far, thus found insertion location. */
- if (ie_key_len > file_name_size)
- break;
- /* Found it. Bugger! Shouldn't be there! */
- if (ie_key_len == file_name_size)
- return -EEXIST;
- /* Name too short, keep looking. */
- /* if (ie_key_len < file_name_size)
- goto do_next; */
+/*
+#ifdef DEBUG
+ Dprintf("file_name_attr1->file_name_length = %i\n",
+ file_name->file_name_length);
+ if (file_name->file_name_length) {
+ char *__buf;
+ __buf = (char*)calloc(1, file_name->file_name_length +
+ 1);
+ if (!__buf)
+ err_exit("Failed to allocate internal buffer: "
+ "%s\n", strerror(errno));
+ i = ucstos(__buf, (uchar_t*)&file_name->file_name,
+ file_name->file_name_length + 1);
+ if (i == -1)
+ Dprintf("Name contains non-displayable "
+ "Unicode characters.\n");
+ Dprintf("file_name_attr1->file_name = %s\n", __buf);
+ free(__buf);
}
- /* Not found it yet, keep looking. */
- /* if (i < 0)
- goto do_next; */
+ Dprintf("file_name_attr2->file_name_length = %i\n",
+ ie->key.file_name.file_name_length);
+ if (ie->key.file_name.file_name_length) {
+ char *__buf;
+ __buf = (char*)calloc(1,
+ ie->key.file_name.file_name_length + 1);
+ if (!__buf)
+ err_exit("Failed to allocate internal buffer: "
+ "%s\n", strerror(errno));
+ i = ucstos(__buf, ie->key.file_name.file_name,
+ ie->key.file_name.file_name_length + 1);
+ if (i == -1)
+ Dprintf("Name contains non-displayable "
+ "Unicode characters.\n");
+ Dprintf("file_name_attr2->file_name = %s\n", __buf);
+ free(__buf);
+ }
+#endif
+*/
+ i = ntfs_file_compare_values(file_name,
+ (FILE_NAME_ATTR*)&ie->key.file_name, 1,
+ IGNORE_CASE, opt.upcase, opt.upcase_len);
+ /*
+ * If @file_name collates before ie->key.file_name, there is no
+ * matching index entry.
+ */
+ if (i == -1)
+ break;
+ /* If file names are not equal, continue search. */
+ if (i)
+ goto do_next;
+ /* File names are equal when compared ignoring case. */
+ /*
+ * If BOTH file names are in the POSIX namespace, do a case
+ * sensitive comparison as well. Otherwise the names match so
+ * we return -EEXIST. FIXME: There are problems with this in a
+ * real world scenario, when one is POSIX and one isn't, but
+ * fine for mkntfs where we don't use POSIX namespace at all
+ * and hence this following code is luxury. (AIA)
+ */
+ if (file_name->file_name_type != FILE_NAME_POSIX ||
+ ie->key.file_name.file_name_type != FILE_NAME_POSIX)
+ return -EEXIST;
+ i = ntfs_file_compare_values(file_name,
+ (FILE_NAME_ATTR*)&ie->key.file_name, 1,
+ CASE_SENSITIVE, opt.upcase, opt.upcase_len);
+ if (i == -1)
+ break;
+ /* Complete match. Bugger. Can't insert. */
+ if (!i)
+ return -EEXIST;
do_next:
+#ifdef DEBUG
/* Next entry. */
if (!ie->length) {
- Dprintf("ie->length is zero, breaking out of loop.\n");
+ Dprintf("BUG: ie->length is zero, breaking out of "
+ "loop.\n");
break;
}
+#endif
ie = (INDEX_ENTRY*)((char*)ie + le16_to_cpu(ie->length));
};
@@ -2428,4 +2474,6 @@
}
Dprintf("number of sectors = %ld\n", opt.nr_sectors);
+ /* Reserve the last sector for the backup boot sector. */
+ opt.nr_sectors--;
/* If user didn't specify the volume size, determine it now. */
if (!opt.volume_size)
@@ -2799,9 +2847,10 @@
buf, opt.mft_record_size * 4);
if (!err)
- err = add_attr_file_name(m, root_ref, opt.mft_record_size * 4 +
- opt.cluster_size - 1 & ~(opt.cluster_size - 1),
- opt.mft_record_size * 4, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$MFTMirr",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$MFTMirr, FILE_$MFTMirr),
+ opt.mft_record_size * 4 + opt.cluster_size - 1
+ & ~(opt.cluster_size - 1), opt.mft_record_size
+ * 4, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$MFTMirr", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$MFTMirr, &sd, &i);
@@ -2823,8 +2872,9 @@
buf2 = NULL;
if (!err)
- err = add_attr_file_name(m, root_ref, opt.logfile_size,
- opt.logfile_size, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$LogFile",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$LogFile, FILE_$LogFile),
+ opt.logfile_size, opt.logfile_size,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$LogFile", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$LogFile, &sd, &i);
@@ -2836,7 +2886,8 @@
Dprintf("Creating $Volume (mft record 3)\n");
m = (MFT_RECORD*)(buf + 3 * opt.mft_record_size);
- err = add_attr_file_name(m, root_ref, 0LL, 0LL, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$Volume",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$Volume, FILE_$Volume), 0LL, 0LL,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$Volume", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$Volume, &sd, &i);
@@ -2869,9 +2920,10 @@
buf2 = NULL;
if (!err)
- err = add_attr_file_name(m, root_ref, buf2_size +
- opt.cluster_size - 1 & ~(opt.cluster_size - 1),
- buf2_size, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$AttrDef",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$AttrDef, FILE_$AttrDef),
+ buf2_size + opt.cluster_size - 1 &
+ ~(opt.cluster_size - 1), buf2_size,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$AttrDef", FILE_NAME_WIN32_AND_DOS);
buf2_size = 0;
if (!err) {
@@ -2887,9 +2939,10 @@
lcn_bitmap_byte_size);
if (!err)
- err = add_attr_file_name(m, root_ref, lcn_bitmap_byte_size +
- opt.cluster_size - 1 & ~(opt.cluster_size - 1),
- lcn_bitmap_byte_size, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$Bitmap",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$Bitmap, FILE_$Bitmap),
+ lcn_bitmap_byte_size + opt.cluster_size - 1 &
+ ~(opt.cluster_size - 1), lcn_bitmap_byte_size,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$Bitmap", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$Bitmap, &sd, &i);
@@ -2909,5 +2962,5 @@
* Create the boot sector into buf2. Note, that buf2 already is zeroed
* in the boot sector section and that it has the NTFS OEM id/magic
- * already inserted, so need to worry about these things.
+ * already inserted, so no need to worry about these things.
*/
bs = (NTFS_BOOT_SECTOR*)buf2;
@@ -2921,8 +2974,5 @@
* setting are: bs->bpb.sectors_per_track, .heads, and .hidden_sectors.
*/
- // FIXME: We should decrement opt.nr_sectors at the beginning, when
- // setting up opt.nr_sectors. Otherwise could end up without a last
- // free sector to work with if we are unlucky...
- bs->number_of_sectors = scpu_to_le64(opt.nr_sectors - 1);
+ bs->number_of_sectors = scpu_to_le64(opt.nr_sectors);
bs->mft_lcn = scpu_to_le64(opt.mft_lcn);
bs->mftmirr_lcn = scpu_to_le64(opt.mftmirr_lcn);
@@ -2969,12 +3019,11 @@
err = add_attr_data_positioned(m, NULL, 0, 0, NULL, 0, 0, rl_boot,
buf2, 8192);
- free(buf2);
- buf2 = NULL;
if (!err)
- err = add_attr_file_name(m, root_ref, 8192 + opt.cluster_size -
- 1 & ~(opt.cluster_size - 1),
- 8192, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$Boot",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$Boot, FILE_$Boot),
+ 8192 + opt.cluster_size - 1 &
+ ~(opt.cluster_size - 1), 8192,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$Boot", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$Boot, &sd, &i);
@@ -2983,4 +3032,25 @@
if (err < 0)
err_exit("Couldn't create $Boot: %s\n", strerror(-err));
+ Dprintf("Creating backup boot sector.\n");
+ /*
+ * Write the first max(512, opt.sector_size) bytes from buf2 to the
+ * last sector.
+ */
+ /* Seek to last cluster. */
+ if (lseek(f, opt.nr_sectors * opt.sector_size, SEEK_SET) == (off_t)-1)
+ err_exit("Couldn't seek to last sector: %s\n", strerror(errno));
+ i = max(512, opt.sector_size);
+ bw = mkntfs_write(f, buf2, i);
+ free(buf2);
+ buf2 = NULL;
+ if (bw != i) {
+ char *_s;
+
+ if (bw == -1LL)
+ _s = strerror(errno);
+ else
+ _s = "unknown error";
+ err_exit("Couldn't write backup boot sector: %s\n", _s);
+ }
//dump_mft_record(m);
Dprintf("Creating $BadClus (mft record 8)\n");
@@ -2994,7 +3064,8 @@
}
if (!err) {
- err = add_attr_file_name(m, root_ref, 0LL, 0LL,
- FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
- "$BadClus", FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$BadClus, FILE_$BadClus),
+ 0LL, 0LL, FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM,
+ 0, 0, "$BadClus", FILE_NAME_WIN32_AND_DOS);
}
if (!err) {
@@ -3009,7 +3080,8 @@
err = add_attr_data(m, NULL, 0, 0, NULL, 0, 0, NULL, 0);
if (!err)
- err = add_attr_file_name(m, root_ref, 0LL, 0LL,
- FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
- "$Quota", FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(9, 9), 0LL, 0LL, FILE_ATTR_HIDDEN
+ | FILE_ATTR_SYSTEM, 0, 0, "$Quota",
+ FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$Secure, &sd, &i);
@@ -3024,9 +3096,10 @@
opt.upcase_len << 1);
if (!err)
- err = add_attr_file_name(m, root_ref, (opt.upcase_len << 1) +
- opt.cluster_size - 1 & ~(opt.cluster_size - 1),
- opt.upcase_len << 1, FILE_ATTR_HIDDEN |
- FILE_ATTR_SYSTEM, 0, 0, "$UpCase",
- FILE_NAME_WIN32_AND_DOS);
+ err = create_hardlink(index_block, root_ref, m,
+ MAKE_MFT_REF(FILE_$UpCase, FILE_$UpCase),
+ (opt.upcase_len << 1) + opt.cluster_size - 1 &
+ ~(opt.cluster_size - 1), opt.upcase_len << 1,
+ FILE_ATTR_HIDDEN | FILE_ATTR_SYSTEM, 0, 0,
+ "$UpCase", FILE_NAME_WIN32_AND_DOS);
if (!err) {
init_system_file_sd(FILE_$UpCase, &sd, &i);
|