| Changes by: antona
Update of /cvsroot/linux-ntfs/linux-ntfs/ntfstools
In directory usw-pr-cvs1:/tmp/cvs-serv32085/ntfstools
Modified Files:
	dumplog.c logfile.c ntfsdump_logfile.c 
Log Message:
dumplog now decodes the first 0x5000 bytes of the logfile given on the command
line as fully as possible with the current knowledge of the logfile structures.
Index: dumplog.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/dumplog.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -U2 -r1.1 -r1.2
--- dumplog.c	2001/06/15 16:45:12	1.1
+++ dumplog.c	2001/06/16 00:06:17	1.2
@@ -54,5 +54,7 @@
 	int i, lps, client;
 	int f = 0;
+	char zero[4096];
 
+	memset(zero, 0, sizeof(zero));
 	printf("\n");
 	if (argc != 2) {
@@ -118,5 +120,5 @@
 		goto log_file_error;
 	}
-	if (pass == 2 && !memcmp(lfd, rph, lps)) {
+	if ((pass == 2) && !memcmp(lfd, rph, lps)) {
 		printf("2nd restart area fully matches the 1st one. Skipping "
 				"display.\n");
@@ -139,7 +141,7 @@
 				le16_to_cpu(rph->major_ver),
 				le16_to_cpu(rph->minor_ver));
-	printf("%s restart area:\n", pass == 1? "1st": "2nd");
+	printf("\n%s restart area:\n", pass == 1? "1st": "2nd");
 	printf("magic = RSTR\n");
-	printf("Lsn = 0x%Lx\n", sle64_to_cpu(rph->chkdsk_lsn));
+	printf("ChkDskLsn = 0x%Lx\n", sle64_to_cpu(rph->chkdsk_lsn));
 	printf("SystemPageSize = %u\n", le32_to_cpu(rph->system_page_size));
 	printf("LogPageSize = %u\n", le32_to_cpu(rph->log_page_size));
@@ -148,16 +150,15 @@
 	printf("CurrentLsn = %Lx\n", sle64_to_cpu(rr->current_lsn));
 	printf("LogClients = %u\n", le16_to_cpu(rr->log_clients));
-	printf("ClientFreeList = %u\n", le16_to_cpu(rr->client_free_list));
-	printf("ClientInUseList = %u\n", le16_to_cpu(rr->client_in_use_list));
+	printf("ClientFreeList = %i\n", sle16_to_cpu(rr->client_free_list));
+	printf("ClientInUseList = %i\n", sle16_to_cpu(rr->client_in_use_list));
 	printf("Flags = 0x%x\n", le16_to_cpu(rr->flags));
-	printf("SeqNumberBits = %u\n", le32_to_cpu(rr->seq_number_bits));
+	printf("SeqNumberBits = %u (0x%x)\n", le32_to_cpu(rr->seq_number_bits),
+			le32_to_cpu(rr->seq_number_bits));
 	printf("RestartAreaLength = 0x%x\n", 
 			le16_to_cpu(rr->restart_area_length));
 	printf("ClientArrayOffset = 0x%x\n",
 			le16_to_cpu(rr->client_array_offset));
-	printf("FileSize = %Lu\n", le64_to_cpu(rr->file_size));
-	if (le64_to_cpu(rr->file_size) != l)
-		puts("Logfile restart area indicates a log file size"
-				"different from the actual size!");
+	printf("FileSize = %Lu (0x%Lx)\n", le64_to_cpu(rr->file_size),
+			le64_to_cpu(rr->file_size));
 	printf("LastLsnDataLength = 0x%x\n",
 			le32_to_cpu(rr->last_lsn_data_length));
@@ -170,9 +171,9 @@
 		printf("ClientRestartLsn = 0x%Lx\n", 
 				sle64_to_cpu(cr->client_restart_lsn));
-		printf("PrevClient = 0x%x\n", le16_to_cpu(cr->prev_client));
-		printf("NextClient = 0x%x\n", le16_to_cpu(cr->next_client));
+		printf("PrevClient = %i\n", sle16_to_cpu(cr->prev_client));
+		printf("NextClient = %i\n", sle16_to_cpu(cr->next_client));
 		printf("SeqNumber = 0x%Lx\n", le64_to_cpu(cr->seq_number));
 		printf("ClientNameLength = 0x%x\n",
-				le32_to_cpu(cr->client_name_lengthi));
+				le32_to_cpu(cr->client_name_length));
 		if (le32_to_cpu(cr->client_name_length)) {
 			// convert to ascii and print out.
@@ -180,5 +181,5 @@
 		}
 		/* Size of a restart client record is fixed at 0xa0 bytes. */
