Coverage Report

Created: 2025-07-01 06:58

/src/sleuthkit/tsk/vs/dos.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * The Sleuth Kit
3
 *
4
 * Brian Carrier [carrier <at> sleuthkit [dot] org]
5
 * Copyright (c) 2006-2011 Brian Carrier, Basis Technology.  All rights reserved
6
 * Copyright (c) 2003-2005 Brian Carrier.  All rights reserved
7
 *
8
 * This software is distributed under the Common Public License 1.0
9
 */
10
11
/** \file dos.c
12
 * Contains the internal functions to process DOS Partition tables
13
 */
14
15
#include "tsk_vs_i.h"
16
#include "tsk_dos.h"
17
18
19
/* Check the extended partition flags */
20
#define dos_is_ext(x) \
21
0
  ((((x) == 0x05) || ((x) == 0x0F) || ((x) == 0x85)) ? 1 : 0)
22
23
/*
24
 * dos_get_desc
25
 *
26
 * Return a buffer with a string description of the partition type
27
 *
28
 * From: http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
29
 */
30
static char *
31
dos_get_desc(uint8_t ptype)
32
0
{
33
0
#define DESC_LEN 64
34
0
    char *str = tsk_malloc(DESC_LEN);
35
0
    if (str == NULL)
36
0
        return "";
37
38
0
    switch (ptype) {
39
0
    case 0x00:
40
0
        snprintf(str, DESC_LEN, "Empty (0x00)");
41
0
        break;
42
0
    case 0x01:
43
0
        snprintf(str, DESC_LEN, "DOS FAT12 (0x01)");
44
0
        break;
45
0
    case 0x02:
46
0
        snprintf(str, DESC_LEN, "XENIX root (0x02)");
47
0
        break;
48
0
    case 0x03:
49
0
        snprintf(str, DESC_LEN, "XENIX /usr (0x03)");
50
0
        break;
51
0
    case 0x04:
52
0
    case 0x06:
53
0
        snprintf(str, DESC_LEN, "DOS FAT16 (0x%.2x)", ptype);
54
0
        break;
55
0
    case 0x05:
56
0
        snprintf(str, DESC_LEN, "DOS Extended (0x05)");
57
0
        break;
58
0
    case 0x07:
59
0
        snprintf(str, DESC_LEN, "NTFS / exFAT (0x07)");
60
0
        break;
61
0
    case 0x08:
62
0
        snprintf(str, DESC_LEN, "AIX Boot (0x08)");
63
0
        break;
64
0
    case 0x09:
65
0
        snprintf(str, DESC_LEN, "AIX Data (0x09)");
66
0
        break;
67
0
    case 0x0a:
68
0
        snprintf(str, DESC_LEN, "OS/2 Boot Manager (0x0a)");
69
0
        break;
70
        /*
71
           case 0x0a:
72
           snprintf(str, DESC_LEN, "Coherent swap (0x0a)");
73
           break;
74
           case 0x0a:
75
           snprintf(str, DESC_LEN, "OPUS (0x0a)");
76
           break;
77
         */
78
0
    case 0x0b:
79
0
    case 0x0c:
80
0
        snprintf(str, DESC_LEN, "Win95 FAT32 (0x%.2x)", ptype);
81
0
        break;
82
0
    case 0x0e:
83
0
        snprintf(str, DESC_LEN, "Win95 FAT16 (0x0e)");
84
0
        break;
85
0
    case 0x0f:
86
0
        snprintf(str, DESC_LEN, "Win95 Extended (0x0f)");
87
0
        break;
88
0
    case 0x10:
89
0
        snprintf(str, DESC_LEN, "OPUS (0x10)");
90
0
        break;
91
0
    case 0x11:
92
0
        snprintf(str, DESC_LEN, "DOS FAT12 Hidden (0x11)");
93
0
        break;
94
0
    case 0x12:
95
0
        snprintf(str, DESC_LEN, "Hibernation (0x12)");
96
0
        break;
97
0
    case 0x14:
98
0
    case 0x16:
99
0
        snprintf(str, DESC_LEN, "DOS FAT16 Hidden (0x%.2x)", ptype);
100
0
        break;
101
0
    case 0x17:
102
0
        snprintf(str, DESC_LEN, "Hidden IFS/HPFS (0x17)");
103
0
        break;
104
0
    case 0x18:
105
0
        snprintf(str, DESC_LEN, "AST SmartSleep (0x18)");
106
0
        break;
107
0
    case 0x19:
108
0
    case 0x1b:
109
0
    case 0x1c:
110
0
        snprintf(str, DESC_LEN, "Win95 FAT32 Hidden (0x%.2x)", ptype);
111
0
        break;
112
0
    case 0x1e:
113
0
        snprintf(str, DESC_LEN, "Win95 FAT16 Hidden (0x1e)");
114
0
        break;
115
0
    case 0x20:
116
0
    case 0x22:
117
0
    case 0x7e:
118
0
    case 0x7f:
119
0
    case 0xed:
120
0
    case 0xf7:
121
0
        snprintf(str, DESC_LEN, "Unused (0x%.2x)", ptype);
122
0
        break;
123
0
    case 0x21:
124
0
    case 0x23:
125
0
    case 0x26:
126
0
    case 0x31:
127
0
    case 0x33:
128
0
    case 0x34:
129
0
    case 0x36:
130
0
    case 0x71:
131
0
    case 0x73:
132
0
    case 0x76:
133
0
    case 0xf3:
134
0
        snprintf(str, DESC_LEN, "Reserved (0x%.2x)", ptype);
135
0
        break;
136
0
    case 0x24:
137
0
        snprintf(str, DESC_LEN, "NEC DOS 3.x (0x24)");
138
0
        break;
139
0
    case 0x32:
140
0
        snprintf(str, DESC_LEN, "NOS (0x32)");
141
0
        break;
142
0
    case 0x35:
143
0
        snprintf(str, DESC_LEN, "JFS on OS/2 or eCS  (0x35)");
144
0
        break;
145
0
    case 0x38:
146
0
        snprintf(str, DESC_LEN, "THEOS v3.2 2gb (0x38)");
147
0
        break;
148
0
    case 0x39:
149
0
        snprintf(str, DESC_LEN, "THEOS v4 Spanned (0x39)");
150
0
        break;
151
        /*
152
           case 0x39:
153
           snprintf(str, DESC_LEN, "Plan 9 (0x39)");
154
           break;
155
         */
156
0
    case 0x3a:
157
0
        snprintf(str, DESC_LEN, "THEOS v4 4gb (0x3a)");
158
0
        break;
159
0
    case 0x3b:
160
0
        snprintf(str, DESC_LEN, "THEOS v4 Extended (0x3b)");
161
0
        break;
162
0
    case 0x3c:
163
0
        snprintf(str, DESC_LEN, "PartitionMagic Recovery (0x3c)");
164
0
        break;
165
0
    case 0x3d:
166
0
        snprintf(str, DESC_LEN, "Hidden NetWare (0x3d)");
167
0
        break;
168
0
    case 0x40:
169
0
        snprintf(str, DESC_LEN, "Venix 80286 (0x40)");
170
0
        break;
171
0
    case 0x41:
172
0
        snprintf(str, DESC_LEN,
173
0
            "Linux/MINIX (Sharing Disk with DR-DOS) (0x41)");
174
0
        break;
175
        /*
176
           case 0x41:
177
           snprintf(str, DESC_LEN, "Personal RISC Boot (0x41)");
178
           break;
179
           case 0x41:
180
           snprintf(str, DESC_LEN, "PPC PReP Boot (0x41)");
181
           break;
182
         */
183
0
    case 0x42:
184
0
        snprintf(str, DESC_LEN, "Win LVM / Secure FS (0x42)");
185
0
        break;
186
0
    case 0x43:
187
0
        snprintf(str, DESC_LEN,
188
0
            "Linux Native (Sharing Disk with DR-DOS) (0x43)");
189
0
        break;
190
0
    case 0x44:
191
0
        snprintf(str, DESC_LEN, "GoBack (0x44)");
192
0
        break;
193
0
    case 0x45:
194
0
        snprintf(str, DESC_LEN, "Boot-US Boot Manager (0x45)");
195
0
        break;
196
        /*
197
           case 0x45:
198
           snprintf(str, DESC_LEN, "Priam (0x45)");
199
           break;
200
           case 0x45:
201
           snprintf(str, DESC_LEN, "EUMEL/Elan  (0x45)");
202
           break;
203
         */
204
0
    case 0x46:
205
0
        snprintf(str, DESC_LEN, "EUMEL/Elan  (0x46)");
206
0
        break;
207
0
    case 0x47:
208
0
        snprintf(str, DESC_LEN, "EUMEL/Elan  (0x47)");
209
0
        break;
210
0
    case 0x48:
211
0
        snprintf(str, DESC_LEN, "EUMEL/Elan  (0x48)");
212
0
        break;
213
0
    case 0x4a:
214
0
        snprintf(str, DESC_LEN,
215
0
            "Mark Aitchison's ALFS/THIN Lightweight Filesystem (0x4a)");
216
0
        break;
217
        /*case 0x4a:
218
           snprintf(str, DESC_LEN, "AdaOS Aquila (0x4a)");
219
           break; */
220
0
    case 0x4c:
221
0
        snprintf(str, DESC_LEN, "Oberon (0x4c)");
222
0
        break;
223
0
    case 0x4d:
224
0
    case 0x4e:
225
0
    case 0x4f:
226
0
        snprintf(str, DESC_LEN, "QNX 4.x (0x%.2x)", ptype);
227
0
        break;
228
        /*case 0x4f:
229
           snprintf(str, DESC_LEN, "Oberon (0x4f)");
230
           break; */
231
        /*case 0x52:
232
           snprintf(str, DESC_LEN, "CP/M (0x52)");
233
           break; */
234
0
    case 0x50:
235
0
    case 0x51:
236
0
    case 0x53:
237
0
    case 0x54:
238
0
        snprintf(str, DESC_LEN, "OnTrack Disk Manager (0x%.2x)", ptype);
239
0
        break;
240
0
    case 0x52:
241
0
        snprintf(str, DESC_LEN, "Microport SysV/AT (0x52)");
242
0
        break;
243
0
    case 0x55:
244
0
        snprintf(str, DESC_LEN, "EZ-Drive (0x55)");
245
0
        break;
246
0
    case 0x56:
247
0
        snprintf(str, DESC_LEN,
248
0
            "AT&T MS-DOS 3.x Logically Sectored FAT (0x56)");
249
0
        break;
250
        /*case 0x56:
251
           snprintf(str, DESC_LEN, "Golden Bow VFeature Partitioned Volume (0x56)");
252
           break; */
253
        /*case 0x56:
254
           snprintf(str, DESC_LEN, "DM Converted to EZ-BIOS (0x56)");
255
           break; */
256
0
    case 0x57:
257
0
        snprintf(str, DESC_LEN, "DrivePro (0x57)");
258
0
        break;
259
0
    case 0x5c:
260
0
        snprintf(str, DESC_LEN, "Priam EDisk (0x5c)");
261
0
        break;
262
0
    case 0x61:
263
0
        snprintf(str, DESC_LEN, "SpeedStor (0x61)");
264
0
        break;
265
0
    case 0x63:
266
0
        snprintf(str, DESC_LEN, "UNIX System V (0x63)");
267
0
        break;
268
0
    case 0x64:
269
0
    case 0x65:
270
0
    case 0x66:
271
0
    case 0x67:
272
0
    case 0x68:
273
0
    case 0x69:
274
0
        snprintf(str, DESC_LEN, "Novell Netware (0x%.2x)", ptype);
275
0
        break;
276
0
    case 0x70:
277
0
        snprintf(str, DESC_LEN, "DiskSecure Multi-Boot (0x70)");
278
0
        break;
279
0
    case 0x74:
280
0
        snprintf(str, DESC_LEN, "Scramdisk (0x74)");
281
0
        break;
282
0
    case 0x75:
283
0
        snprintf(str, DESC_LEN, "IBM PC/IX (0x75)");
284
0
        break;
285
0
    case 0x77:
286
0
        snprintf(str, DESC_LEN, "VNDI (0x77)");
287
0
        break;
288
        /*case 0x77:
289
           snprintf(str, DESC_LEN, "M2FS/M2CS (0x77)");
290
           break; */
291
0
    case 0x78:
292
0
        snprintf(str, DESC_LEN, "XOSL FS (0x78)");
293
0
        break;
294
0
    case 0x80:
295
0
        snprintf(str, DESC_LEN, "MINIX <=v1.4a (0x80)");
296
0
        break;
297
0
    case 0x81:
298
0
        snprintf(str, DESC_LEN, "MINIX >=v1.4b, Early Linux (0x81)");
299
0
        break;
300
        /*case 0x81:
301
           snprintf(str, DESC_LEN, "Mitac Disk Manager (0x81)");
302
           break; */
303
0
    case 0x82:
304
0
        snprintf(str, DESC_LEN, "Linux Swap / Solaris x86 (0x82)");
305
0
        break;
306
0
    case 0x83:
307
0
        snprintf(str, DESC_LEN, "Linux (0x83)");
308
0
        break;
309
0
    case 0x84:
310
0
        snprintf(str, DESC_LEN, "Hibernation (0x84)");
311
0
        break;
312
0
    case 0x85:
313
0
        snprintf(str, DESC_LEN, "Linux Extended (0x85)");
314
0
        break;
315
0
    case 0x86:
316
0
        snprintf(str, DESC_LEN, "NTFS Volume Set (0x86)");
317
0
        break;
318
0
    case 0x87:
319
0
        snprintf(str, DESC_LEN, "NTFS Volume Set (0x87)");
320
0
        break;
321
0
    case 0x8a:
322
0
        snprintf(str, DESC_LEN, "Linux Kernel (0x8a)");
323
0
        break;
324
0
    case 0x8b:
325
0
        snprintf(str, DESC_LEN, "Legacy Fault Tolerant FAT32 (0x8b)");
326
0
        break;
327
0
    case 0x8c:
328
0
        snprintf(str, DESC_LEN,
329
0
            "Legacy Fault Tolerant FAT32 using BIOS extd INT 13h (0x8c)");
330
0
        break;
331
0
    case 0x8d:
332
0
        snprintf(str, DESC_LEN,
333
0
            "Free FDISK Hidden Primary DOS FAT12 (0x8d)");
334
0
        break;
335
0
    case 0x8e:
336
0
        snprintf(str, DESC_LEN, "Linux Logical Volume Manager (0x8e)");
337
0
        break;
338
0
    case 0x90:
339
0
        snprintf(str, DESC_LEN,
340
0
            "Free FDISK Hidden Primary DOS FAT16 (0x90)");
341
0
        break;
342
0
    case 0x91:
343
0
        snprintf(str, DESC_LEN, "Free FDISK Hidden DOS Extended (0x91)");
344
0
        break;
345
0
    case 0x92:
346
0
        snprintf(str, DESC_LEN,
347
0
            "Free FDISK Hidden Primary DOS Large FAT16 (0x92)");
348
0
        break;
349
0
    case 0x93:
350
0
        snprintf(str, DESC_LEN, "Linux Hidden (0x93)");
351
0
        break;
352
0
    case 0x94:
353
0
        snprintf(str, DESC_LEN, "Amoeba Bad Block Table (0x94)");
354
0
        break;
355
0
    case 0x95:
356
0
        snprintf(str, DESC_LEN, "MIT EXOPC (0x95)");
357
0
        break;
358
0
    case 0x97:
359
0
        snprintf(str, DESC_LEN,
360
0
            "Free FDISK Hidden Primary DOS FAT32 (0x97)");
361
0
        break;
362
0
    case 0x98:
363
0
        snprintf(str, DESC_LEN,
364
0
            "Free FDISK Hidden Primary DOS FAT32 LBA (0x98)");
365
0
        break;
366
        /*case 0x98:
367
           snprintf(str, DESC_LEN, "Datalight ROM-DOS Super-Boot (0x98)");
368
           break; */
369
0
    case 0x99:
370
0
        snprintf(str, DESC_LEN, "DCE376 Logical Drive (0x99)");
371
0
        break;
372
0
    case 0x9a:
373
0
        snprintf(str, DESC_LEN,
374
0
            "Free FDISK Hidden Primary DOS FAT16 LBA (0x9a)");
375
0
        break;
376
0
    case 0x9b:
377
0
        snprintf(str, DESC_LEN,
378
0
            "Free FDISK Hidden DOS Extended LBA (0x9b)");
379
0
        break;
380
0
    case 0x9f:
381
0
        snprintf(str, DESC_LEN, "BSD/OS (0x9f)");
382
0
        break;
383
0
    case 0xa0:
384
0
    case 0xa1:
385
0
        snprintf(str, DESC_LEN, "Hibernation (0x%.2x)", ptype);
386
0
        break;
387
0
    case 0xa3:
388
0
        snprintf(str, DESC_LEN,
389
0
            "HP Volume Expansion (SpeedStor Variant) (0xa3)");
390
0
        break;
391
0
    case 0xa4:
392
0
        snprintf(str, DESC_LEN,
393
0
            "HP Volume Expansion (SpeedStor Variant) (0xa4)");
394
0
        break;
395
0
    case 0xa5:
396
0
        snprintf(str, DESC_LEN, "BSD/386, 386BSD, NetBSD, FreeBSD (0xa5)");
397
0
        break;
398
0
    case 0xa6:
399
0
        snprintf(str, DESC_LEN, "OpenBSD (0xa6)");
400
0
        break;
401
0
    case 0xa7:
402
0
        snprintf(str, DESC_LEN, "NeXTSTEP (0xa7)");
403
0
        break;
404
0
    case 0xa8:
405
0
        snprintf(str, DESC_LEN, "Mac OS X (0xa8)");
406
0
        break;
407
0
    case 0xa9:
408
0
        snprintf(str, DESC_LEN, "NetBSD (0xa9)");
409
0
        break;
410
0
    case 0xaa:
411
0
        snprintf(str, DESC_LEN, "Olivetti Fat 12 1.44MB Service (0xaa)");
412
0
        break;
413
0
    case 0xab:
414
0
        snprintf(str, DESC_LEN, "Mac OS X Boot Partition (0xab)");
415
0
        break;
416
0
    case 0xae:
417
0
        snprintf(str, DESC_LEN, "ShagOS Filesystem (0xae)");
418
0
        break;
419
0
    case 0xaf:
420
0
        snprintf(str, DESC_LEN, "Mac OS X HFS (0xaf)");
421
0
        break;
422
0
    case 0xb0:
423
0
        snprintf(str, DESC_LEN, "BootStar Dummy (0xb0)");
424
0
        break;
425
0
    case 0xb1:
426
0
        snprintf(str, DESC_LEN,
427
0
            "HP Volume Expansion (SpeedStor Variant) (0xb1)");
428
0
        break;
429
0
    case 0xb3:
430
0
        snprintf(str, DESC_LEN,
431
0
            "HP Volume Expansion (SpeedStor Variant) (0xb3)");
432
0
        break;
433
0
    case 0xb4:
434
0
        snprintf(str, DESC_LEN,
435
0
            "HP Volume Expansion (SpeedStor Variant) (0xb4)");
436
0
        break;
437
0
    case 0xb6:
438
0
        snprintf(str, DESC_LEN,
439
0
            "Corrupted Windows NT Mirror Set Master FAT16 (0xb6)");
440
0
        break;
441
        /*case 0xb6:
442
           snprintf(str, DESC_LEN, "HP Volume Expansion (SpeedStor Variant) (0xb6)");
443
           break; */
444
0
    case 0xb7:
445
0
        snprintf(str, DESC_LEN, "BSDI (0xb7)");
446
0
        break;
447
0
    case 0xb8:
448
0
        snprintf(str, DESC_LEN, "BSDI Swap (0xb8)");
449
0
        break;
450
0
    case 0xbb:
451
0
        snprintf(str, DESC_LEN, "Boot Wizard Hidden (0xbb)");
452
0
        break;
453
0
    case 0xbe:
454
0
        snprintf(str, DESC_LEN, "Solaris 8 Boot (0xbe)");
455
0
        break;
456
0
    case 0xc0:
457
0
        snprintf(str, DESC_LEN, "DR-DOS Secured (0xc0)");
458
0
        break;
459
        /*case 0xc0:
460
           snprintf(str, DESC_LEN, "CTOS (0xc0)");
461
           break; */
462
        /*case 0xc0:
463
           snprintf(str, DESC_LEN, "REAL/32 Secure Small (0xc0)");
464
           break; */
465
        /*case 0xc0:
466
           snprintf(str, DESC_LEN, "NTFT (0xc0)");
467
           break; */
468
0
    case 0xc1:
469
0
        snprintf(str, DESC_LEN, "DR-DOS Secured FAT12 (0xc1)");
470
0
        break;
471
0
    case 0xc2:
472
0
        snprintf(str, DESC_LEN, "Hidden Linux (0xc2)");
473
0
        break;
474
0
    case 0xc3:
475
0
        snprintf(str, DESC_LEN, "Hidden Linux Swap (0xc3)");
476
0
        break;
477
0
    case 0xc4:
478
0
        snprintf(str, DESC_LEN, "DR-DOS Secured FAT16 <32M (0xc4)");
479
0
        break;
480
0
    case 0xc5:
481
0
        snprintf(str, DESC_LEN, "DR-DOS Secured Extended (0xc5)");
482
0
        break;
483
0
    case 0xc6:
484
0
    case 0xc7:
485
0
        snprintf(str, DESC_LEN,
486
0
            "Corrupted Windows NT Volume / Stripe Set (0x%.2x)", ptype);
487
0
        break;
488
0
    case 0xc8:
489
0
        snprintf(str, DESC_LEN, "Reserved for DR-DOS 8.0+ (0xc8)");
490
0
        break;
491
0
    case 0xc9:
492
0
        snprintf(str, DESC_LEN, "Reserved for DR-DOS 8.0+ (0xc9)");
493
0
        break;
494
0
    case 0xca:
495
0
        snprintf(str, DESC_LEN, "Reserved for DR-DOS 8.0+ (0xca)");
496
0
        break;
497
0
    case 0xcb:
498
0
        snprintf(str, DESC_LEN, "DR-DOS 7.04+ Secured FAT32 CHS (0xcb)");
499
0
        break;
500
0
    case 0xcc:
501
0
        snprintf(str, DESC_LEN, "DR-DOS 7.04+ Secured FAT32 LBA (0xcc)");
502
0
        break;
503
0
    case 0xcd:
504
0
        snprintf(str, DESC_LEN, "CTOS Memdump? (0xcd)");
505
0
        break;
506
0
    case 0xce:
507
0
        snprintf(str, DESC_LEN, "DR-DOS 7.04+ FAT16X LBA (0xce)");
508
0
        break;
509
0
    case 0xcf:
510
0
        snprintf(str, DESC_LEN, "DR-DOS 7.04+ Secured EXT DOS LBA (0xcf)");
511
0
        break;
512
0
    case 0xd0:
513
0
        snprintf(str, DESC_LEN, "Multiuser DOS Secured (0xd0)");
514
0
        break;
515
        /*case 0xd0:
516
           snprintf(str, DESC_LEN, "REAL/32 Secure Big (0xd0)");
517
           break; */
518
0
    case 0xd1:
519
0
        snprintf(str, DESC_LEN, "Old Multiuser DOS Secured FAT12 (0xd1)");
520
0
        break;
521
0
    case 0xd4:
522
0
        snprintf(str, DESC_LEN,
523
0
            "Old Multiuser DOS Secured FAT16 <32M (0xd4)");
524
0
        break;
525
0
    case 0xd5:
526
0
        snprintf(str, DESC_LEN,
527
0
            "Old Multiuser DOS Secured extended (0xd5)");
528
0
        break;
529
0
    case 0xd6:
530
0
        snprintf(str, DESC_LEN,
531
0
            "Old Multiuser DOS Secured FAT16 >=32M (0xd6)");
532
0
        break;
533
0
    case 0xd8:
534
0
        snprintf(str, DESC_LEN, "CP/M-86 (0xd8)");
535
0
        break;
536
0
    case 0xda:
537
0
        snprintf(str, DESC_LEN, "Non-FS Data (0xda)");
538
0
        break;
539
0
    case 0xdb:
540
0
        snprintf(str, DESC_LEN,
541
0
            "Digital Research CP/M, Concurrent CP/M, Concurrent DOS (0xdb)");
542
0
        break;
543
        /*case 0xdb:
544
           snprintf(str, DESC_LEN, "Unisys CTOS (0xdb)");
545
           break; */
546
        /*case 0xdb:
547
           snprintf(str, DESC_LEN, "KDG Telemetry SCPU boot (0xdb)");
548
           break; */
549
0
    case 0xdd:
550
0
        snprintf(str, DESC_LEN, "Hidden CTOS Memdump?  (0xdd)");
551
0
        break;
552
0
    case 0xde:
553
0
        snprintf(str, DESC_LEN, "Dell Utilities FAT (0xde)");
554
0
        break;
555
        /*case 0xdf:
556
           snprintf(str, DESC_LEN, "DG/UX Virtual Disk Manager (0xdf)");
557
           break; */
558
        /*case 0xdf:
559
           snprintf(str, DESC_LEN, "BootIt EMBRM (0xdf)");
560
           break; */
561
0
    case 0xe0:
562
0
        snprintf(str, DESC_LEN,
563
0
            "Reserved by STMicroelectronics for ST AVFS. (0xe0)");
564
0
        break;
565
0
    case 0xe1:
566
0
        snprintf(str, DESC_LEN,
567
0
            "DOS Access or SpeedStor 12-bit FAT Extended (0xe1)");
568
0
        break;
569
0
    case 0xe3:
570
0
        snprintf(str, DESC_LEN, "DOS R/O or SpeedStor (0xe3)");
571
0
        break;
572
0
    case 0xe4:
573
0
        snprintf(str, DESC_LEN,
574
0
            "SpeedStor 16-bit FAT Extended <1024 cyl. (0xe4)");
575
0
        break;
576
0
    case 0xe5:
577
0
        snprintf(str, DESC_LEN,
578
0
            "Tandy MS-DOS with Logically Sectored FAT (0xe5)");
579
0
        break;
580
0
    case 0xe6:
581
0
        snprintf(str, DESC_LEN, "Storage Dimensions SpeedStor (0xe6)");
582
0
        break;
583
0
    case 0xeb:
584
0
        snprintf(str, DESC_LEN, "BeOS BFS (0xeb)");
585
0
        break;
586
0
    case 0xee:
587
0
        snprintf(str, DESC_LEN, "GPT Safety Partition (0xee)");
588
0
        break;
589
0
    case 0xef:
590
0
        snprintf(str, DESC_LEN, "EFI File System (0xef)");
591
0
        break;
592
0
    case 0xf0:
593
0
        snprintf(str, DESC_LEN, "Linux/PA-RISC Boot Loader (0xf0)");
594
0
        break;
595
0
    case 0xf1:
596
0
        snprintf(str, DESC_LEN, "Storage Dimensions SpeedStor (0xf1)");
597
0
        break;
598
0
    case 0xf2:
599
0
        snprintf(str, DESC_LEN, "DOS 3.3+ Secondary (0xf2)");
600
0
        break;
601
0
    case 0xf4:
602
0
        snprintf(str, DESC_LEN, "SpeedStor Large (0xf4)");
603
0
        break;
604
        /*case 0xf4:
605
           snprintf(str, DESC_LEN, "Prologue Single-Volume (0xf4)");
606
           break; */
607
0
    case 0xf5:
608
0
        snprintf(str, DESC_LEN, "Prologue Multi-Volume (0xf5)");
609
0
        break;
610
0
    case 0xf6:
611
0
        snprintf(str, DESC_LEN, "Storage Dimensions SpeedStor (0xf6)");
612
0
        break;
613
0
    case 0xf9:
614
0
        snprintf(str, DESC_LEN, "pCache (0xf9)");
615
0
        break;
616
0
    case 0xfa:
617
0
        snprintf(str, DESC_LEN, "Bochs (0xfa)");
618
0
        break;
619
0
    case 0xfb:
620
0
        snprintf(str, DESC_LEN, "VMWare File System (0xfb)");
621
0
        break;
622
0
    case 0xfc:
623
0
        snprintf(str, DESC_LEN, "VMWare Swap (0xfc)");
624
0
        break;
625
0
    case 0xfd:
626
0
        snprintf(str, DESC_LEN, "Linux RAID (0xfd)");
627
0
        break;
628
0
    case 0xfe:
629
0
        snprintf(str, DESC_LEN,
630
0
            "Windows NT Disk Administrator Hidden (0xfe)");
631
0
        break;
632
        /*case 0xfe:
633
           snprintf(str, DESC_LEN, "SpeedStor >1024 cyl. (0xfe)");
634
           break; */
635
        /*case 0xfe:
636
           snprintf(str, DESC_LEN, "LANstep (0xfe)");
637
           break; */
638
        /*case 0xfe:
639
           snprintf(str, DESC_LEN, "IBM PS/2 IML (0xfe)");
640
           break; */
641
        /*case 0xfe:
642
           snprintf(str, DESC_LEN, "Old Linux Logical Volume Manager (0xfe)");
643
           break; */
644
0
    case 0xff:
645
0
        snprintf(str, DESC_LEN, "Xenix Bad Block Table (0xff)");
646
0
        break;
647
0
    default:
648
0
        snprintf(str, DESC_LEN, "Unknown Type (0x%.2x)", ptype);
649
0
        break;
650
0
    }
651
652
0
    return str;
653
0
}
654
655
/*
656
 * Load an extended partition table into the structure in TSK_VS_INFO.
657
 *
658
 * sect_cur: The sector where the extended table is located
659
 * sect_ext_base: The sector of the primary extended table (this does
660
 *   not change for recursive calls)
661
 * table: a counter that identifies the table depth
662
 *   (increases by 1 for each recursive call)
663
 *
664
 * For the primary extended table, sect_cur == sect_ext_base
665
 *
666
 * Return 1 on error and 0 on success
667
 *
668
 */
