mirror of https://github.com/x64dbg/btparser
888 lines
22 KiB
Plaintext
888 lines
22 KiB
Plaintext
|
1:
|
||
|
2:
|
||
|
3:
|
||
|
4:
|
||
|
5:
|
||
|
6:
|
||
|
7:
|
||
|
8:
|
||
|
9:
|
||
|
10: LittleEndian ( ) ;
|
||
|
11:
|
||
|
12: typedef char BOOL ;
|
||
|
13: typedef char BYTE ;
|
||
|
14: typedef unsigned char UBYTE ;
|
||
|
15: typedef short SHORT ;
|
||
|
16: typedef unsigned short USHORT ;
|
||
|
17: typedef long LONG ;
|
||
|
18: typedef unsigned long ULONG ;
|
||
|
19:
|
||
|
20:
|
||
|
21: local quad DataAreaSector ;
|
||
|
22: local quad DataAreaFilePos ;
|
||
|
23:
|
||
|
24: local quad CurrentPosSector ;
|
||
|
25:
|
||
|
26: local unsigned char SizeOfEach_ClusterEntry_InBytes ;
|
||
|
27:
|
||
|
28:
|
||
|
29:
|
||
|
30:
|
||
|
31:
|
||
|
32: typedef enum < uchar > tagSYSTEMID
|
||
|
33: {
|
||
|
34: EMPTY = 0 ,
|
||
|
35: FAT_12 = 1 ,
|
||
|
36: XENIX_ROOT = 2 ,
|
||
|
37: XENIX_USR = 3 ,
|
||
|
38: FAT_16_INF32MB = 4 ,
|
||
|
39: EXTENDED = 5 ,
|
||
|
40: FAT_16 = 6 ,
|
||
|
41: NTFS_HPFS = 7 ,
|
||
|
42: AIX = 8 ,
|
||
|
43: AIX_BOOT = 9 ,
|
||
|
44: OS2_BOOT_MGR = 10 ,
|
||
|
45: PRI_FAT32_INT13 = 11 ,
|
||
|
46: EXT_FAT32_INT13 = 12 ,
|
||
|
47: EXT_FAT16_INT13 = 14 ,
|
||
|
48: WIN95_EXT = 15 ,
|
||
|
49: OPUS = 16 ,
|
||
|
50: FAT_12_HIDDEN = 17 ,
|
||
|
51: COMPAQ_DIAG = 18 ,
|
||
|
52: FAT_16_HIDDEN_INF32MB = 20 ,
|
||
|
53: FAT_16_HIDDEN = 22 ,
|
||
|
54: NTFS_HPFS_HIDDEN = 23 ,
|
||
|
55: VENIX = 64 ,
|
||
|
56: NOVEL0 = 81 ,
|
||
|
57: MICROPORT = 82 ,
|
||
|
58: GNU_HURD = 99 ,
|
||
|
59: NOVEL1 = 100 ,
|
||
|
60: PC_IX = 117 ,
|
||
|
61: MINUX_OLD = 128 ,
|
||
|
62: MINUX_LINUX = 129 ,
|
||
|
63: LINUX_SWAP = 130 ,
|
||
|
64: LINUX_NATIVE = 131 ,
|
||
|
65: AMOEBA = 147 ,
|
||
|
66: AMOEBA_BBT = 148 ,
|
||
|
67: BSD_386 = 165 ,
|
||
|
68: BSDI_FS = 183 ,
|
||
|
69: BSDI_SWAP = 184 ,
|
||
|
70: SYRINX = 199 ,
|
||
|
71: CP_M = 219 ,
|
||
|
72: ACCESS_DOS = 225 ,
|
||
|
73: DOS_R_O = 227 ,
|
||
|
74: DOS_SECONDARY = 242 ,
|
||
|
75: BBT = 255
|
||
|
76: } SYSTEMID ;
|
||
|
77:
|
||
|
78:
|
||
|
79: typedef enum < uchar > tagBOOTINDICATOR
|
||
|
80: {
|
||
|
81: NOBOOT = 0 ,
|
||
|
82: SYSTEM_PARTITION = 128 ,
|
||
|
83: } BOOTINDICATOR ;
|
||
|
84:
|
||
|
85:
|
||
|
86: typedef struct PART_ENTRY
|
||
|
87: {
|
||
|
88: BOOTINDICATOR BootIndicator ;
|
||
|
89: UBYTE StartingHead ;
|
||
|
90: WORD StartingSectCylinder ;
|
||
|
91: SYSTEMID SystemID ;
|
||
|
92: UBYTE EndingHead ;
|
||
|
93: WORD EndingSectCylinder ;
|
||
|
94: DWORD RelativeSector ;
|
||
|
95: DWORD TotalSectors ;
|
||
|
96: } PART_ENTRY ;
|
||
|
97:
|
||
|
98:
|
||
|
99: struct MASTER_BOOT_RECORD
|
||
|
100: {
|
||
|
101: UBYTE BootCode [ 446 ] ;
|
||
|
102: PART_ENTRY partitions [ 4 ] ;
|
||
|
103: WORD EndOfSectorMarker < format = hex > ;
|
||
|
104: } ;
|
||
|
105:
|
||
|
106:
|
||
|
107:
|
||
|
108:
|
||
|
109: struct BOOTSECTOR_FAT16
|
||
|
110: {
|
||
|
111: UBYTE jmp [ 3 ] ;
|
||
|
112: CHAR OemName [ 8 ] ;
|
||
|
113:
|
||
|
114: typedef struct BPB_FAT16
|
||
|
115: {
|
||
|
116: USHORT BytesPerSector ;
|
||
|
117: UBYTE SectorsPerCluster ;
|
||
|
118: USHORT ReservedSectors ;
|
||
|
119: UBYTE NumberOfCopiesOfFats ;
|
||
|
120: USHORT MaxRootDirEntries ;
|
||
|
121: USHORT NumberOfSectors ;
|
||
|
122: UBYTE MediaDescriptor ;
|
||
|
123: USHORT SectorsPerFAT ;
|
||
|
124: USHORT SectorsPerTrack ;
|
||
|
125: USHORT NumHeadsPerCylinder ;
|
||
|
126: ULONG NumHiddenSectors ;
|
||
|
127: ULONG NumSectorInPartition ;
|
||
|
128: } ;
|
||
|
129: BPB_FAT16 bpb_fat16 ;
|
||
|
130: USHORT LogicDriveNumber ;
|
||
|
131: UBYTE extBootSignature < format = hex > ;
|
||
|
132: ULONG SerialNumber ;
|
||
|
133: CHAR VolumeLabel [ 11 ] ;
|
||
|
134: CHAR FileSystem [ 8 ] ;
|
||
|
135: UBYTE ExecutableCode [ 448 ] ;
|
||
|
136: WORD EndOfSectorMarker < format = hex > ;
|
||
|
137: } ;
|
||
|
138:
|
||
|
139:
|
||
|
140:
|
||
|
141:
|
||
|
142: typedef enum < ushort > tagMEDIATYPE
|
||
|
143: {
|
||
|
144: HARD_DISK = 0xFFF8 ,
|
||
|
145: FLOPPY_DISK = 0xFFF0
|
||
|
146: } MEDIATYPE ;
|
||
|
147:
|
||
|
148: typedef enum < ushort > tagPARTITIONSTATE
|
||
|
149: {
|
||
|
150: PARTITION_NOT_IN_USE = 0xFFFF ,
|
||
|
151: PARTITION_IN_USE = 0xFFF7
|
||
|
152: } PARTITIONSTATE ;
|
||
|
153:
|
||
|
154: typedef enum < ushort > tagCLUSTERINFO
|
||
|
155: {
|
||
|
156: FREE_CLUSTER = 0x0 ,
|
||
|
157: RESERVED_0001 = 0x1 ,
|
||
|
158: RESERVED_FFF0 = 0xFFF0 ,
|
||
|
159: RESERVED_FFF1 = 0xFFF1 ,
|
||
|
160: RESERVED_FFF2 = 0xFFF2 ,
|
||
|
161: RESERVED_FFF3 = 0xFFF3 ,
|
||
|
162: RESERVED_FFF4 = 0xFFF4 ,
|
||
|
163: RESERVED_FFF5 = 0xFFF5 ,
|
||
|
164: RESERVED_FFF6 = 0xFFF6 ,
|
||
|
165: BAD_CLUSTER = 0xFFF7 ,
|
||
|
166: USED_LAST_CLUSTER_FFF8 = 0xFFF8 ,
|
||
|
167: USED_LAST_CLUSTER_FFF9 = 0xFFF9 ,
|
||
|
168: USED_LAST_CLUSTER_FFFA = 0xFFFA ,
|
||
|
169: USED_LAST_CLUSTER_FFFB = 0xFFFB ,
|
||
|
170: USED_LAST_CLUSTER_FFFC = 0xFFFC ,
|
||
|
171: USED_LAST_CLUSTER_FFFD = 0xFFFD ,
|
||
|
172: USED_LAST_CLUSTER_FFFE = 0xFFFE ,
|
||
|
173: USED_LAST_CLUSTER_FFFF = 0xFFFF
|
||
|
174: } CLUSTERINFO ;
|
||
|
175:
|
||
|
176: void FAT16_FAT_Table ( quad FilePosStartFatTable , quad SizeOfFatTableInSectors , UBYTE NumberOfCopiesOfFats )
|
||
|
177: {
|
||
|
178: SizeOfEach_ClusterEntry_InBytes = 2 ;
|
||
|
179:
|
||
|
180: FSeek ( FilePosStartFatTable ) ;
|
||
|
181:
|
||
|
182: if ( NumberOfCopiesOfFats == 1 )
|
||
|
183: {
|
||
|
184: MEDIATYPE FAT16_MediaType ;
|
||
|
185: PARTITIONSTATE FAT16_PartitionState ;
|
||
|
186: CLUSTERINFO FAT16_Cluster [ ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) ] ;
|
||
|
187: } else if ( NumberOfCopiesOfFats == 2 )
|
||
|
188: {
|
||
|
189:
|
||
|
190: MEDIATYPE FAT16_MediaType_FAT1 ;
|
||
|
191: PARTITIONSTATE FAT16_PartitionState_FAT1 ;
|
||
|
192: CLUSTERINFO FAT16_Cluster_FAT1 [ ( ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) / NumberOfCopiesOfFats ) - 1 ] ;
|
||
|
193:
|
||
|
194: MEDIATYPE FAT16_MediaType_FAT2 ;
|
||
|
195: PARTITIONSTATE FAT16_PartitionState_FAT2 ;
|
||
|
196: CLUSTERINFO FAT16_Cluster_FAT2 [ ( ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) / NumberOfCopiesOfFats ) - 1 ] ;
|
||
|
197: }
|
||
|
198: }
|
||
|
199:
|
||
|
200:
|
||
|
201:
|
||
|
202:
|
||
|
203:
|
||
|
204: typedef enum < uchar > tagAttribute
|
||
|
205: {
|
||
|
206: NoneOrFile = 0 ,
|
||
|
207: ReadOnly = 1 ,
|
||
|
208: Hidden = 2 ,
|
||
|
209: ReadOnlyHidden = 3 ,
|
||
|
210: System = 4 ,
|
||
|
211: ReadOnlySystem = 5 ,
|
||
|
212: HiddenSystem0 = 6 ,
|
||
|
213: ReadOnlyHiddenSystem = 7 ,
|
||
|
214: VolumeID = 8 ,
|
||
|
215: ReadOnlyVolume = 9 ,
|
||
|
216: HiddenSystem1 = 10 ,
|
||
|
217: ReadOnlySystemVolume0 = 11 ,
|
||
|
218: SystemVolume = 12 ,
|
||
|
219: ReadOnlySystemVolume1 = 13 ,
|
||
|
220: HiddenSystemVolume = 14 ,
|
||
|
221: LFN_Entry = 15 ,
|
||
|
222: Directory = 16 ,
|
||
|
223: Archive = 32 ,
|
||
|
224: ArchiveReadOnly = 33 ,
|
||
|
225: ArchiveHidden = 34
|
||
|
226: } ATTR ;
|
||
|
227:
|
||
|
228: typedef struct tagTime
|
||
|
229: {
|
||
|
230: USHORT Sec : 5 ;
|
||
|
231: USHORT Min : 6 ;
|
||
|
232: USHORT Hour : 5 ;
|
||
|
233: } tTIME ;
|
||
|
234:
|
||
|
235: typedef struct tagDate
|
||
|
236: {
|
||
|
237: USHORT Day : 5 ;
|
||
|
238: USHORT Month : 4 ;
|
||
|
239: USHORT YearSince1980 : 7 ;
|
||
|
240: } tDATE ;
|
||
|
241:
|
||
|
242: typedef struct ShortEntry
|
||
|
243: {
|
||
|
244: CHAR Name [ 8 ] ;
|
||
|
245: CHAR Extension [ 3 ] ;
|
||
|
246: ATTR Attribute ;
|
||
|
247: UBYTE Reserved ;
|
||
|
248: UBYTE CreateTime10ms ;
|
||
|
249: tTIME CreateTime ;
|
||
|
250: tDATE CreateDate ;
|
||
|
251: tDATE AccessDate ;
|
||
|
252: USHORT HCluster ;
|
||
|
253: tTIME UpdateTime ;
|
||
|
254: tDATE UpdateDate ;
|
||
|
255: USHORT Cluster ;
|
||
|
256: ULONG FileSizeInBytes ;
|
||
|
257: } SHORTENTRY < read = Read_SHORT_DIR_ENTRY > ;
|
||
|
258:
|
||
|
259: unsigned char FAT16_Attribute ( ATTR Attribute , string & stmp )
|
||
|
260: {
|
||
|
261: unsigned char volume = 0 ;
|
||
|
262:
|
||
|
263: switch ( Attribute )
|
||
|
264: {
|
||
|
265: case NoneOrFile :
|
||
|
266: stmp = "NoneOrFile" ;
|
||
|
267: break ;
|
||
|
268:
|
||
|
269: case ReadOnly :
|
||
|
270: stmp = "ReadOnly" ;
|
||
|
271: break ;
|
||
|
272:
|
||
|
273: case Hidden :
|
||
|
274: stmp = "Hidden" ;
|
||
|
275: break ;
|
||
|
276:
|
||
|
277: case ReadOnlyHidden :
|
||
|
278: stmp = "ReadOnlyHidden" ;
|
||
|
279: break ;
|
||
|
280:
|
||
|
281: case System :
|
||
|
282: stmp = "System" ;
|
||
|
283: volume = 1 ;
|
||
|
284: break ;
|
||
|
285:
|
||
|
286: case ReadOnlySystem :
|
||
|
287: stmp = "ReadOnlySystem" ;
|
||
|
288: volume = 1 ;
|
||
|
289: break ;
|
||
|
290:
|
||
|
291: case HiddenSystem0 :
|
||
|
292: stmp = "HiddenSystem0" ;
|
||
|
293: volume = 1 ;
|
||
|
294: break ;
|
||
|
295:
|
||
|
296: case ReadOnlyHiddenSystem :
|
||
|
297: stmp = "ReadOnlyHiddenSystem" ;
|
||
|
298: volume = 1 ;
|
||
|
299: break ;
|
||
|
300:
|
||
|
301: case VolumeID :
|
||
|
302: stmp = "VolumeID" ;
|
||
|
303: volume = 1 ;
|
||
|
304: break ;
|
||
|
305:
|
||
|
306: case ReadOnlyVolume :
|
||
|
307: stmp = "ReadOnlyVolume" ;
|
||
|
308: volume = 1 ;
|
||
|
309: break ;
|
||
|
310:
|
||
|
311: case HiddenSystem1 :
|
||
|
312: stmp = "HiddenSystem1" ;
|
||
|
313: break ;
|
||
|
314:
|
||
|
315: case ReadOnlySystemVolume0 :
|
||
|
316: stmp = "ReadOnlySystemVolume0" ;
|
||
|
317: break ;
|
||
|
318:
|
||
|
319: case SystemVolume :
|
||
|
320: stmp = "SystemVolume" ;
|
||
|
321: volume = 1 ;
|
||
|
322: break ;
|
||
|
323:
|
||
|
324: case ReadOnlySystemVolume1 :
|
||
|
325: stmp = "ReadOnlySystemVolume1" ;
|
||
|
326: volume = 1 ;
|
||
|
327: break ;
|
||
|
328:
|
||
|
329: case HiddenSystemVolume :
|
||
|
330: stmp = "HiddenSystemVolume" ;
|
||
|
331: volume = 1 ;
|
||
|
332: break ;
|
||
|
333:
|
||
|
334: case LFN_Entry :
|
||
|
335: stmp = "LFN_Entry" ;
|
||
|
336: break ;
|
||
|
337:
|
||
|
338: case Directory :
|
||
|
339: stmp = "Directory" ;
|
||
|
340: volume = 1 ;
|
||
|
341: break ;
|
||
|
342:
|
||
|
343: case Archive :
|
||
|
344: stmp = "Archive" ;
|
||
|
345: break ;
|
||
|
346:
|
||
|
347: case ArchiveReadOnly :
|
||
|
348: stmp = "ArchiveReadOnly" ;
|
||
|
349: break ;
|
||
|
350:
|
||
|
351: case ArchiveHidden :
|
||
|
352: stmp = "ArchiveHidden" ;
|
||
|
353: break ;
|
||
|
354:
|
||
|
355: default :
|
||
|
356: stmp = "Unknown" ;
|
||
|
357: volume = 1 ;
|
||
|
358: break ;
|
||
|
359: }
|
||
|
360: return volume ;
|
||
|
361: }
|
||
|
362:
|
||
|
363: string Read_SHORT_DIR_ENTRY ( SHORTENTRY & f )
|
||
|
364: {
|
||
|
365: string s ;
|
||
|
366: string stmp ;
|
||
|
367: unsigned char volume = 0 ;
|
||
|
368:
|
||
|
369: s = "" ;
|
||
|
370: if ( f . Name [ 0 ] == 0 )
|
||
|
371: {
|
||
|
372: return "Last Dir Entry Empty" ;
|
||
|
373: }
|
||
|
374:
|
||
|
375:
|
||
|
376: volume = FAT16_Attribute ( f . Attribute , stmp ) ;
|
||
|
377: s += stmp ;
|
||
|
378:
|
||
|
379: if ( volume )
|
||
|
380: {
|
||
|
381: SPrintf ( stmp , "=%08s%03s" , f . Name , f . Extension ) ;
|
||
|
382: s += stmp ;
|
||
|
383: } else
|
||
|
384: {
|
||
|
385: SPrintf ( stmp , "=%08s.%03s" , f . Name , f . Extension ) ;
|
||
|
386: s += stmp ;
|
||
|
387: }
|
||
|
388: return s ;
|
||
|
389: }
|
||
|
390:
|
||
|
391: typedef struct tagLFN_RecordSeqNum
|
||
|
392: {
|
||
|
393: UBYTE LFN_RecSeqNum : 6 ;
|
||
|
394: UBYTE Last_LFN_record : 1 ;
|
||
|
395: UBYTE LFN_Erased : 1 ;
|
||
|
396: } tLFN_RecordSeqNum ;
|
||
|
397:
|
||
|
398: local string sconv ;
|
||
|
399: local unsigned short iconv ;
|
||
|
400: string Conv_UnicodeToASCII ( char data [ ] , unsigned short totalsize_inbyte )
|
||
|
401: {
|
||
|
402: sconv = "" ;
|
||
|
403: for ( iconv = 0 ; iconv < totalsize_inbyte ; iconv += 2 )
|
||
|
404: {
|
||
|
405: if ( data [ iconv ] != - 1 )
|
||
|
406: {
|
||
|
407: sconv += data [ iconv ] ;
|
||
|
408: }
|
||
|
409: }
|
||
|
410: return sconv ;
|
||
|
411: }
|
||
|
412:
|
||
|
413: local string s_longentry ;
|
||
|
414:
|
||
|
415: typedef struct LongEntry
|
||
|
416: {
|
||
|
417:
|
||
|
418:
|
||
|
419:
|
||
|
420: typedef struct internalLongEntry
|
||
|
421: {
|
||
|
422: typedef union ulfn
|
||
|
423: {
|
||
|
424: tLFN_RecordSeqNum LFN_RecordSeqNum ;
|
||
|
425: unsigned char char0 ;
|
||
|
426: } ULFN ;
|
||
|
427: ULFN LFN ;
|
||
|
428: char UnicodeChar1 [ 10 ] ;
|
||
|
429: ATTR Attribute ;
|
||
|
430: UBYTE Reserved ;
|
||
|
431: UBYTE ChkShortName ;
|
||
|
432: char UnicodeChar2 [ 12 ] ;
|
||
|
433: USHORT Cluster ;
|
||
|
434: char UnicodeChar3 [ 4 ] ;
|
||
|
435: } ILONGENTRY ;
|
||
|
436:
|
||
|
437: local unsigned char NumberOfLFNEntry ;
|
||
|
438: local unsigned char dirname0 ;
|
||
|
439: dirname0 = ReadByte ( FTell ( ) ) ;
|
||
|
440: if ( ! ( dirname0 == 0x0 ) )
|
||
|
441: {
|
||
|
442: if ( dirname0 == 0xE5 )
|
||
|
443: {
|
||
|
444: for ( i = 0 ; i < 63 ; i ++ )
|
||
|
445: {
|
||
|
446: dirname0 = ReadByte ( FTell ( ) ) ;
|
||
|
447: if ( ! ( dirname0 == 0xE5 ) )
|
||
|
448: break ;
|
||
|
449:
|
||
|
450: if ( ReadByte ( FTell ( ) + 11 ) != 0xF )
|
||
|
451: break ;
|
||
|
452:
|
||
|
453: ILONGENTRY long_entry ;
|
||
|
454: }
|
||
|
455: } else
|
||
|
456: {
|
||
|
457: ILONGENTRY long_entry ;
|
||
|
458: NumberOfLFNEntry = long_entry . LFN . LFN_RecordSeqNum . LFN_RecSeqNum - 1 ;
|
||
|
459: for ( i = 0 ; i < NumberOfLFNEntry ; i ++ )
|
||
|
460: {
|
||
|
461: ILONGENTRY long_entry ;
|
||
|
462: }
|
||
|
463: }
|
||
|
464: }
|
||
|
465: } LONGENTRY < read = Read_LONG_DIR_ENTRY > ;
|
||
|
466:
|
||
|
467: string Read_LONG_DIR_ENTRY ( LONGENTRY & f )
|
||
|
468: {
|
||
|
469: local unsigned short i ;
|
||
|
470: local unsigned short NumberOfLFNEntry ;
|
||
|
471: local string str ;
|
||
|
472:
|
||
|
473: str = "" ;
|
||
|
474:
|
||
|
475: if ( f . long_entry [ 0 ] . LFN . LFN_RecordSeqNum . LFN_Erased == 1 )
|
||
|
476: {
|
||
|
477:
|
||
|
478: str += "Erased name:" ;
|
||
|
479:
|
||
|
480: for ( i = 0 ; i < 63 ; i ++ )
|
||
|
481: {
|
||
|
482: if ( exists ( f . long_entry [ i ] . LFN . char0 ) )
|
||
|
483: {
|
||
|
484: if ( f . long_entry [ i ] . LFN . char0 != 0xE5 )
|
||
|
485: {
|
||
|
486: break ;
|
||
|
487: }
|
||
|
488: } else
|
||
|
489: {
|
||
|
490: break ;
|
||
|
491: }
|
||
|
492: }
|
||
|
493: NumberOfLFNEntry = i - 1 ;
|
||
|
494: } else
|
||
|
495: {
|
||
|
496:
|
||
|
497: str += "Name:" ;
|
||
|
498: NumberOfLFNEntry = f . long_entry [ 0 ] . LFN . LFN_RecordSeqNum . LFN_RecSeqNum - 1 ;
|
||
|
499: }
|
||
|
500: for ( i = NumberOfLFNEntry ; i > 0 ; i -- )
|
||
|
501: {
|
||
|
502: str += Conv_UnicodeToASCII ( f . long_entry [ i ] . UnicodeChar1 , 10 ) ;
|
||
|
503: str += Conv_UnicodeToASCII ( f . long_entry [ i ] . UnicodeChar2 , 12 ) ;
|
||
|
504: str += Conv_UnicodeToASCII ( f . long_entry [ i ] . UnicodeChar3 , 4 ) ;
|
||
|
505: }
|
||
|
506: str += Conv_UnicodeToASCII ( f . long_entry [ 0 ] . UnicodeChar1 , 10 ) ;
|
||
|
507: str += Conv_UnicodeToASCII ( f . long_entry [ 0 ] . UnicodeChar2 , 12 ) ;
|
||
|
508: str += Conv_UnicodeToASCII ( f . long_entry [ 0 ] . UnicodeChar3 , 4 ) ;
|
||
|
509: return str ;
|
||
|
510: }
|
||
|
511:
|
||
|
512:
|
||
|
513:
|
||
|
514:
|
||
|
515:
|
||
|
516:
|
||
|
517:
|
||
|
518:
|
||
|
519:
|
||
|
520:
|
||
|
521:
|
||
|
522:
|
||
|
523:
|
||
|
524:
|
||
|
525:
|
||
|
526:
|
||
|
527: void FAT16_Directory_Entry ( quad FilePosStartDirectoryEntry )
|
||
|
528: {
|
||
|
529: FSeek ( FilePosStartDirectoryEntry ) ;
|
||
|
530: i = 0 ;
|
||
|
531: while ( 1 )
|
||
|
532: {
|
||
|
533: if ( ReadByte ( FTell ( ) + 11 ) == 0xF )
|
||
|
534: {
|
||
|
535: LONGENTRY fat16_long_direntry ;
|
||
|
536: } else
|
||
|
537: {
|
||
|
538: SHORTENTRY fat16_short_direntry ;
|
||
|
539: if ( fat16_short_direntry . Name [ 0 ] == 0 && fat16_short_direntry . Name [ 1 ] == 0 )
|
||
|
540: {
|
||
|
541: break ;
|
||
|
542: }
|
||
|
543: }
|
||
|
544: }
|
||
|
545: }
|
||
|
546:
|
||
|
547:
|
||
|
548:
|
||
|
549:
|
||
|
550: struct BOOTSECTOR_FAT32
|
||
|
551: {
|
||
|
552: BYTE jmp [ 3 ] ;
|
||
|
553: CHAR OemName [ 8 ] ;
|
||
|
554:
|
||
|
555: typedef struct BPB_FAT32
|
||
|
556: {
|
||
|
557: WORD BytesPerSector ;
|
||
|
558: BYTE SectorsPerCluster ;
|
||
|
559: WORD ReservedSectors ;
|
||
|
560: BYTE NumberOfFATs ;
|
||
|
561: WORD RootEntries ;
|
||
|
562: WORD TotalSectors ;
|
||
|
563: BYTE Media ;
|
||
|
564: WORD SectorsPerFAT ;
|
||
|
565: WORD SectorsPerTrack ;
|
||
|
566: WORD HeadsPerCylinder ;
|
||
|
567: DWORD HiddenSectors ;
|
||
|
568: DWORD TotalSectorsBig ;
|
||
|
569: DWORD SectorsPerFAT ;
|
||
|
570: WORD Flags ;
|
||
|
571: WORD Version ;
|
||
|
572: DWORD RootCluster ;
|
||
|
573: WORD InfoSector ;
|
||
|
574: WORD BootBackupStart ;
|
||
|
575: BYTE Reserved [ 12 ] ;
|
||
|
576: } ;
|
||
|
577:
|
||
|
578: BPB_FAT32 bpb_fat32 ;
|
||
|
579:
|
||
|
580: BYTE DriveNumber ;
|
||
|
581: BYTE Unused ;
|
||
|
582: BYTE ExtBootSignature < format = hex > ;
|
||
|
583: DWORD SerialNumber ;
|
||
|
584: CHAR VolumeLabel [ 11 ] ;
|
||
|
585: CHAR FileSystem [ 8 ] ;
|
||
|
586: CHAR BootCode [ 420 ] ;
|
||
|
587: WORD EndOfSectorMarker < format = hex > ;
|
||
|
588: } ;
|
||
|
589:
|
||
|
590:
|
||
|
591:
|
||
|
592:
|
||
|
593:
|
||
|
594:
|
||
|
595:
|
||
|
596:
|
||
|
597:
|
||
|
598: typedef enum < ulong > tagMEDIATYPE_FAT32
|
||
|
599: {
|
||
|
600: HARD_DISK_FAT32 = 0xFFFFFF8 ,
|
||
|
601: FLOPPY_DISK_FAT32 = 0xFFFFFF0
|
||
|
602: } MEDIATYPE_FAT32 ;
|
||
|
603:
|
||
|
604: typedef enum < ulong > tagPARTITIONSTATE_FAT32
|
||
|
605: {
|
||
|
606: PARTITION_NOT_IN_USE_FAT32 = 0xFFFFFFFF ,
|
||
|
607: PARTITION_IN_USE_FAT32 = 0xFFFFFFF7
|
||
|
608: } PARTITIONSTATE_FAT32 ;
|
||
|
609:
|
||
|
610: typedef enum < ulong > tagCLUSTERINFO_FAT32
|
||
|
611: {
|
||
|
612: FREE_CLUSTER_FAT32 = 0x0 ,
|
||
|
613: RESERVED_0001_FAT32 = 0x1 ,
|
||
|
614: RESERVED_FFF0_FAT32 = 0xFFFFFF0 ,
|
||
|
615: RESERVED_FFF1_FAT32 = 0xFFFFFF1 ,
|
||
|
616: RESERVED_FFF2_FAT32 = 0xFFFFFF2 ,
|
||
|
617: RESERVED_FFF3_FAT32 = 0xFFFFFF3 ,
|
||
|
618: RESERVED_FFF4_FAT32 = 0xFFFFFF4 ,
|
||
|
619: RESERVED_FFF5_FAT32 = 0xFFFFFF5 ,
|
||
|
620: RESERVED_FFF6_FAT32 = 0xFFFFFF6 ,
|
||
|
621: BAD_CLUSTER_FAT32 = 0xFFFFFF7 ,
|
||
|
622: USED_LAST_CLUSTER_FFF8_FAT32 = 0xFFFFFF8 ,
|
||
|
623: USED_LAST_CLUSTER_FFF9_FAT32 = 0xFFFFFF9 ,
|
||
|
624: USED_LAST_CLUSTER_FFFA_FAT32 = 0xFFFFFFA ,
|
||
|
625: USED_LAST_CLUSTER_FFFB_FAT32 = 0xFFFFFFB ,
|
||
|
626: USED_LAST_CLUSTER_FFFC_FAT32 = 0xFFFFFFC ,
|
||
|
627: USED_LAST_CLUSTER_FFFD_FAT32 = 0xFFFFFFD ,
|
||
|
628: USED_LAST_CLUSTER_FFFE_FAT32 = 0xFFFFFFE ,
|
||
|
629: USED_LAST_CLUSTER_FFFF_FAT32 = 0xFFFFFFF
|
||
|
630: } CLUSTERINFO_FAT32 ;
|
||
|
631:
|
||
|
632: void FAT32_FAT_Table ( quad FilePosStartFatTable , quad SizeOfFatTableInSectors , UBYTE NumberOfCopiesOfFats )
|
||
|
633: {
|
||
|
634: local unsigned char SizeOfEach_ClusterEntry_InBytes ;
|
||
|
635: SizeOfEach_ClusterEntry_InBytes = 4 ;
|
||
|
636:
|
||
|
637: FSeek ( FilePosStartFatTable ) ;
|
||
|
638:
|
||
|
639: if ( NumberOfCopiesOfFats == 1 )
|
||
|
640: {
|
||
|
641: MEDIATYPE_FAT32 FAT32_MediaType ;
|
||
|
642: PARTITIONSTATE_FAT32 FAT32_PartitionState ;
|
||
|
643: CLUSTERINFO_FAT32 FAT32_Cluster [ ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) ] ;
|
||
|
644:
|
||
|
645: } else if ( NumberOfCopiesOfFats == 2 )
|
||
|
646: {
|
||
|
647: MEDIATYPE_FAT32 FAT32_MediaType_FAT1 ;
|
||
|
648: PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT1 ;
|
||
|
649: CLUSTERINFO_FAT32 FAT32_Cluster_FAT1 [ ( ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) / NumberOfCopiesOfFats ) - 0 ] ;
|
||
|
650:
|
||
|
651: MEDIATYPE_FAT32 FAT32_MediaType_FAT2 ;
|
||
|
652: PARTITIONSTATE_FAT32 FAT32_PartitionState_FAT2 ;
|
||
|
653: CLUSTERINFO_FAT32 FAT32_Cluster_FAT2 [ ( ( ( ( SizeOfFatTableInSectors * 512 ) / SizeOfEach_ClusterEntry_InBytes ) - SizeOfEach_ClusterEntry_InBytes ) / NumberOfCopiesOfFats ) - 0 ] ;
|
||
|
654: }
|
||
|
655: }
|
||
|
656:
|
||
|
657: void FAT32_Directory_Entry ( quad FilePosStartDirectoryEntry )
|
||
|
658: {
|
||
|
659: FSeek ( FilePosStartDirectoryEntry ) ;
|
||
|
660: i = 0 ;
|
||
|
661: while ( 1 )
|
||
|
662: {
|
||
|
663: if ( ReadByte ( FTell ( ) + 11 ) == 0xF )
|
||
|
664: {
|
||
|
665: LONGENTRY fat32_long_direntry ;
|
||
|
666: } else
|
||
|
667: {
|
||
|
668: SHORTENTRY fat32_short_direntry ;
|
||
|
669: if ( fat32_short_direntry . Name [ 0 ] == 0 && fat32_short_direntry . Name [ 1 ] == 0 )
|
||
|
670: {
|
||
|
671: break ;
|
||
|
672: }
|
||
|
673: }
|
||
|
674: }
|
||
|
675: }
|
||
|
676:
|
||
|
677:
|
||
|
678:
|
||
|
679:
|
||
|
680:
|
||
|
681: struct BOOTSECTOR_NTFS
|
||
|
682: {
|
||
|
683: BYTE jmp [ 3 ] ;
|
||
|
684: CHAR OEMName [ 8 ] ;
|
||
|
685:
|
||
|
686: typedef struct BPB_NTFS
|
||
|
687: {
|
||
|
688: WORD BytesPerSector ;
|
||
|
689: BYTE SectorsPerCluster ;
|
||
|
690: WORD ReservedSectors ;
|
||
|
691: BYTE Zero [ 3 ] ;
|
||
|
692: WORD NotUsed ;
|
||
|
693: BYTE MediaDescriptor ;
|
||
|
694: WORD Zero ;
|
||
|
695: WORD SectorsPerTrack ;
|
||
|
696: WORD HeadsPerCylinder ;
|
||
|
697: DWORD HiddenSectors ;
|
||
|
698: DWORD NotUsed ;
|
||
|
699: DWORD NotUsed ;
|
||
|
700: UQUAD TotalSectors ;
|
||
|
701: UQUAD LogicalClusterMFT ;
|
||
|
702: UQUAD LogicalClusterMFTMiror ;
|
||
|
703: DWORD ClustersPerFileRecSegment ;
|
||
|
704: DWORD ClustersPerIndexBlock ;
|
||
|
705: UQUAD SerialNumber ;
|
||
|
706: DWORD Checksum ;
|
||
|
707: } ;
|
||
|
708:
|
||
|
709: BPB_NTFS bpb_ntfs ;
|
||
|
710: BYTE BootCode [ 426 ] ;
|
||
|
711: WORD EndOfSectorMarker < format = hex > ;
|
||
|
712: } ;
|
||
|
713:
|
||
|
714: typedef union boot
|
||
|
715: {
|
||
|
716: struct MASTER_BOOT_RECORD mbr ;
|
||
|
717: struct BOOTSECTOR_FAT16 boot_fat16 ;
|
||
|
718: struct BOOTSECTOR_FAT32 boot_fat32 ;
|
||
|
719: struct BOOTSECTOR_NTFS boot_ntfs ;
|
||
|
720: } ;
|
||
|
721:
|
||
|
722:
|
||
|
723: void FAT16CheckInit ( SYSTEMID SystemID )
|
||
|
724: {
|
||
|
725: if ( SystemID == FAT_16_INF32MB ||
|
||
|
726: SystemID == FAT_16 ||
|
||
|
727: SystemID == EXT_FAT16_INT13
|
||
|
728: )
|
||
|
729: {
|
||
|
730: CurrentPosSector = FTell ( ) / 512 ;
|
||
|
731:
|
||
|
732: BOOTSECTOR_FAT16 detected_fat16 ;
|
||
|
733:
|
||
|
734: FATTableSector = CurrentPosSector + detected_fat16 . bpb_fat16 . ReservedSectors ;
|
||
|
735:
|
||
|
736: RootDirEntrySector = CurrentPosSector + detected_fat16 . bpb_fat16 . ReservedSectors +
|
||
|
737: ( detected_fat16 . bpb_fat16 . SectorsPerFAT * 2 ) ;
|
||
|
738: RootDirEntryFilePos = RootDirEntrySector * 512 ;
|
||
|
739:
|
||
|
740: FATTableFilePos = FATTableSector * 512 ;
|
||
|
741: FATTableSizeInSectors = RootDirEntrySector - FATTableSector ;
|
||
|
742:
|
||
|
743:
|
||
|
744: FAT16_FAT_Table ( FATTableFilePos , FATTableSizeInSectors , detected_fat16 . bpb_fat16 . NumberOfCopiesOfFats ) ;
|
||
|
745:
|
||
|
746:
|
||
|
747: FAT16_Directory_Entry ( RootDirEntryFilePos ) ;
|
||
|
748:
|
||
|
749: DataAreaSector = CurrentPosSector + detected_fat16 . bpb_fat16 . ReservedSectors +
|
||
|
750: ( detected_fat16 . bpb_fat16 . SectorsPerFAT * 2 ) +
|
||
|
751: ( ( detected_fat16 . bpb_fat16 . MaxRootDirEntries * 32 ) / detected_fat16 . bpb_fat16 . BytesPerSector ) ;
|
||
|
752: DataAreaFilePos = DataAreaSector * 512 ;
|
||
|
753:
|
||
|
754:
|
||
|
755: }
|
||
|
756: }
|
||
|
757:
|
||
|
758: void FAT32CheckInit ( SYSTEMID SystemID )
|
||
|
759: {
|
||
|
760: if ( SystemID == PRI_FAT32_INT13 ||
|
||
|
761: SystemID == EXT_FAT32_INT13
|
||
|
762: )
|
||
|
763: {
|
||
|
764: CurrentPosSector = FTell ( ) / 512 ;
|
||
|
765:
|
||
|
766: struct BOOTSECTOR_FAT32 detected_fat32 ;
|
||
|
767:
|
||
|
768: FATTableSector = CurrentPosSector + detected_fat32 . bpb_fat32 . ReservedSectors ;
|
||
|
769:
|
||
|
770: RootDirEntrySector = CurrentPosSector + detected_fat32 . bpb_fat32 . ReservedSectors +
|
||
|
771: ( detected_fat32 . bpb_fat32 . SectorsPerFAT * 2 ) ;
|
||
|
772: RootDirEntryFilePos = RootDirEntrySector * 512 ;
|
||
|
773:
|
||
|
774: FATTableFilePos = FATTableSector * 512 ;
|
||
|
775: FATTableSizeInSectors = RootDirEntrySector - FATTableSector ;
|
||
|
776:
|
||
|
777:
|
||
|
778: FAT32_FAT_Table ( FATTableFilePos , FATTableSizeInSectors , detected_fat32 . bpb_fat32 . NumberOfFATs ) ;
|
||
|
779:
|
||
|
780:
|
||
|
781: FAT32_Directory_Entry ( RootDirEntryFilePos ) ;
|
||
|
782: }
|
||
|
783: }
|
||
|
784:
|
||
|
785:
|
||
|
786:
|
||
|
787:
|
||
|
788: typedef struct _FATStruct
|
||
|
789: {
|
||
|
790: local unsigned short mbr_boot_ok = 0 ;
|
||
|
791: local quad FATTableSector ;
|
||
|
792: local quad FATTableFilePos ;
|
||
|
793: local quad FATTableSizeInSectors ;
|
||
|
794:
|
||
|
795: local quad RootDirEntrySector ;
|
||
|
796: local quad RootDirEntryFilePos ;
|
||
|
797:
|
||
|
798:
|
||
|
799: if ( ReadUShort ( 510 ) == 0xAA55 )
|
||
|
800: {
|
||
|
801: boot boot_sect ;
|
||
|
802: local unsigned short i ;
|
||
|
803:
|
||
|
804: for ( i = 0 ; i < 4 ; i ++ )
|
||
|
805: {
|
||
|
806: if ( ( boot_sect . mbr . partitions [ i ] . BootIndicator == SYSTEM_PARTITION ||
|
||
|
807: boot_sect . mbr . partitions [ i ] . BootIndicator == NOBOOT ) &&
|
||
|
808: boot_sect . mbr . partitions [ i ] . SystemID != EMPTY
|
||
|
809: )
|
||
|
810: {
|
||
|
811: if ( mbr_boot_ok == 0 )
|
||
|
812: {
|
||
|
813: FSeek ( 0 ) ;
|
||
|
814: MASTER_BOOT_RECORD detected_mbr ;
|
||
|
815: mbr_boot_ok = 1 ;
|
||
|
816: }
|
||
|
817:
|
||
|
818: FSeek ( boot_sect . mbr . partitions [ i ] . RelativeSector * 512 ) ;
|
||
|
819:
|
||
|
820: FAT16CheckInit ( boot_sect . mbr . partitions [ i ] . SystemID ) ;
|
||
|
821: FAT32CheckInit ( boot_sect . mbr . partitions [ i ] . SystemID ) ;
|
||
|
822: }
|
||
|
823: }
|
||
|
824:
|
||
|
825: if ( boot_sect . boot_fat16 . FileSystem == "FAT16 " )
|
||
|
826: {
|
||
|
827: FSeek ( 0 ) ;
|
||
|
828: BOOTSECTOR_FAT16 detected_fat16 ;
|
||
|
829:
|
||
|
830: FATTableSector = 0 + detected_fat16 . bpb_fat16 . ReservedSectors ;
|
||
|
831:
|
||
|
832: RootDirEntrySector = 0 + detected_fat16 . bpb_fat16 . ReservedSectors +
|
||
|
833: ( detected_fat16 . bpb_fat16 . SectorsPerFAT * 2 ) ;
|
||
|
834: RootDirEntryFilePos = RootDirEntrySector * 512 ;
|
||
|
835:
|
||
|
836: FATTableFilePos = FATTableSector * 512 ;
|
||
|
837: FATTableSizeInSectors = RootDirEntrySector - FATTableSector ;
|
||
|
838:
|
||
|
839:
|
||
|
840: FAT16_FAT_Table ( FATTableFilePos , FATTableSizeInSectors , detected_fat16 . bpb_fat16 . NumberOfCopiesOfFats ) ;
|
||
|
841:
|
||
|
842:
|
||
|
843: FAT16_Directory_Entry ( RootDirEntryFilePos ) ;
|
||
|
844:
|
||
|
845: DataAreaSector = 0 + detected_fat16 . bpb_fat16 . ReservedSectors +
|
||
|
846: ( detected_fat16 . bpb_fat16 . SectorsPerFAT * 2 ) +
|
||
|
847: ( ( detected_fat16 . bpb_fat16 . MaxRootDirEntries * 32 ) / detected_fat16 . bpb_fat16 . BytesPerSector ) ;
|
||
|
848: DataAreaFilePos = DataAreaSector * 512 ;
|
||
|
849:
|
||
|
850:
|
||
|
851: }
|
||
|
852:
|
||
|
853: if ( boot_sect . boot_fat32 . FileSystem == "FAT32 " )
|
||
|
854: {
|
||
|
855: FSeek ( 0 ) ;
|
||
|
856: struct BOOTSECTOR_FAT32 detected_fat32 ;
|
||
|
857:
|
||
|
858: FATTableSector = 0 + detected_fat32 . bpb_fat32 . ReservedSectors ;
|
||
|
859:
|
||
|
860: RootDirEntrySector = 0 + detected_fat32 . bpb_fat32 . ReservedSectors +
|
||
|
861: ( detected_fat32 . bpb_fat32 . SectorsPerFAT * 2 ) ;
|
||
|
862: RootDirEntryFilePos = RootDirEntrySector * 512 ;
|
||
|
863:
|
||
|
864: FATTableFilePos = FATTableSector * 512 ;
|
||
|
865: FATTableSizeInSectors = RootDirEntrySector - FATTableSector ;
|
||
|
866:
|
||
|
867:
|
||
|
868: FAT32_FAT_Table ( FATTableFilePos , FATTableSizeInSectors , detected_fat32 . bpb_fat32 . NumberOfFATs ) ;
|
||
|
869:
|
||
|
870:
|
||
|
871: FAT32_Directory_Entry ( RootDirEntryFilePos ) ;
|
||
|
872:
|
||
|
873: }
|
||
|
874:
|
||
|
875:
|
||
|
876:
|
||
|
877: } else
|
||
|
878: {
|
||
|
879:
|
||
|
880:
|
||
|
881:
|
||
|
882:
|
||
|
883: }
|
||
|
884: } MBR_FAT ;
|
||
|
885:
|
||
|
886: MBR_FAT mbr_fat ;
|
||
|
887:
|
||
|
888: tok_eof
|