1/**
2 * bootsect.c - Boot sector handling code. Originated from the Linux-NTFS project.
3 *
4 * Copyright (c) 2000-2006 Anton Altaparmakov
5 * Copyright (c) 2003-2008 Szabolcs Szakacsits
6 * Copyright (c)      2005 Yura Pakhuchiy
7 *
8 * This program/include file is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as published
10 * by the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program/include file is distributed in the hope that it will be
14 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program (in the main directory of the NTFS-3G
20 * distribution in the file COPYING); if not, write to the Free Software
21 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#ifdef HAVE_STDIO_H
29#include <stdio.h>
30#endif
31#ifdef HAVE_STDLIB_H
32#include <stdlib.h>
33#endif
34#ifdef HAVE_STRING_H
35#include <string.h>
36#endif
37#ifdef HAVE_ERRNO_H
38#include <errno.h>
39#endif
40
41#include "compat.h"
42#include "bootsect.h"
43#include "debug.h"
44#include "logging.h"
45
46/**
47 * ntfs_boot_sector_is_ntfs - check if buffer contains a valid ntfs boot sector
48 * @b:		buffer containing putative boot sector to analyze
49 * @silent:	if zero, output progress messages to stderr
50 *
51 * Check if the buffer @b contains a valid ntfs boot sector. The buffer @b
52 * must be at least 512 bytes in size.
53 *
54 * If @silent is zero, output progress messages to stderr. Otherwise, do not
55 * output any messages (except when configured with --enable-debug in which
56 * case warning/debug messages may be displayed).
57 *
58 * Return TRUE if @b contains a valid ntfs boot sector and FALSE if not.
59 */
60BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
61{
62	u32 i;
63	BOOL ret = FALSE;
64
65	ntfs_log_debug("Beginning bootsector check.\n");
66
67	ntfs_log_debug("Checking OEMid, NTFS signature.\n");
68	if (b->oem_id != cpu_to_le64(0x202020205346544eULL)) { /* "NTFS    " */
69		ntfs_log_error("NTFS signature is missing.\n");
70		goto not_ntfs;
71	}
72
73	ntfs_log_debug("Checking bytes per sector.\n");
74	if (le16_to_cpu(b->bpb.bytes_per_sector) <  256 ||
75	    le16_to_cpu(b->bpb.bytes_per_sector) > 4096) {
76		ntfs_log_error("Unexpected bytes per sector value (%d).\n",
77			       le16_to_cpu(b->bpb.bytes_per_sector));
78		goto not_ntfs;
79	}
80
81	ntfs_log_debug("Checking sectors per cluster.\n");
82	switch (b->bpb.sectors_per_cluster) {
83	case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
84		break;
85	default:
86		ntfs_log_error("Unexpected sectors per cluster value (%d).\n",
87			       b->bpb.sectors_per_cluster);
88		goto not_ntfs;
89	}
90
91	ntfs_log_debug("Checking cluster size.\n");
92	i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) *
93		b->bpb.sectors_per_cluster;
94	if (i > 65536) {
95		ntfs_log_error("Unexpected cluster size (%d).\n", i);
96		goto not_ntfs;
97	}
98
99	ntfs_log_debug("Checking reserved fields are zero.\n");
100	if (le16_to_cpu(b->bpb.reserved_sectors) ||
101	    le16_to_cpu(b->bpb.root_entries) ||
102	    le16_to_cpu(b->bpb.sectors) ||
103	    le16_to_cpu(b->bpb.sectors_per_fat) ||
104	    le32_to_cpu(b->bpb.large_sectors) ||
105	    b->bpb.fats) {
106		ntfs_log_error("Reserved fields aren't zero "
107			       "(%d, %d, %d, %d, %d, %d).\n",
108			       le16_to_cpu(b->bpb.reserved_sectors),
109			       le16_to_cpu(b->bpb.root_entries),
110			       le16_to_cpu(b->bpb.sectors),
111			       le16_to_cpu(b->bpb.sectors_per_fat),
112			       le32_to_cpu(b->bpb.large_sectors),
113			       b->bpb.fats);
114		goto not_ntfs;
115	}
116
117	ntfs_log_debug("Checking clusters per mft record.\n");
118	if ((u8)b->clusters_per_mft_record < 0xe1 ||
119	    (u8)b->clusters_per_mft_record > 0xf7) {
120		switch (b->clusters_per_mft_record) {
121		case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
122			break;
123		default:
124			ntfs_log_error("Unexpected clusters per mft record "
125				       "(%d).\n", b->clusters_per_mft_record);
126			goto not_ntfs;
127		}
128	}
129
130	ntfs_log_debug("Checking clusters per index block.\n");
131	if ((u8)b->clusters_per_index_record < 0xe1 ||
132	    (u8)b->clusters_per_index_record > 0xf7) {
133		switch (b->clusters_per_index_record) {
134		case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
135			break;
136		default:
137			ntfs_log_error("Unexpected clusters per index record "
138				       "(%d).\n", b->clusters_per_index_record);
139			goto not_ntfs;
140		}
141	}
142
143	if (b->end_of_sector_marker != cpu_to_le16(0xaa55))
144		ntfs_log_debug("Warning: Bootsector has invalid end of sector "
145			       "marker.\n");
146
147	ntfs_log_debug("Bootsector check completed successfully.\n");
148
149	ret = TRUE;
150not_ntfs:
151	return ret;
152}
153
154static const char *last_sector_error =
155"HINTS: Either the volume is a RAID/LDM but it wasn't setup yet,\n"
156"   or it was not setup correctly (e.g. by not using mdadm --build ...),\n"
157"   or a wrong device is tried to be mounted,\n"
158"   or the partition table is corrupt (partition is smaller than NTFS),\n"
159"   or the NTFS boot sector is corrupt (NTFS size is not valid).\n";
160
161/**
162 * ntfs_boot_sector_parse - setup an ntfs volume from an ntfs boot sector
163 * @vol:	ntfs_volume to setup
164 * @bs:		buffer containing ntfs boot sector to parse
165 *
166 * Parse the ntfs bootsector @bs and setup the ntfs volume @vol with the
167 * obtained values.
168 *
169 * Return 0 on success or -1 on error with errno set to the error code EINVAL.
170 */
171int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
172{
173	s64 sectors;
174	u8  sectors_per_cluster;
175	s8  c;
176
177	/* We return -1 with errno = EINVAL on error. */
178	errno = EINVAL;
179
180	vol->sector_size = le16_to_cpu(bs->bpb.bytes_per_sector);
181	vol->sector_size_bits = ffs(vol->sector_size) - 1;
182	ntfs_log_debug("SectorSize = 0x%x\n", vol->sector_size);
183	ntfs_log_debug("SectorSizeBits = %u\n", vol->sector_size_bits);
184	/*
185	 * The bounds checks on mft_lcn and mft_mirr_lcn (i.e. them being
186	 * below or equal the number_of_clusters) really belong in the
187	 * ntfs_boot_sector_is_ntfs but in this way we can just do this once.
188	 */
189	sectors_per_cluster = bs->bpb.sectors_per_cluster;
190	ntfs_log_debug("SectorsPerCluster = 0x%x\n", sectors_per_cluster);
191	if (sectors_per_cluster & (sectors_per_cluster - 1)) {
192		ntfs_log_error("sectors_per_cluster (%d) is not a power of 2."
193			       "\n", sectors_per_cluster);
194		return -1;
195	}
196
197	sectors = sle64_to_cpu(bs->number_of_sectors);
198	ntfs_log_debug("NumberOfSectors = %lld\n", (long long)sectors);
199	if (!sectors) {
200		ntfs_log_error("Volume size is set to zero.\n");
201		return -1;
202	}
203	if (vol->dev->d_ops->seek(vol->dev,
204				  (sectors - 1) << vol->sector_size_bits,
205				  SEEK_SET) == -1) {
206		ntfs_log_perror("Failed to read last sector (%lld)",
207			       	(long long)sectors);
208		ntfs_log_error("%s", last_sector_error);
209		return -1;
210	}
211
212	vol->nr_clusters =  sectors >> (ffs(sectors_per_cluster) - 1);
213
214	vol->mft_lcn = sle64_to_cpu(bs->mft_lcn);
215	vol->mftmirr_lcn = sle64_to_cpu(bs->mftmirr_lcn);
216	ntfs_log_debug("MFT LCN = %lld\n", (long long)vol->mft_lcn);
217	ntfs_log_debug("MFTMirr LCN = %lld\n", (long long)vol->mftmirr_lcn);
218	if (vol->mft_lcn     > vol->nr_clusters ||
219	    vol->mftmirr_lcn > vol->nr_clusters) {
220		ntfs_log_error("$MFT LCN (%lld) or $MFTMirr LCN (%lld) is "
221			      "greater than the number of clusters (%lld).\n",
222			      (long long)vol->mft_lcn, (long long)vol->mftmirr_lcn,
223			      (long long)vol->nr_clusters);
224		return -1;
225	}
226
227	vol->cluster_size = sectors_per_cluster * vol->sector_size;
228	if (vol->cluster_size & (vol->cluster_size - 1)) {
229		ntfs_log_error("cluster_size (%d) is not a power of 2.\n",
230			       vol->cluster_size);
231		return -1;
232	}
233	vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
234	/*
235	 * Need to get the clusters per mft record and handle it if it is
236	 * negative. Then calculate the mft_record_size. A value of 0x80 is
237	 * illegal, thus signed char is actually ok!
238	 */
239	c = bs->clusters_per_mft_record;
240	ntfs_log_debug("ClusterSize = 0x%x\n", (unsigned)vol->cluster_size);
241	ntfs_log_debug("ClusterSizeBits = %u\n", vol->cluster_size_bits);
242	ntfs_log_debug("ClustersPerMftRecord = 0x%x\n", c);
243	/*
244	 * When clusters_per_mft_record is negative, it means that it is to
245	 * be taken to be the negative base 2 logarithm of the mft_record_size
246	 * min bytes. Then:
247	 *	 mft_record_size = 2^(-clusters_per_mft_record) bytes.
248	 */
249	if (c < 0)
250		vol->mft_record_size = 1 << -c;
251	else
252		vol->mft_record_size = c << vol->cluster_size_bits;
253	if (vol->mft_record_size & (vol->mft_record_size - 1)) {
254		ntfs_log_error("mft_record_size (%d) is not a power of 2.\n",
255			       vol->mft_record_size);
256		return -1;
257	}
258	vol->mft_record_size_bits = ffs(vol->mft_record_size) - 1;
259	ntfs_log_debug("MftRecordSize = 0x%x\n", (unsigned)vol->mft_record_size);
260	ntfs_log_debug("MftRecordSizeBits = %u\n", vol->mft_record_size_bits);
261	/* Same as above for INDX record. */
262	c = bs->clusters_per_index_record;
263	ntfs_log_debug("ClustersPerINDXRecord = 0x%x\n", c);
264	if (c < 0)
265		vol->indx_record_size = 1 << -c;
266	else
267		vol->indx_record_size = c << vol->cluster_size_bits;
268	vol->indx_record_size_bits = ffs(vol->indx_record_size) - 1;
269	ntfs_log_debug("INDXRecordSize = 0x%x\n", (unsigned)vol->indx_record_size);
270	ntfs_log_debug("INDXRecordSizeBits = %u\n", vol->indx_record_size_bits);
271	/*
272	 * Work out the size of the MFT mirror in number of mft records. If the
273	 * cluster size is less than or equal to the size taken by four mft
274	 * records, the mft mirror stores the first four mft records. If the
275	 * cluster size is bigger than the size taken by four mft records, the
276	 * mft mirror contains as many mft records as will fit into one
277	 * cluster.
278	 */
279	if (vol->cluster_size <= 4 * vol->mft_record_size)
280		vol->mftmirr_size = 4;
281	else
282		vol->mftmirr_size = vol->cluster_size / vol->mft_record_size;
283	return 0;
284}
285
286