669
static uint8_t
670
dos_load_ext_table(TSK_VS_INFO * vs, TSK_DADDR_T sect_cur,
671
    TSK_DADDR_T sect_ext_base, int table)
672
0
{
673
0
    dos_sect *sect;
674
0
    char *sect_buf;
675
0
    int i;
676
0
    char *table_str;
677
0
    ssize_t cnt;
678
0
    TSK_DADDR_T max_addr = (vs->img_info->size - vs->offset) / vs->block_size;  // max sector
679
680
0
    if (tsk_verbose)
681
0
        tsk_fprintf(stderr,
682
0
            "dos_load_ext: Table Sector: %" PRIuDADDR
683
0
            ", Primary Base Sector: %" PRIuDADDR "\n", sect_cur,
684
0
            sect_ext_base);
685
686
0
    if ((sect_buf = tsk_malloc(vs->block_size)) == NULL)
687
0
        return 1;
688
0
    sect = (dos_sect *) sect_buf;
689
690
    /* Read the partition table sector */
691
0
    cnt = tsk_vs_read_block(vs, sect_cur, sect_buf, vs->block_size);
692
0
    if (cnt != vs->block_size) {
693
0
        if (cnt >= 0) {
694
0
            tsk_error_reset();
695
0
            tsk_error_set_errno(TSK_ERR_VS_READ);
696
0
        }
697
0
        tsk_error_set_errstr2("Extended DOS table sector %" PRIuDADDR,
698
0
            sect_cur);
699
0
        free(sect_buf);
700
0
        return 1;
701
0
    }
702
703
    /* Sanity Check */
704
0
    if (tsk_getu16(vs->endian, sect->magic) != DOS_MAGIC) {
705
0
        tsk_error_reset();
706
0
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
707
0
        tsk_error_set_errstr("Extended DOS partition table in sector %"
708
0
            PRIuDADDR, sect_cur);
709
0
        free(sect_buf);
710
0
        return 1;
711
0
    }
712
713
    /* Add an entry of 1 length for the table  to the internal structure */
714
0
    if ((table_str = tsk_malloc(32)) == NULL) {
715
0
        free(sect_buf);
716
0
        return 1;
717
0
    }
718
719
0
    snprintf(table_str, 32, "Extended Table (#%d)", table);
720
0
    if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) sect_cur,
