summaryrefslogtreecommitdiff
blob: 1cb8bb6c46c0fc7ee0dabb085a8c5c449974389e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
--- a/libntfs-3g/bootsect.c.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/libntfs-3g/bootsect.c	2018-05-07 09:11:13.004710800 +0200
@@ -38,6 +38,7 @@ 
 #include <errno.h>
 #endif
 
+#include "param.h"
 #include "compat.h"
 #include "bootsect.h"
 #include "debug.h"
@@ -61,6 +62,7 @@ 
 {
 	u32 i;
 	BOOL ret = FALSE;
+	u16 sectors_per_cluster;
 
 	ntfs_log_debug("Beginning bootsector check.\n");
 
@@ -83,15 +85,27 @@ 
 	case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
 		break;
 	default:
-		ntfs_log_error("Unexpected sectors per cluster value (%d).\n",
-			       b->bpb.sectors_per_cluster);
-		goto not_ntfs;
+		if ((b->bpb.sectors_per_cluster < 240)
+		    || (b->bpb.sectors_per_cluster > 249)) {
+			if (b->bpb.sectors_per_cluster > 128)
+				ntfs_log_error("Unexpected sectors"
+					" per cluster value (code 0x%x)\n",
+					b->bpb.sectors_per_cluster);
+			else
+				ntfs_log_error("Unexpected sectors"
+					" per cluster value (%d).\n",
+					b->bpb.sectors_per_cluster);
+			goto not_ntfs;
+		}
 	}
 
 	ntfs_log_debug("Checking cluster size.\n");