-		cr = (char*)cr + 0xa0;
+		cr = (RESTART_CLIENT*)((char*)cr + 0xa0);
 	}
 skip_rstr_pass:
@@ -189,12 +190,12 @@
 	}
 	rcrd_ph = (RECORD_PAGE_HEADER*)rph;
-	/* Reuse pass for log record counter. */
+	/* Reuse pass for log record clienter. */
 	pass = 0;
 	printf("\nFinished with restart area. Beginning with log area.\n");
 rcrd_pass_loc:
-	printf("Log record page number %i", pass);
 	rcrd_ph = (RECORD_PAGE_HEADER*)((char*)rcrd_ph + lps);
-	if ((char*)rcrd_ph + lps > lfd + l)
+	if ((char*)rcrd_ph + lps > (char*)lfd + l)
 		goto end_of_rcrd_passes;
+	printf("\nLog record page number %i", pass);
 	if (!is_rcrd_recordp(rcrd_ph)) {
 		for (i = 0; i < lps; i++)
@@ -207,7 +208,76 @@
 		pass++;
 		goto rcrd_pass_loc;
-	}
+	} else
+		printf(":");
 	/* Dump log record page */
-	// ...
+	printf("\nmagic = RCRD\n");
+	printf("copy.last_lsn/file_offset = 0x%Lx\n",
+			le64_to_cpu(rcrd_ph->copy.last_lsn));
+	printf("flags = 0x%x\n", le32_to_cpu(rcrd_ph->flags));
+	printf("page count = %i\n", le16_to_cpu(rcrd_ph->page_count));
+	printf("page position = %i\n", le16_to_cpu(rcrd_ph->page_position));
+	printf("header.next_record_offset = 0x%Lx\n",
+			le64_to_cpu(rcrd_ph->header.packed.next_record_offset));
+	printf("header.last_end_lsn = 0x%Lx\n",
+			le64_to_cpu(rcrd_ph->header.packed.last_end_lsn));
+	/*
+	 * Where does the 0x40 come from? Is it just usa_offset +
+	 * usa_client * 2 + 7 & ~7 or is it derived from somewhere?
+	 */
+	lr = (LOG_RECORD*)((char*)rcrd_ph + 0x40);
+	client = 0;
+log_record_pass:
+	printf("\nLog record %i:\n", client);
+	printf("this lsn = 0x%Lx\n", le64_to_cpu(lr->this_lsn));
+	printf("client previous lsn = 0x%Lx\n",
+			le64_to_cpu(lr->client_previous_lsn));
+	printf("client undo next lsn = 0x%Lx\n",
+			le64_to_cpu(lr->client_undo_next_lsn));
+	printf("client data length = 0x%x\n",
+			le32_to_cpu(lr->client_data_length));
+	printf("client_id.seq_number = 0x%x\n",
+			le16_to_cpu(lr->client_id.seq_number));
+	printf("client_id.client_index = 0x%x\n",
+			le16_to_cpu(lr->client_id.client_index));
+	printf("record type = 0x%x\n", le32_to_cpu(lr->record_type));
+	printf("transaction_id = 0x%x\n", le32_to_cpu(lr->transaction_id));
+	printf("flags = 0x%x:", lr->flags);
+	if (!lr->flags)
+		printf(" NONE\n");
+	else {
+		int _b = 0;
+
+		if (lr->flags & LOG_RECORD_MULTI_PAGE) {
+			printf(" LOG_RECORD_MULTI_PAGE");
+			_b = 1;
+		}
+		if (lr->flags & ~LOG_RECORD_MULTI_PAGE) {
+			if (_b)
+				printf(" |");
+			printf(" Unknown flags");
+		}
+		printf("\n");
+	}
+	printf("redo_operation = 0x%x\n", le16_to_cpu(lr->redo_operation));
+	printf("undo_operation = 0x%x\n", le16_to_cpu(lr->undo_operation));
+	printf("redo_offset = 0x%x\n", le16_to_cpu(lr->redo_offset));
+	printf("redo_length = 0x%x\n", le16_to_cpu(lr->redo_length));
+	printf("undo_offset = 0x%x\n", le16_to_cpu(lr->undo_offset));
+	printf("undo_length = 0x%x\n", le16_to_cpu(lr->undo_length));
+	printf("target_attribute = 0x%x\n", le16_to_cpu(lr->target_attribute));
+	printf("lcns_to_follow = 0x%x\n", le16_to_cpu(lr->lcns_to_follow));
+	printf("record_offset = 0x%x\n", le16_to_cpu(lr->record_offset));
+	printf("attribute_offset = 0x%x\n", le16_to_cpu(lr->attribute_offset));
+	printf("target_vcn = 0x%Lx\n", sle64_to_cpu(lr->target_vcn));
+	if (le16_to_cpu(lr->lcns_to_follow) > 0)
+		printf("Array of lcns:\n");
+	for (i = 0; i < le16_to_cpu(lr->lcns_to_follow); i++)
+		printf("lcn_list[%i].lcn = 0x%Lx\n",
+				sle64_to_cpu(lr->lcn_list[i].lcn));
+	client++;
+	lr = (LOG_RECORD*)((char*)lr + 0x70);
+	if (((char*)lr + 0x70 <= (char*)rcrd_ph +
+			le64_to_cpu(rcrd_ph->header.packed.next_record_offset)))
+		goto log_record_pass;
 	pass++;
 	goto rcrd_pass_loc;