721
0
            (TSK_DADDR_T) 1, TSK_VS_PART_FLAG_META, table_str, table,
722
0
            -1)) {
723
0
        free(sect_buf);
724
0
        return 1;
725
0
    }
726
727
    /* Cycle through the four partitions in the table
728
     *
729
     * When another extended partition is found, it is processed
730
     * inside of the loop
731
     */
732
0
    for (i = 0; i < 4; i++) {
733
0
        dos_part *part = &sect->ptable[i];
734
735
        /* Get the starting sector and size, we currently
736
         * ignore CHS */
737
0
        uint32_t part_start = tsk_getu32(vs->endian, part->start_sec);
738
0
        uint32_t part_size = tsk_getu32(vs->endian, part->size_sec);
739
740
0
        if (tsk_verbose)
741
0
            tsk_fprintf(stderr,
742
0
                "load_ext: %d:%d    Start: %" PRIu32 "   Size: %"
743
0
                PRIu32 "  Type: %d\n", table, i, part_start, part_size,
744
0
                part->ptype);
745
746
        /* part_start == 0 would cause infinite recursion */
747
0
        if (part_size == 0 || part_start == 0)
748
0
            continue;
749
750
        /* partitions are addressed differently
751
         * in extended partitions */
752
0
        if (dos_is_ext(part->ptype)) {
753
754
0
            TSK_VS_PART_INFO *part_info;
755
756
            /* Sanity check to prevent infinite recursion in dos_load_ext_table.
757
             * If we already have a partition with this starting address then
758
             * return an error. This will prevent any more partitions from being
759
             * added but will leave any existing partitions alone. */
760
0
            part_info = vs->part_list;
761
0
            while (part_info != NULL) {
762
0
                if (part_info->start == (TSK_DADDR_T)(sect_ext_base + part_start)) {
763
0
                    if (tsk_verbose)
764
0
                        tsk_fprintf(stderr,
765
0
                            "Starting sector %" PRIuDADDR
766
0
                            " of extended partition has already been used\n",
767
0
                            (TSK_DADDR_T)(sect_ext_base + part_start));
768
0
                    tsk_error_reset();
769
0
                    tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
770
0
                    tsk_error_set_errstr
771
0
                        ("dos_load_ext_table: Loop in partition table detected");
772
0
                    free(sect_buf);
773
0
                    return 1;
774
0
                }
775
0
                part_info = part_info->next;
776
0
            }
777
778
            /* part start is added to the start of the
779
             * first extended partition (the primary
780
             * extended partition) */
781
782
0
            if (NULL == tsk_vs_part_add(vs,
783
0
                    (TSK_DADDR_T) (sect_ext_base + part_start),
784
0
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_META,
785
0
                    dos_get_desc(part->ptype), table, i)) {
786
0
                free(sect_buf);
787
0
                return 1;
788
0
            }
789
790
0
            if (sect_ext_base + part_start > max_addr) {
791
0
                if (tsk_verbose)
792
0
                    tsk_fprintf(stderr,
793
0
                        "Starting sector %" PRIuDADDR
794
0
                        " of extended partition too large for image\n",
795
0
                        sect_ext_base + part_start);
796
0
            }
797
            /* Process the extended partition */
798
0
            else if (dos_load_ext_table(vs, sect_ext_base + part_start,
799
0
                    sect_ext_base, table + 1)) {
800
0
                free(sect_buf);
801
0
                return 1;
802
0
            }
803
0
        }
804
805
0
        else {
806
            /* part_start is added to the start of the
807
             * current partition for the actual
808
             * starting location */
809
810
            // we ignore the max_addr checks on extended partitions...
811
812
0
            if (NULL == tsk_vs_part_add(vs,
813
0
                    (TSK_DADDR_T) (sect_cur + part_start),
814
0
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_ALLOC,
815
0
                    dos_get_desc(part->ptype), table, i)) {
816
0
                free(sect_buf);
817
0
                return 1;
818
0
            }
819
0
        }
820
0
    }