-	i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) * 
-		b->bpb.sectors_per_cluster;
-	if (i > 65536) {
+	if (b->bpb.sectors_per_cluster > 128)
+		sectors_per_cluster = 1 << (256 - b->bpb.sectors_per_cluster);
+	else
+		sectors_per_cluster = b->bpb.sectors_per_cluster;
+	i = (u32)le16_to_cpu(b->bpb.bytes_per_sector) * sectors_per_cluster;
+	if (i > NTFS_MAX_CLUSTER_SIZE) {
 		ntfs_log_error("Unexpected cluster size (%d).\n", i);
 		goto not_ntfs;
 	}
@@ -171,7 +185,7 @@ 
 int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
 {
 	s64 sectors;
-	u8  sectors_per_cluster;
+	u16  sectors_per_cluster;
 	s8  c;
 
 	/* We return -1 with errno = EINVAL on error. */
@@ -186,7 +200,10 @@ 
 	 * below or equal the number_of_clusters) really belong in the
 	 * ntfs_boot_sector_is_ntfs but in this way we can just do this once.
 	 */
-	sectors_per_cluster = bs->bpb.sectors_per_cluster;
+	if (bs->bpb.sectors_per_cluster > 128)
+		sectors_per_cluster = 1 << (256 - bs->bpb.sectors_per_cluster);
+	else
+		sectors_per_cluster = bs->bpb.sectors_per_cluster;
 	ntfs_log_debug("SectorsPerCluster = 0x%x\n", sectors_per_cluster);
 	if (sectors_per_cluster & (sectors_per_cluster - 1)) {
 		ntfs_log_error("sectors_per_cluster (%d) is not a power of 2."
--- a/ntfsprogs/mkntfs.8.in.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/ntfsprogs/mkntfs.8.in	2018-05-07 09:11:13.014132400 +0200
@@ -132,7 +132,7 @@ 
 .TP
 \fB\-c\fR, \fB\-\-cluster\-size\fR BYTES
 Specify the size of clusters in bytes. Valid cluster size values are powers of
-two, with at least 256, and at most 65536 bytes per cluster. If omitted,
+two, with at least 256, and at most 2097152 bytes (2MB) per cluster. If omitted,
 .B mkntfs
 uses 4096 bytes as the default cluster size.
 .sp
--- a/ntfsprogs/mkntfs.c.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/ntfsprogs/mkntfs.c	2018-05-07 09:11:13.035522300 +0200
@@ -6,7 +6,7 @@ 
  * Copyright (c) 2002-2006 Szabolcs Szakacsits
  * Copyright (c) 2005      Erik Sornes
  * Copyright (c) 2007      Yura Pakhuchiy
- * Copyright (c) 2010-2014 Jean-Pierre Andre
+ * Copyright (c) 2010-2018 Jean-Pierre Andre
  *
  * This utility will create an NTFS 1.2 or 3.1 volume on a user
  * specified (block) device.
@@ -119,6 +119,7 @@ 
 #	endif
 #endif
 
+#include "param.h"
 #include "security.h"
 #include "types.h"
 #include "attrib.h"
@@ -287,7 +288,7 @@ 
 	ntfs_log_info("Copyright (c) 2002-2006 Szabolcs Szakacsits\n");
 	ntfs_log_info("Copyright (c) 2005      Erik Sornes\n");
 	ntfs_log_info("Copyright (c) 2007      Yura Pakhuchiy\n");
-	ntfs_log_info("Copyright (c) 2010-2014 Jean-Pierre Andre\n");
+	ntfs_log_info("Copyright (c) 2010-2018 Jean-Pierre Andre\n");
 	ntfs_log_info("\n%s\n%s%s\n", ntfs_gpl, ntfs_bugs, ntfs_home);
 }
 
@@ -3719,11 +3720,11 @@ 
 		/*
 		 * For huge volumes, grow the cluster size until the number of
 		 * clusters fits into 32 bits or the cluster size exceeds the
-		 * maximum limit of 64kiB.
+		 * maximum limit of NTFS_MAX_CLUSTER_SIZE.
 		 */
 		while (volume_size >> (ffs(vol->cluster_size) - 1 + 32)) {
 			vol->cluster_size <<= 1;
-			if (vol->cluster_size > 65535) {
+			if (vol->cluster_size >= NTFS_MAX_CLUSTER_SIZE) {
 				ntfs_log_error("Device is too large to hold an "
 						"NTFS volume (maximum size is "
 						"256TiB).\n");
@@ -3744,15 +3745,18 @@ 
 				"to, or larger than, the sector size.\n");
 		return FALSE;
 	}
-	if (vol->cluster_size > 128 * (u32)opts.sector_size) {
+		/* Before Windows 10 Creators, the limit was 128 */
+	if (vol->cluster_size > 4096 * (u32)opts.sector_size) {
 		ntfs_log_error("The cluster size is invalid.  It cannot be "
-				"more that 128 times the size of the sector "
+				"more that 4096 times the size of the sector "
 				"size.\n");
 		return FALSE;
 	}
-	if (vol->cluster_size > 65536) {
+	if (vol->cluster_size > NTFS_MAX_CLUSTER_SIZE) {
 		ntfs_log_error("The cluster size is invalid.  The maximum "
-			"cluster size is 65536 bytes (64kiB).\n");
+			"cluster size is %lu bytes (%lukiB).\n",
+			(unsigned long)NTFS_MAX_CLUSTER_SIZE,
+			(unsigned long)(NTFS_MAX_CLUSTER_SIZE >> 10));
 		return FALSE;
 	}
 	vol->cluster_size_bits = ffs(vol->cluster_size) - 1;
@@ -4387,6 +4391,7 @@ 
 	u8 *sd;
 	FILE_ATTR_FLAGS extend_flags;
 	VOLUME_FLAGS volume_flags = const_cpu_to_le16(0);
+	int sectors_per_cluster;
 	int nr_sysfiles;
 	int buf_sds_first_size;
 	char *buf_sds;
@@ -4639,8 +4644,11 @@ 
 	 * already inserted, so no need to worry about these things.
 	 */
 	bs->bpb.bytes_per_sector = cpu_to_le16(opts.sector_size);
-	bs->bpb.sectors_per_cluster = (u8)(g_vol->cluster_size /
-			opts.sector_size);
+	sectors_per_cluster = g_vol->cluster_size / opts.sector_size;
+	if (sectors_per_cluster > 128)
+		bs->bpb.sectors_per_cluster = 257 - ffs(sectors_per_cluster);
+	else
+		bs->bpb.sectors_per_cluster = sectors_per_cluster;
 	bs->bpb.media_type = 0xf8; /* hard disk */
 	bs->bpb.sectors_per_track = cpu_to_le16(opts.sectors_per_track);
 	ntfs_log_debug("sectors per track = %ld (0x%lx)\n",
--- a/ntfsprogs/ntfsclone.c.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/ntfsprogs/ntfsclone.c	2018-05-07 09:11:38.245007100 +0200
@@ -3,7 +3,7 @@ 
  *
  * Copyright (c) 2003-2006 Szabolcs Szakacsits
  * Copyright (c) 2004-2006 Anton Altaparmakov
- * Copyright (c) 2010-2016 Jean-Pierre Andre
+ * Copyright (c) 2010-2018 Jean-Pierre Andre
  * Special image format support copyright (c) 2004 Per Olofsson
  *
  * Clone NTFS data and/or metadata to a sparse file, image, device or stdout.
@@ -71,6 +71,7 @@ 
  */
 #define NTFS_DO_NOT_CHECK_ENDIANS
 
+#include "param.h"
 #include "debug.h"
 #include "types.h"
 #include "support.h"
@@ -270,7 +271,6 @@ 
 
 #define LAST_METADATA_INODE	11
 
-#define NTFS_MAX_CLUSTER_SIZE	65536
 #define NTFS_SECTOR_SIZE	  512
 
 #define rounded_up_division(a, b) (((a) + (b - 1)) / (b))
@@ -393,7 +393,7 @@ 
 		   "Efficiently clone, image, restore or rescue an NTFS Volume.\n\n"
 		   "Copyright (c) 2003-2006 Szabolcs Szakacsits\n"
 		   "Copyright (c) 2004-2006 Anton Altaparmakov\n"
-		   "Copyright (c) 2010-2016 Jean-Pierre Andre\n\n");
+		   "Copyright (c) 2010-2018 Jean-Pierre Andre\n\n");
 	fprintf(stderr, "%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home);
 	exit(0);
 }
@@ -756,7 +756,7 @@ 
 
 static void copy_cluster(int rescue, u64 rescue_lcn, u64 lcn)
 {
-	char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
+	char *buff;
 	/* vol is NULL if opt.restore_image is set */
 	s32 csize = le32_to_cpu(image_hdr.cluster_size);
 	BOOL backup_bootsector;
@@ -783,6 +783,10 @@ 
 		}
 	}
 
+	buff = (char*)ntfs_malloc(csize);
+	if (!buff)
+		err_exit("Not enough memory");
+
 // need reading when not about to write ?
 	if (read_all(fd, buff, csize) == -1) {
 
@@ -858,6 +862,7 @@ 
 		perr_printf("Write failed");
 #endif
 	}
+	free(buff);
 }
 
 static s64 lseek_out(int fd, s64 pos, int mode)
@@ -995,7 +1000,11 @@ 
 				 struct progress_bar *progress, u64 *p_counter)
 {
 	s64 i;
-	char buff[NTFS_MAX_CLUSTER_SIZE];
+	char *buff;
+
+	buff = (char*)ntfs_malloc(csize);
+	if (!buff)
+		err_exit("Not enough memory");
 
 	memset(buff, 0, csize);
 
@@ -1004,6 +1013,7 @@ 
 			perr_exit("write_all");
 		progress_update(progress, ++(*p_counter));
 	}
