-
Notifications
You must be signed in to change notification settings - Fork 52
/
MBRTemplateFAT.bt
executable file
·887 lines (773 loc) · 22.4 KB
/
MBRTemplateFAT.bt
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
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
//----------------------------------------
//--- 010 Editor v4.0 Binary Template
//
// File: MBR_FAT16_FAT32_NTFS.bt
// Author: Benjamin Vernoux ([email protected])
// Revision: 0.1 Beta 14 January 2013
// Purpose: Defines a template for
// FAT16 or FAT32 drive with support of MBR
//----------------------------------------
LittleEndian();
typedef char BOOL;
typedef char BYTE;
typedef unsigned char UBYTE;
typedef short SHORT;
typedef unsigned short USHORT;
typedef long LONG;
typedef unsigned long ULONG;
// Global Shared Variable
local quad DataAreaSector;
local quad DataAreaFilePos;
local quad CurrentPosSector;
local unsigned char SizeOfEach_ClusterEntry_InBytes;
//##############################
// MBR
//##############################
// Partition Types
typedef enum <uchar> tagSYSTEMID
{
EMPTY = 0,
FAT_12 = 1,
XENIX_ROOT = 2,
XENIX_USR = 3,
FAT_16_INF32MB = 4,
EXTENDED = 5,
FAT_16 = 6,
NTFS_HPFS = 7,
AIX = 8,
AIX_BOOT = 9,
OS2_BOOT_MGR = 10,
PRI_FAT32_INT13 = 11,
EXT_FAT32_INT13 = 12,
EXT_FAT16_INT13 = 14,
WIN95_EXT = 15,
OPUS = 16,
FAT_12_HIDDEN = 17,
COMPAQ_DIAG = 18,
FAT_16_HIDDEN_INF32MB = 20,
FAT_16_HIDDEN = 22,
NTFS_HPFS_HIDDEN = 23,
VENIX = 64,
NOVEL0 = 81,
MICROPORT = 82,
GNU_HURD = 99,
NOVEL1 = 100,
PC_IX = 117,
MINUX_OLD = 128,
MINUX_LINUX = 129,
LINUX_SWAP = 130,
LINUX_NATIVE = 131,
AMOEBA = 147,
AMOEBA_BBT = 148,
BSD_386 = 165,
BSDI_FS = 183,
BSDI_SWAP = 184,
SYRINX = 199,
CP_M = 219,
ACCESS_DOS = 225,
DOS_R_O = 227,
DOS_SECONDARY = 242,
BBT = 255
} SYSTEMID;
// Boot Indicator Values
typedef enum <uchar> tagBOOTINDICATOR
{
NOBOOT = 0,
SYSTEM_PARTITION = 128,
} BOOTINDICATOR;
// Partition Entry
typedef struct PART_ENTRY
{
BOOTINDICATOR BootIndicator;
UBYTE StartingHead;
WORD StartingSectCylinder; // Need Bit fields
SYSTEMID SystemID;
UBYTE EndingHead;
WORD EndingSectCylinder; // Need Bit fields
DWORD RelativeSector;
DWORD TotalSectors;
} PART_ENTRY;
// MBR
struct MASTER_BOOT_RECORD
{
UBYTE BootCode[446];
PART_ENTRY partitions[4];
WORD EndOfSectorMarker <format=hex>;
};
//##############################
// FAT16 Boot Sector
//##############################
struct BOOTSECTOR_FAT16
{
UBYTE jmp[3];
CHAR OemName[8];
typedef struct BPB_FAT16
{
USHORT BytesPerSector;
UBYTE SectorsPerCluster;
USHORT ReservedSectors;
UBYTE NumberOfCopiesOfFats;
USHORT MaxRootDirEntries;
USHORT NumberOfSectors;
UBYTE MediaDescriptor;
USHORT SectorsPerFAT;
USHORT SectorsPerTrack;
USHORT NumHeadsPerCylinder;
ULONG NumHiddenSectors;
ULONG NumSectorInPartition;
};
BPB_FAT16 bpb_fat16;
USHORT LogicDriveNumber;
UBYTE extBootSignature <format=hex>;
ULONG SerialNumber;
CHAR VolumeLabel[11];
CHAR FileSystem[8];
UBYTE ExecutableCode[448];
WORD EndOfSectorMarker <format=hex>;
};
//##############################
// FAT16 FAT Table
//##############################
typedef enum <ushort> tagMEDIATYPE
{
HARD_DISK = 0xfff8,
FLOPPY_DISK = 0xfff0
} MEDIATYPE;
typedef enum <ushort> tagPARTITIONSTATE
{
PARTITION_NOT_IN_USE = 0xffff,
PARTITION_IN_USE = 0xfff7
} PARTITIONSTATE;
typedef enum <ushort> tagCLUSTERINFO
{
FREE_CLUSTER = 0x0000,
RESERVED_0001 = 0x0001,
RESERVED_FFF0 = 0xFFF0,
RESERVED_FFF1 = 0xFFF1,
RESERVED_FFF2 = 0xFFF2,
RESERVED_FFF3 = 0xFFF3,
RESERVED_FFF4 = 0xFFF4,
RESERVED_FFF5 = 0xFFF5,
RESERVED_FFF6 = 0xFFF6,
BAD_CLUSTER = 0xFFF7,
USED_LAST_CLUSTER_FFF8 = 0xFFF8,
USED_LAST_CLUSTER_FFF9 = 0xFFF9,
USED_LAST_CLUSTER_FFFA = 0xFFFA,
USED_LAST_CLUSTER_FFFB = 0xFFFB,
USED_LAST_CLUSTER_FFFC = 0xFFFC,
USED_LAST_CLUSTER_FFFD = 0xFFFD,
USED_LAST_CLUSTER_FFFE = 0xFFFE,
USED_LAST_CLUSTER_FFFF = 0xFFFF
} CLUSTERINFO;
void FAT16_FAT_Table(quad FilePosStartFatTable,quad SizeOfFatTableInSectors, UBYTE NumberOfCopiesOfFats)
{
SizeOfEach_ClusterEntry_InBytes=2;
FSeek(FilePosStartFatTable);
if(NumberOfCopiesOfFats==1)
{
MEDIATYPE FAT16_MediaType;
PARTITIONSTATE FAT16_PartitionState;
CLUSTERINFO FAT16_Cluster[ (((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes) ];
}else if(NumberOfCopiesOfFats==2)
{
MEDIATYPE FAT16_MediaType_FAT1;
PARTITIONSTATE FAT16_PartitionState_FAT1;
CLUSTERINFO FAT16_Cluster_FAT1[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-1 ];
MEDIATYPE FAT16_MediaType_FAT2;
PARTITIONSTATE FAT16_PartitionState_FAT2;
CLUSTERINFO FAT16_Cluster_FAT2[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-1 ];
}
}
//##############################
// FAT16 Directory Entry
//##############################
typedef enum <uchar> tagAttribute
{
NoneOrFile = 0,
ReadOnly = 1, // bit0
Hidden = 2, // bit1
ReadOnlyHidden = 3,
System = 4, // bit2
ReadOnlySystem = 5,
HiddenSystem0 = 6,
ReadOnlyHiddenSystem= 7,
VolumeID = 8, // bit3
ReadOnlyVolume = 9,
HiddenSystem1 = 10,
ReadOnlySystemVolume0 = 11,
SystemVolume = 12,
ReadOnlySystemVolume1 = 13,
HiddenSystemVolume = 14,
LFN_Entry = 15,
Directory = 16, // bit4
Archive = 32, // bit5
ArchiveReadOnly = 33,
ArchiveHidden = 34
}ATTR;
typedef struct tagTime
{
USHORT Sec : 5; // bit0-4 need to be multiplied by 2
USHORT Min : 6; // bit5-10
USHORT Hour : 5; // bit11-15
}tTIME;
typedef struct tagDate
{
USHORT Day : 5; // bit0-4
USHORT Month : 4; // bit5-8
USHORT YearSince1980 : 7; // bit9-15
}tDATE;
typedef struct ShortEntry // Normal-Short structure
{
CHAR Name[8]; // Blank-padded name
CHAR Extension[3]; //Blank-padded extension
ATTR Attribute; // See tagAttribute enum only 5 valid bit (from 0 to 4)
UBYTE Reserved;
UBYTE CreateTime10ms; //10-ms unit’s "Create Time" refinement
tTIME CreateTime;
tDATE CreateDate;
tDATE AccessDate;
USHORT HCluster; // Used on FAT32 only
tTIME UpdateTime;
tDATE UpdateDate;
USHORT Cluster;
ULONG FileSizeInBytes; //File size in bytes (always zero for directories).
} SHORTENTRY <read=Read_SHORT_DIR_ENTRY>;
unsigned char FAT16_Attribute(ATTR Attribute, string &stmp)
{
unsigned char volume=0;
switch(Attribute)
{
case NoneOrFile:
stmp="NoneOrFile";
break;
case ReadOnly:
stmp="ReadOnly";
break;
case Hidden:
stmp="Hidden";
break;
case ReadOnlyHidden:
stmp="ReadOnlyHidden";
break;
case System:
stmp="System";
volume=1;
break;
case ReadOnlySystem:
stmp="ReadOnlySystem";
volume=1;
break;
case HiddenSystem0:
stmp="HiddenSystem0";
volume=1;
break;
case ReadOnlyHiddenSystem:
stmp="ReadOnlyHiddenSystem";
volume=1;
break;
case VolumeID:
stmp="VolumeID";
volume=1;
break;
case ReadOnlyVolume:
stmp="ReadOnlyVolume";
volume=1;
break;
case HiddenSystem1:
stmp="HiddenSystem1";
break;
case ReadOnlySystemVolume0:
stmp="ReadOnlySystemVolume0";
break;
case SystemVolume:
stmp="SystemVolume";
volume=1;
break;
case ReadOnlySystemVolume1:
stmp="ReadOnlySystemVolume1";
volume=1;
break;
case HiddenSystemVolume:
stmp="HiddenSystemVolume";
volume=1;
break;
case LFN_Entry:
stmp="LFN_Entry";
break;
case Directory:
stmp="Directory";
volume=1;
break;
case Archive:
stmp="Archive";
break;
case ArchiveReadOnly:
stmp="ArchiveReadOnly";
break;
case ArchiveHidden:
stmp="ArchiveHidden";
break;
default:
stmp="Unknown";
volume=1;
break;
}
return volume;
}
string Read_SHORT_DIR_ENTRY( SHORTENTRY &f )
{
string s;
string stmp;
unsigned char volume=0;
s="";
if(f.Name[0]==0)
{
return "Last Dir Entry Empty";
}
// Short Entry
volume=FAT16_Attribute(f.Attribute, stmp);
s+=stmp;
if(volume)
{
SPrintf(stmp, "=%08s%03s",f.Name,f.Extension);
s+=stmp;
}else
{
SPrintf(stmp, "=%08s.%03s",f.Name,f.Extension);
s+=stmp;
}
return s;
}
typedef struct tagLFN_RecordSeqNum
{
UBYTE LFN_RecSeqNum : 6; // bit0-5 LFN sequence number (1..63)
UBYTE Last_LFN_record : 1; // bit6 Last LFN record in the sequence
UBYTE LFN_Erased : 1; // bit7 LFN record is an erased long name entry or maybe if it is part of an erased long name?
}tLFN_RecordSeqNum;
local string sconv;
local unsigned short iconv;
string Conv_UnicodeToASCII(char data[], unsigned short totalsize_inbyte)
{
sconv="";
for(iconv=0;iconv<totalsize_inbyte;iconv+=2)
{
if( data[iconv]!=-1 )
{
sconv+=data[iconv];
}
}
return sconv;
}
local string s_longentry;
typedef struct LongEntry // Long File Name (LFN) Entry Format
{
//############
// Structure
//############
typedef struct internalLongEntry
{
typedef union ulfn
{
tLFN_RecordSeqNum LFN_RecordSeqNum; // LFN Record Sequence Number
unsigned char char0;
}ULFN;
ULFN LFN;
char UnicodeChar1[10]; //5 UNICODE characters, LFN first part.
ATTR Attribute; // This field contains the special value of 0Fh, which indicates an LFN entry.
UBYTE Reserved;
UBYTE ChkShortName; // Checksum of short name entry, used to validate that the LFN entry belongs to the short name entry following. According to Ralf Brown's interrupt list, the checksum is computed by adding up all the short name characters and rotating the intermediate value right by one bit position before adding each character.
char UnicodeChar2[12]; //6 UNICODE characters, LFN 2nd part.
USHORT Cluster; //Initial cluster number, which is always zero for LFN entries.
char UnicodeChar3[4]; //2 UNICODE characters, LFN 3rd part.
}ILONGENTRY;
local unsigned char NumberOfLFNEntry;
local unsigned char dirname0;
dirname0=ReadByte(FTell());
if( !(dirname0==0x00) )
{
if( dirname0==0xE5 ) // Empty/Erased
{
for(i=0;i<63;i++)
{
dirname0=ReadByte(FTell());
if( !(dirname0==0xE5) ) // Check still Empty/Erased ?
break;
if(ReadByte(FTell()+11)!=0x0f) // Check is still LFN ?
break;
ILONGENTRY long_entry;
}
}else
{
ILONGENTRY long_entry;
NumberOfLFNEntry=long_entry.LFN.LFN_RecordSeqNum.LFN_RecSeqNum-1;
for(i=0;i<NumberOfLFNEntry;i++)
{
ILONGENTRY long_entry;
}
}
}
}LONGENTRY <read=Read_LONG_DIR_ENTRY>;
string Read_LONG_DIR_ENTRY( LONGENTRY &f )
{
local unsigned short i;
local unsigned short NumberOfLFNEntry;
local string str;
str="";
if(f.long_entry[0].LFN.LFN_RecordSeqNum.LFN_Erased==1)
{
// Entry deleted
str+="Erased name:";
// Count number of erased entry
for(i=0;i<63;i++)
{
if(exists(f.long_entry[i].LFN.char0))
{
if(f.long_entry[i].LFN.char0!=0xE5)
{
break;
}
}else
{
break;
}
}
NumberOfLFNEntry=i-1;
}else
{
// Long Entry
str+="Name:";
NumberOfLFNEntry=f.long_entry[0].LFN.LFN_RecordSeqNum.LFN_RecSeqNum-1;
}
for(i=NumberOfLFNEntry;i>0;i--)
{
str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar1,10);
str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar2,12);
str+=Conv_UnicodeToASCII(f.long_entry[i].UnicodeChar3,4);
}
str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar1,10);
str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar2,12);
str+=Conv_UnicodeToASCII(f.long_entry[0].UnicodeChar3,4);
return str;
}
/*
typedef union FAT16_DirEntry
{
struct ShortEntry shortEntry;
struct LongEntry longEntry;
};
*/
/*
void FAT16_DIR_ENTRYWrite( FAT16_DIR_ENTRY &f, string s )
{
SScanf( s, "%d-%d-%d %d:%d:%d", f[0], f[1], f[2], f[3], f[4], f[5] );
}
*/
void FAT16_Directory_Entry(quad FilePosStartDirectoryEntry)
{
FSeek(FilePosStartDirectoryEntry);
i=0;
while(1)
{
if(ReadByte(FTell()+11)==0x0f) // LFN Entry
{
LONGENTRY fat16_long_direntry;
}else
{
SHORTENTRY fat16_short_direntry;
if(fat16_short_direntry.Name[0]==0 && fat16_short_direntry.Name[1]==0) // End of Directory Entry
{
break;
}
}
}
}
//##############################
// FAT32 Boot Sector
//##############################
struct BOOTSECTOR_FAT32
{
BYTE jmp[3];
CHAR OemName[8];
typedef struct BPB_FAT32
{
WORD BytesPerSector;
BYTE SectorsPerCluster;
WORD ReservedSectors;
BYTE NumberOfFATs;
WORD RootEntries;
WORD TotalSectors;
BYTE Media;
WORD SectorsPerFAT;
WORD SectorsPerTrack;
WORD HeadsPerCylinder;
DWORD HiddenSectors;
DWORD TotalSectorsBig;
DWORD SectorsPerFAT;
WORD Flags;
WORD Version;
DWORD RootCluster;
WORD InfoSector;
WORD BootBackupStart;
BYTE Reserved[12];
};
BPB_FAT32 bpb_fat32;
BYTE DriveNumber;
BYTE Unused;
BYTE ExtBootSignature <format=hex>;
DWORD SerialNumber;
CHAR VolumeLabel[11];
CHAR FileSystem[8];
CHAR BootCode[420];
WORD EndOfSectorMarker <format=hex>;
};
//##############################
// FAT32 FAT Table
//##############################
// Warning on FAT32 only 28bit contain value
// 4 high bit (MSB) are reserved for future use.
// It is why following FAT32 enum could be wrong if 4 high bit reserved are different from 0x0 or 0xf
typedef enum <ulong> tagMEDIATYPE_FAT32
{
HARD_DISK_FAT32 = 0x0ffffff8,
FLOPPY_DISK_FAT32 = 0x0ffffff0
} MEDIATYPE_FAT32;
typedef enum <ulong> tagPARTITIONSTATE_FAT32
{
PARTITION_NOT_IN_USE_FAT32 = 0xffffffff,
PARTITION_IN_USE_FAT32 = 0xfffffff7
} PARTITIONSTATE_FAT32;
typedef enum <ulong> tagCLUSTERINFO_FAT32
{
FREE_CLUSTER_FAT32 = 0x00000000,
RESERVED_0001_FAT32 = 0x00000001,
RESERVED_FFF0_FAT32 = 0x0FFFFFF0,
RESERVED_FFF1_FAT32 = 0x0FFFFFF1,
RESERVED_FFF2_FAT32 = 0x0FFFFFF2,
RESERVED_FFF3_FAT32 = 0x0FFFFFF3,
RESERVED_FFF4_FAT32 = 0x0FFFFFF4,
RESERVED_FFF5_FAT32 = 0x0FFFFFF5,
RESERVED_FFF6_FAT32 = 0x0FFFFFF6,
BAD_CLUSTER_FAT32 = 0x0FFFFFF7,
USED_LAST_CLUSTER_FFF8_FAT32 = 0x0FFFFFF8,
USED_LAST_CLUSTER_FFF9_FAT32 = 0x0FFFFFF9,
USED_LAST_CLUSTER_FFFA_FAT32 = 0x0FFFFFFA,
USED_LAST_CLUSTER_FFFB_FAT32 = 0x0FFFFFFB,
USED_LAST_CLUSTER_FFFC_FAT32 = 0x0FFFFFFC,
USED_LAST_CLUSTER_FFFD_FAT32 = 0x0FFFFFFD,
USED_LAST_CLUSTER_FFFE_FAT32 = 0x0FFFFFFE,
USED_LAST_CLUSTER_FFFF_FAT32 = 0x0FFFFFFF
} CLUSTERINFO_FAT32;
void FAT32_FAT_Table(quad FilePosStartFatTable,quad SizeOfFatTableInSectors, UBYTE NumberOfCopiesOfFats)
{
local unsigned char SizeOfEach_ClusterEntry_InBytes;
SizeOfEach_ClusterEntry_InBytes=4;
FSeek(FilePosStartFatTable);
if(NumberOfCopiesOfFats==1)
{
MEDIATYPE_FAT32 FAT32_MediaType;
PARTITIONSTATE_FAT32 FAT32_PartitionState;
CLUSTERINFO_FAT32 FAT32_Cluster[ (((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes) ];
}else if(NumberOfCopiesOfFats==2)
{
MEDIATYPE_FAT32 FAT32_MediaType_FAT1;
PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT1;
CLUSTERINFO_FAT32 FAT32_Cluster_FAT1[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-0 ];
MEDIATYPE_FAT32 FAT32_MediaType_FAT2;
PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT2;
CLUSTERINFO_FAT32 FAT32_Cluster_FAT2[ ((((SizeOfFatTableInSectors*512)/SizeOfEach_ClusterEntry_InBytes)-SizeOfEach_ClusterEntry_InBytes)/NumberOfCopiesOfFats)-0 ];
}
}
void FAT32_Directory_Entry(quad FilePosStartDirectoryEntry)
{
FSeek(FilePosStartDirectoryEntry);
i=0;
while(1)
{
if(ReadByte(FTell()+11)==0x0f) // LFN Entry
{
LONGENTRY fat32_long_direntry;
}else
{
SHORTENTRY fat32_short_direntry;
if(fat32_short_direntry.Name[0]==0 && fat32_short_direntry.Name[1]==0) // End of Directory Entry
{
break;
}
}
}
}
//##############################
// NTFS Boot Sector
//##############################
struct BOOTSECTOR_NTFS
{
BYTE jmp[3]; // Jump Instruction
CHAR OEMName[8]; // OEM Identifier
typedef struct BPB_NTFS
{
WORD BytesPerSector;
BYTE SectorsPerCluster;
WORD ReservedSectors;
BYTE Zero[3];
WORD NotUsed;
BYTE MediaDescriptor;
WORD Zero;
WORD SectorsPerTrack;
WORD HeadsPerCylinder;
DWORD HiddenSectors;
DWORD NotUsed;
DWORD NotUsed;
UQUAD TotalSectors;
UQUAD LogicalClusterMFT;
UQUAD LogicalClusterMFTMiror;
DWORD ClustersPerFileRecSegment;
DWORD ClustersPerIndexBlock;
UQUAD SerialNumber;
DWORD Checksum;
};
BPB_NTFS bpb_ntfs;
BYTE BootCode[426];
WORD EndOfSectorMarker <format=hex>;
};
typedef union boot
{
struct MASTER_BOOT_RECORD mbr;
struct BOOTSECTOR_FAT16 boot_fat16;
struct BOOTSECTOR_FAT32 boot_fat32;
struct BOOTSECTOR_NTFS boot_ntfs;
};
void FAT16CheckInit(SYSTEMID SystemID)
{
if( SystemID==FAT_16_INF32MB ||
SystemID==FAT_16 ||
SystemID==EXT_FAT16_INT13
)
{
CurrentPosSector=FTell()/512;
BOOTSECTOR_FAT16 detected_fat16;
FATTableSector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors;
RootDirEntrySector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors+
(detected_fat16.bpb_fat16.SectorsPerFAT*2);
RootDirEntryFilePos=RootDirEntrySector*512;
FATTableFilePos=FATTableSector*512;
FATTableSizeInSectors=RootDirEntrySector-FATTableSector;
// FAT16 FAT Table
FAT16_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat16.bpb_fat16.NumberOfCopiesOfFats);
// FAT16 Directory Entry
FAT16_Directory_Entry(RootDirEntryFilePos);
DataAreaSector=CurrentPosSector+detected_fat16.bpb_fat16.ReservedSectors+
(detected_fat16.bpb_fat16.SectorsPerFAT*2)+
((detected_fat16.bpb_fat16.MaxRootDirEntries*32)/detected_fat16.bpb_fat16.BytesPerSector);
DataAreaFilePos=DataAreaSector*512;
//FSeek(DataAreaSector*512);
//unsigned char DataArea[4096];
}
}
void FAT32CheckInit(SYSTEMID SystemID)
{
if( SystemID==PRI_FAT32_INT13 ||
SystemID==EXT_FAT32_INT13
)
{
CurrentPosSector=FTell()/512;
struct BOOTSECTOR_FAT32 detected_fat32;
FATTableSector=CurrentPosSector+detected_fat32.bpb_fat32.ReservedSectors;
RootDirEntrySector=CurrentPosSector+detected_fat32.bpb_fat32.ReservedSectors+
(detected_fat32.bpb_fat32.SectorsPerFAT*2);
RootDirEntryFilePos=RootDirEntrySector*512;
FATTableFilePos=FATTableSector*512;
FATTableSizeInSectors=RootDirEntrySector-FATTableSector;
// FAT32 FAT Table
FAT32_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat32.bpb_fat32.NumberOfFATs);
// FAT32 Directory Entry
FAT32_Directory_Entry(RootDirEntryFilePos);
}
}
//######################################
// Check if it's a drive access on FAT
//######################################
typedef struct _FATStruct
{
local unsigned short mbr_boot_ok=0;
local quad FATTableSector;
local quad FATTableFilePos;
local quad FATTableSizeInSectors;
local quad RootDirEntrySector;
local quad RootDirEntryFilePos;
// Check EndOfSectorMarker (present on MBR/FAT16/FAT32/NTFS
if(ReadUShort(510)==0xAA55)
{
boot boot_sect;
local unsigned short i;
// Check if MBR (check BootIndicator)
for(i=0;i<4;i++)
{
if( (boot_sect.mbr.partitions[i].BootIndicator==SYSTEM_PARTITION ||
boot_sect.mbr.partitions[i].BootIndicator==NOBOOT) &&
boot_sect.mbr.partitions[i].SystemID!=EMPTY
)
{
if(mbr_boot_ok==0)
{
FSeek(0);
MASTER_BOOT_RECORD detected_mbr;
mbr_boot_ok=1;
}
// Jump to Partition
FSeek(boot_sect.mbr.partitions[i].RelativeSector*512);
// Check type of filesystem and add it if found
FAT16CheckInit(boot_sect.mbr.partitions[i].SystemID);
FAT32CheckInit(boot_sect.mbr.partitions[i].SystemID);
}
}
// Check if FAT16
if(boot_sect.boot_fat16.FileSystem=="FAT16 ")
{
FSeek(0);
BOOTSECTOR_FAT16 detected_fat16;
FATTableSector=0+detected_fat16.bpb_fat16.ReservedSectors;
RootDirEntrySector=0+detected_fat16.bpb_fat16.ReservedSectors+
(detected_fat16.bpb_fat16.SectorsPerFAT*2);
RootDirEntryFilePos=RootDirEntrySector*512;
FATTableFilePos=FATTableSector*512;
FATTableSizeInSectors=RootDirEntrySector-FATTableSector;
// FAT16 FAT Table
FAT16_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat16.bpb_fat16.NumberOfCopiesOfFats);
// FAT16 Directory Entry
FAT16_Directory_Entry(RootDirEntryFilePos);
DataAreaSector=0+detected_fat16.bpb_fat16.ReservedSectors+
(detected_fat16.bpb_fat16.SectorsPerFAT*2)+
((detected_fat16.bpb_fat16.MaxRootDirEntries*32)/detected_fat16.bpb_fat16.BytesPerSector);
DataAreaFilePos=DataAreaSector*512;
//FSeek(DataAreaSector*512);
//unsigned char DataArea[4096];
}
// Check if FAT32
if(boot_sect.boot_fat32.FileSystem=="FAT32 ")
{
FSeek(0);
struct BOOTSECTOR_FAT32 detected_fat32;
FATTableSector=0+detected_fat32.bpb_fat32.ReservedSectors;
RootDirEntrySector=0+detected_fat32.bpb_fat32.ReservedSectors+
(detected_fat32.bpb_fat32.SectorsPerFAT*2);
RootDirEntryFilePos=RootDirEntrySector*512;
FATTableFilePos=FATTableSector*512;
FATTableSizeInSectors=RootDirEntrySector-FATTableSector;
// FAT32 FAT Table
FAT32_FAT_Table(FATTableFilePos,FATTableSizeInSectors,detected_fat32.bpb_fat32.NumberOfFATs);
// FAT32 Directory Entry
FAT32_Directory_Entry(RootDirEntryFilePos);
}
// Check if NTFS
//FSeek(0);
//struct BOOTSECTOR_NTFS detected_ntfs;
}else
{
/*
Warning( "File/Disk is not a valid MBR/FAT16/FAT32/NTFS (wrong BootIndicator). Template stopped." );
return -1;
*/
}
}MBR_FAT;
MBR_FAT mbr_fat;
// Shared DataAreaSector && DataAreaFilePos