821
822
0
    free(sect_buf);
823
0
    return 0;
824
0
}
825
826
827
/*
828
 * Load the primary partition table (MBR) into the internal
829
 * data structures in TSK_VS_INFO
830
 *
831
 * This will automatically call load_ext_table for extended
832
 * partitions
833
 *
834
 * sect_cur is the address of the table to load
835
 *
836
 * 0 is returned if the load is successful and 1 if error
837
 */
838
static uint8_t
839
dos_load_prim_table(TSK_VS_INFO * vs, uint8_t test)
840
0
{
841
0
    dos_sect *sect;
842
0
    char *sect_buf;
843
0
    int i, added = 0;
844
0
    char *table_str;
845
0
    ssize_t cnt;
846
0
    TSK_DADDR_T taddr = vs->offset / vs->block_size + DOS_PART_SOFFSET;
847
0
    TSK_DADDR_T max_addr = (vs->img_info->size - vs->offset) / vs->block_size;  // max sector
848
849
0
    if (tsk_verbose)
850
0
        tsk_fprintf(stderr,
851
0
            "dos_load_prim: Table Sector: %" PRIuDADDR "\n", taddr);
852
853
0
    if ((sect_buf = tsk_malloc(vs->block_size)) == NULL)
854
0
        return 1;
855
0
    sect = (dos_sect *) sect_buf;
856
857
    /* Read the table */
858
0
    cnt = tsk_vs_read_block
859
0
        (vs, DOS_PART_SOFFSET, sect_buf, vs->block_size);
860
861
0
    if (cnt != vs->block_size) {
862
0
        if (cnt >= 0) {
863
0
            tsk_error_reset();
864
0
            tsk_error_set_errno(TSK_ERR_VS_READ);
865
0
        }
866
0
        tsk_error_set_errstr2("Primary DOS table sector %" PRIuDADDR,
867
0
            taddr);
868
0
        free(sect_buf);
869
0
        return 1;
870
0
    }
871
872
873
    /* Sanity Check */
874
0
    if (tsk_vs_guessu16(vs, sect->magic, DOS_MAGIC)) {
875
0
        tsk_error_reset();
876
0
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
877
0
        tsk_error_set_errstr
878
0
            ("File is not a DOS partition (invalid primary magic) (Sector: %"
879
0
            PRIuDADDR ")", taddr);
880
0
        if (tsk_verbose)
881
0
            fprintf(stderr,
882
0
                "File is not a DOS partition (invalid primary magic) (Sector: %"
883
0
                PRIuDADDR ")", taddr);
884
0
        free(sect_buf);
885
0
        return 1;
886
0
    }
887
888
    /* Because FAT and NTFS use the same magic - check for a
889
     * standard MS OEM name and sizes.  Not a great check, but we can't
890
     * really test the table entries.
891
     */
892
0
    if (test) {
893
0
        if (tsk_verbose)
894
0
            tsk_fprintf(stderr,
895
0
                "dos_load_prim_table: Testing FAT/NTFS conditions\n");
896
897
0
        if (strncmp("MSDOS", sect->oemname, 5) == 0) {
898
0
            tsk_error_reset();
899
0
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
900
0
            tsk_error_set_errstr
901
0
                ("dos_load_prim_table: MSDOS OEM name exists");
902
0
            if (tsk_verbose)
903
0
                tsk_fprintf(stderr,
904
0
                    "dos_load_prim_table: MSDOS OEM name exists\n");
905
0
            free(sect_buf);
906
0
            return 1;
907
0
        }
908
0
        else if (strncmp("MSWIN", sect->oemname, 5) == 0) {
909
0
            tsk_error_reset();
910
0
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
911
0
            tsk_error_set_errstr
912
0
                ("dos_load_prim_table: MSWIN OEM name exists");
913
0
            if (tsk_verbose)
914
0
                tsk_fprintf(stderr,
915
0
                    "dos_load_prim_table: MSWIN OEM name exists\n");
916
0
            free(sect_buf);
917
0
            return 1;
918
0
        }
919
0
        else if (strncmp("NTFS", sect->oemname, 4) == 0) {
920
0
            tsk_error_reset();
921
0
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
922
0
            tsk_error_set_errstr
923
0
                ("dos_load_prim_table: NTFS OEM name exists");
924
0
            if (tsk_verbose)
925
0
                tsk_fprintf(stderr,
926
0
                    "dos_load_prim_table: NTFS OEM name exists\n");
927
0
            free(sect_buf);
928
0
            return 1;
929
0
        }
930
0
        else if (strncmp("FAT", sect->oemname, 4) == 0) {
931
0
            tsk_error_reset();
932
0
            tsk_error_set_errno(TSK_ERR_VS_MAGIC);
933
0
            tsk_error_set_errstr
934
0
                ("dos_load_prim_table: FAT OEM name exists");
935
0
            if (tsk_verbose)
936
0
                tsk_fprintf(stderr,
937
0
                    "dos_load_prim_table: FAT OEM name exists\n");
938
0
            free(sect_buf);
939
0
            return 1;
940
0
        }
941
0
    }
942
943
    /* Add an entry of 1 sector for the table  to the internal structure */
944
0
    if ((table_str = tsk_malloc(32)) == NULL) {
945
0
        free(sect_buf);
946
0
        return 1;
947
0
    }
948
949
0
    snprintf(table_str, 32, "Primary Table (#0)");
950
0
    if (NULL == tsk_vs_part_add(vs, DOS_PART_SOFFSET, (TSK_DADDR_T) 1,
951
0
            TSK_VS_PART_FLAG_META, table_str, -1, -1)) {
952
0
        free(sect_buf);
953
0
        return 1;
954
0
    }
955
956
    /* Cycle through the partition table */
957
0
    for (i = 0; i < 4; i++) {
958
0
        dos_part *part = &sect->ptable[i];
959
960
        /* We currently ignore CHS */
961
0
        uint32_t part_start = tsk_getu32(vs->endian, part->start_sec);
962
0
        uint32_t part_size = tsk_getu32(vs->endian, part->size_sec);
963
964
0
        if (tsk_verbose)
965
0
            tsk_fprintf(stderr,
966
0
                "load_pri:0:%d    Start: %" PRIu32 "   Size: %" PRIu32
967
0
                "  Type: %d\n", i, part_start, part_size, part->ptype);
968
969
0
        if (part_size == 0)
970
0
            continue;
971
972
        // make sure the first couple are in the image bounds
973
0
        if ((i < 2) && (part_start > max_addr)) {
974
0
            tsk_error_reset();
975
0
            tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
976
0
            tsk_error_set_errstr
977
0
                ("dos_load_prim_table: Starting sector too large for image");
978
0
            if (tsk_verbose)
979
0
                tsk_fprintf(stderr,
980
0
                    "Starting sector %" PRIu32 " too large for image\n",
981
0
                    part_start);
982
0
            free(sect_buf);
983
0
            return 1;
984
0
        }
985
#if 0
986
// I'm not sure if this is too strict ...
987
        else if ((part_start + part_size) > max_addr) {
988
            tsk_error_reset();
989
            tsk_error_set_errno(TSK_ERR_VS_BLK_NUM);
990
            tsk_error_set_errstr
991
                ("dos_load_prim_table: Partition ends after image");
992
            return 1;
993
        }
994
#endif
995
996
0
        added = 1;
997
998
        /* Add the partition to the internal structure
999
         * If it is an extended partition, process it now */
1000
0
        if (dos_is_ext(part->ptype)) {
1001
0
            if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) part_start,
1002
0
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_META,
1003
0
                    dos_get_desc(part->ptype), 0, i)) {
1004
0
                free(sect_buf);
1005
0
                return 1;
1006
0
            }