+	free(buff);
 }
 
 static void restore_image(void)
@@ -1492,7 +1502,7 @@ 
 
 static void copy_wipe_mft(ntfs_walk_clusters_ctx *image, runlist *rl)
 {
-	char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
+	char *buff;
 	void *fd;
 	s64 mft_no;
 	u32 mft_record_size;
@@ -1522,6 +1532,10 @@ 
 		clusters_per_set = mft_record_size/csize;
 		records_per_set = 1;
 	}
+	buff = (char*)ntfs_malloc(mft_record_size);
+	if (!buff)
+		err_exit("Not enough memory");
+
 	mft_no = 0;
 	ri = rj = 0;
 	wi = wj = 0;
@@ -1554,6 +1568,7 @@ 
 		}
 	}
 	image->current_lcn = current_lcn;
+	free(buff);
 }
 
 /*
@@ -1566,7 +1581,7 @@ 
 
 static void copy_wipe_i30(ntfs_walk_clusters_ctx *image, runlist *rl)
 {
-	char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
+	char *buff;
 	void *fd;
 	u32 indx_record_size;
 	u32 csize;
@@ -1595,6 +1610,10 @@ 
 		clusters_per_set = indx_record_size/csize;
 		records_per_set = 1;
 	}
+	buff = (char*)ntfs_malloc(indx_record_size);
+	if (!buff)
+		err_exit("Not enough memory");
+
 	ri = rj = 0;
 	wi = wj = 0;
 	if (rl[ri].length)
@@ -1627,6 +1646,7 @@ 
 		}
 	}
 	image->current_lcn = current_lcn;
+	free(buff);
 }
 
 static void dump_clusters(ntfs_walk_clusters_ctx *image, runlist *rl)
--- a/ntfsprogs/ntfsresize.c.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/ntfsprogs/ntfsresize.c	2018-05-07 09:11:13.076883400 +0200
@@ -59,6 +59,7 @@ 
 #include <fcntl.h>
 #endif
 
+#include "param.h"
 #include "debug.h"
 #include "types.h"
 #include "support.h"
@@ -243,8 +244,6 @@ 
 #define DIRTY_INODE		(1)
 #define DIRTY_ATTRIB		(2)
 
-#define NTFS_MAX_CLUSTER_SIZE	(65536)
-
 static s64 rounded_up_division(s64 numer, s64 denom)
 {
 	return (numer + (denom - 1)) / denom;
@@ -404,7 +403,7 @@ 
 	printf("Copyright (c) 2002-2005  Anton Altaparmakov\n");
 	printf("Copyright (c) 2002-2003  Richard Russon\n");
 	printf("Copyright (c) 2007       Yura Pakhuchiy\n");
-	printf("Copyright (c) 2011-2016  Jean-Pierre Andre\n");
+	printf("Copyright (c) 2011-2018  Jean-Pierre Andre\n");
 	printf("\n%s\n%s%s", ntfs_gpl, ntfs_bugs, ntfs_home);
 }
 
@@ -1849,9 +1848,13 @@ 
 static void copy_clusters(ntfs_resize_t *resize, s64 dest, s64 src, s64 len)
 {
 	s64 i;
-	char buff[NTFS_MAX_CLUSTER_SIZE]; /* overflow checked at mount time */
+	char *buff;
 	ntfs_volume *vol = resize->vol;
 
+	buff = (char*)ntfs_malloc(vol->cluster_size);
+	if (!buff)
+		perr_exit("ntfs_malloc");
+
 	for (i = 0; i < len; i++) {
 
 		lseek_to_cluster(vol, src + i);
@@ -1875,6 +1878,7 @@ 
 		resize->relocations++;
 		progress_update(&resize->progress, resize->relocations);
 	}
+	free(buff);
 }
 
 static void relocate_clusters(ntfs_resize_t *r, runlist *dest_rl, s64 src_lcn)
--- a/include/ntfs-3g/param.h.ref	2017-03-23 10:42:44.000000000 +0100
+++ b/include/ntfs-3g/param.h	2018-05-07 09:11:13.088302600 +0200
@@ -40,6 +40,13 @@ 
 };
 
 /*
+ *		Parameters for formatting
+ */
+
+		/* Up to Windows 10, the cluster size was limited to 64K */
+#define NTFS_MAX_CLUSTER_SIZE 2097152 /* Windows 10 Creators allows 2MB */
+
+/*
  *		Parameters for compression
  */