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