1007
1008
0
            if (dos_load_ext_table(vs, part_start, part_start, 1)) {
1009
0
                if (tsk_verbose) {
1010
0
                    fprintf(stderr,
1011
0
                        "Error loading extended table, moving on");
1012
0
                    tsk_error_print(stderr);
1013
0
                }
1014
0
                tsk_error_reset();
1015
0
            }
1016
0
        }
1017
0
        else {
1018
0
            if (NULL == tsk_vs_part_add(vs, (TSK_DADDR_T) part_start,
1019
0
                    (TSK_DADDR_T) part_size, TSK_VS_PART_FLAG_ALLOC,
1020
0
                    dos_get_desc(part->ptype), 0, i)) {
1021
0
                free(sect_buf);
1022
0
                return 1;
1023
0
            }
1024
0
        }
1025
0
    }
1026
0
    free(sect_buf);
1027
1028
0
    if (added == 0) {
1029
0
        if (tsk_verbose)
1030
0
            tsk_fprintf(stderr, "dos_load_prim: No valid entries\n");
1031
1032
0
        tsk_error_reset();
1033
0
        tsk_error_set_errno(TSK_ERR_VS_MAGIC);
1034
0
        tsk_error_set_errstr
1035
0
            ("dos_load_prim_table: No valid entries in primary table");
1036
0
        return 1;
1037
0
    }