Index: logfile.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/logfile.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -U2 -r1.1 -r1.2
--- logfile.c	2001/06/15 16:45:12	1.1
+++ logfile.c	2001/06/16 00:06:17	1.2
@@ -20,111 +20,4 @@
 void init_logfile(char *log_buf, __u32 log_buf_size)
 {
-	__s64 l;
-	unsigned char *lfd = NULL;
-	RESTART_PAGE_HEADER *rph;
-	RESTART_AREA *rr;
-	RESTART_CLIENT *cr;
-	int pass = 1;
-	int i, lps;
-	int f = 0;
-
-	/* Check restart area. */
-	if (!is_rstr_recordp(lfd)) {
-		__s64 _l;
-		
-		for (_l = 0LL; _l < l; _l++)
-			if (lfd[_l] != (unsigned char)-1)
-				break;
-		if (_l < l)
-			puts("$LogFile contents are corrupt (magic RSTR "
-					"missing)!");
-		else
-			puts("$LogFile is empty.");
-		goto log_file_error;
-	}
-	/* Do the interpretation and display now. */
-	rph = (RESTART_PAGE_HEADER*)lfd;
-	lps = le32_to_cpu(rph->log_page_size);
-pass_loc:
-	if (!post_read_mst_fixup((NTFS_RECORD*)rph, lps) ||
-	    is_baad_recordp(rph)) {
-		puts("$LogFile incomplete multi sector transfer detected! "
-		     "Cannot handle this yet!");
-		goto log_file_error;
-	}
-	if (le16_to_cpu(rph->major_ver != 1) || 
-	    le16_to_cpu(rph->minor_ver != 1)) {
-		fprintf(stderr, "$LogFile version %i.%i! Error: Unknown "
-				"$LogFile version!\n",
-					le16_to_cpu(rph->major_ver),
-					le16_to_cpu(rph->minor_ver));
-		goto log_file_error;
-	}
-	rr = (RESTART_AREA*)((char*)rph + le16_to_cpu(rph->restart_offset));
-	cr = (RESTART_CLIENT*)((char*)rr + sizeof(RESTART_AREA));
-	/* Dump of the interpreted $LogFile restart area. */
-	if (pass == 1)
-		printf("\n$LogFile version %i.%i.\n",
-					le16_to_cpu(rph->major_ver),
-					le16_to_cpu(rph->minor_ver));
-	printf("%s restart area:\n", pass == 1? "1st": "2nd");
-	printf("magic = RSTR\n");
-	printf("Lsn = 0x%Lx\n", sle64_to_cpu(rph->chkdsk_lsn));
-	printf("SystempageSize = %u\n", le32_to_cpu(rph->system_page_size));
-	printf("LogPageSize = %u\n", le32_to_cpu(rph->log_page_size));
-	printf("RestartOffset = 0x%x\n", le16_to_cpu(rph->restart_offset));
-	printf("\n(1st) restart record:\n");
-	printf("CurrentLsn = %Lx\n", sle64_to_cpu(rr->current_lsn));
-	printf("LogClients = %u\n", le16_to_cpu(rr->log_clients));
-	printf("ClientFreeList = %u\n", le16_to_cpu(rr->client_free_list));
-	printf("ClientInUseList = %u\n", le16_to_cpu(rr->client_in_use_list));
-	printf("Flags = 0x%x\n", le16_to_cpu(rr->flags));
-	printf("SeqNumberBits = %u\n", le32_to_cpu(rr->seq_number_bits));
-	printf("RestartAreaLength = 0x%x\n", 
-					le16_to_cpu(rr->restart_area_length));
-	printf("ClientArrayOffset = 0x%x\n",
-					le16_to_cpu(rr->client_array_offset));
-	printf("FileSize = %Lu\n", le64_to_cpu(rr->file_size));
-	if (le64_to_cpu(rr->file_size) != l)
-		puts("$LogFile restart area indicates a log file size"
-		     "different from the actual size!");
-	printf("LastLsnDataLength = 0x%x\n",
-					le32_to_cpu(rr->last_lsn_data_length));
-	printf("RecordLength = 0x%x\n", le16_to_cpu(rr->record_length));
-	printf("LogPageDataOffset = 0x%x\n", 
-					le16_to_cpu(rr->log_page_data_offset));
-	printf("\n1st Client record:\n");
-	printf("OldestLsn = 0x%Lx\n", sle64_to_cpu(cr->oldest_lsn));
-	printf("ClientRestartLsn = 0x%Lx\n", 
-					sle64_to_cpu(cr->client_restart_lsn));
-	printf("PrevClient = 0x%x\n", le16_to_cpu(cr->prev_client));
-	printf("NextClient = 0x%x\n", le16_to_cpu(cr->next_client));
-	printf("SeqNumber = 0x%x\n", le16_to_cpu(cr->seq_number));
-	printf("ClientName = %u\n", le16_to_cpu(cr->client_name));
-	printf("\nTerminator = 0x%x\n", *(__u32*)((char*)cr + 
-						sizeof(RESTART_CLIENT)));
-	if (*(__u32*)((char*)cr + sizeof(RESTART_CLIENT)) != 0xffffffff)
-		puts("$LogFile restart area is not terminated!");
-	printf("Unicode string \"NTFS\"%spresent\n", *(__u64*)((char*)cr + 
-				sizeof(RESTART_CLIENT) + 0x10) == 
-				cpu_to_le64(0x005300460054004e) ? " ": " not ");
-	rph = (RESTART_PAGE_HEADER*)((char*)rph + lps);
-	if (pass == 1) {
-		++pass;
-		goto pass_loc;
-	}
-	if (!is_rcrd_recordp(rph))
-		puts("$LogFile's first record area magic RCRD is missing!");
-	puts("That's all for now. Dumping of the actual log contents is not "
-	     "implemented yet.");
-log_file_error:
-	printf("\n");
-	/* Set return code to 0. */
-	i = 0;
-final_exit:
-	return i;
-error_exit:
-	i = 1;
-	goto final_exit;
 }
 
Index: ntfsdump_logfile.c
===================================================================
RCS file: /cvsroot/linux-ntfs/linux-ntfs/ntfstools/ntfsdump_logfile.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -U2 -r1.9 -r1.10
--- ntfsdump_logfile.c	2001/06/10 18:30:17	1.9
+++ ntfsdump_logfile.c	2001/06/16 00:06:17	1.10
@@ -227,5 +227,5 @@
 	printf("NextClient = 0x%x\n", le16_to_cpu(cr->next_client));
 	printf("SeqNumber = 0x%x\n", le16_to_cpu(cr->seq_number));
-	printf("ClientName = %u\n", le16_to_cpu(cr->client_name));
+	//printf("ClientName = %u\n", le16_to_cpu(cr->client_name));
 	printf("\nTerminator = 0x%x\n", *(__u32*)((char*)cr + 
 						sizeof(RESTART_CLIENT)));
 |