1038
0
    return 0;
1039
0
}
1040
1041
1042
static void
1043
dos_close(TSK_VS_INFO * vs)
1044
0
{
1045
0
    vs->tag = 0;
1046
0
    tsk_vs_part_free(vs);
1047
0
    free(vs);
1048
0
}
1049
1050
1051
/*
1052
 * Given the path to the file, open it and load the internal
1053
 * partition table structure
1054
 *
1055
 * offset is the byte offset to the start of the volume system
1056
 *
1057
 * If test is 1 then additional tests are performed to make sure
1058
 * it isn't a FAT or NTFS file system. This is used when autodetection
1059
 * is being used to detect the volume system type.
1060
 */
1061
TSK_VS_INFO *
1062
tsk_vs_dos_open(TSK_IMG_INFO * img_info, TSK_DADDR_T offset, uint8_t test)
1063
0
{
1064
0
    TSK_VS_INFO *vs;
1065
1066
    // clean up any errors that are lying around
1067
0
    tsk_error_reset();
1068
1069
0
    if (img_info->sector_size == 0) {
1070
0
        tsk_error_reset();
1071
0
        tsk_error_set_errno(TSK_ERR_VS_ARG);
1072
0
        tsk_error_set_errstr("tsk_vs_dos_open: sector size is 0");
1073
0
        return NULL;
1074
0
    }
1075
1076
0
    vs = (TSK_VS_INFO *) tsk_malloc(sizeof(*vs));
1077
0
    if (vs == NULL)
1078
0
        return NULL;
1079
1080
0
    vs->vstype = TSK_VS_TYPE_DOS;
1081
0
    vs->tag = TSK_VS_INFO_TAG;
1082
0
    vs->img_info = img_info;
1083
1084
0
    vs->offset = offset;
1085
1086
    /* initialize settings */
1087
0
    vs->part_list = NULL;
1088
0
    vs->part_count = 0;
1089
0
    vs->endian = 0;
1090
0
    vs->block_size = img_info->sector_size;
1091
1092
1093
    /* Assign functions */
1094
0
    vs->close = dos_close;
1095
1096
    /* Load the partitions into the sorted list */
1097
0
    if (dos_load_prim_table(vs, test)) {
1098
0
        dos_close(vs);
1099
0
        return NULL;
1100
0
    }
1101
1102
    /* fill in the sorted list with the 'unknown' values */
1103
0
    if (tsk_vs_part_unused(vs)) {
1104
0
        dos_close(vs);
1105
0
        return NULL;
1106
0
    }
1107
1108
0
    return vs;
1109
0
}