summaryrefslogtreecommitdiffstats
path: root/private/utils/ufat/inc/cvf.hxx
blob: e105beff8d0f2b190e7221db817bef6649faa08b (plain) (blame)
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
/*++

Copyright (c) 1991  Microsoft Corporation

Module Name:

    cvf.hxx

Abstract:

    This module contains basic declarations and definitions for
    the double-space file system format.  Note that more extensive
    description of the file system structures may be found in
    ntos\fastfat\cvf.h

Author:

    Bill McJohn     [BillMc]        24-September-1993

Revision History:



--*/

#if !defined( _UFATDB_DEFN_ )
#define _UFATDB_DEFN_

#include "bpb.hxx"

// Manifest constants for fixed values on a Double Space drive:
//
CONST DoubleSpaceBytesPerSector = 512;
CONST DoubleSpaceLog2BytesPerSector = 9;
CONST DoubleSpaceSectorsPerCluster = 16;
CONST DoubleSpaceLog2SectorsPerCluster = 4;
CONST DoubleSpaceReservedSectors = 16;
CONST DoubleSpaceFats = 1;
CONST DoubleSpaceSectorsInRootDir = 32;
CONST DoubleSpaceRootEntries = 512;
CONST DoubleSpaceMediaByte = 0xf8;
CONST DoubleSpaceSectorsPerTrack = 0x11;
CONST DoubleSpaceHeads = 6;
CONST DoubleSpaceHiddenSectors = 0;
CONST DoubleSpaceReservedSectors2 = 31;
CONST DSBytesPerBitmapPage = 2048;
CONST DSSectorsPerBitmapPage = 4;

CONST ULONG EIGHT_MEG = 8 * 1024L * 1024L;

CONST DbSignatureLength = 4;
CONST UCHAR FirstDbSignature[DbSignatureLength] = { (UCHAR)0xf8, 'D', 'R', 0 };
CONST UCHAR SecondDbSignature[DbSignatureLength] = "MDR";

INLINE
ULONG
ComputeMaximumCapacity(
    IN ULONG HostDriveSize
    )
/*++

Routine Description:

    This function computes the maximum capacity for a compressed
    volume file on a host volume of a given size.

Arguments:

    HostDriveSize   --  Supplies the size in bytes of the host drive.

Return Value:

    The appropriate Maximum Capacity.

--*/
{
    ULONG MaxCap;

    if( HostDriveSize < 20 * 1024L * 1024L ) {

        MaxCap = 16 * HostDriveSize;

    } else if ( HostDriveSize < 64 * 1024L * 1024L ) {

        MaxCap = 8 * HostDriveSize;

    } else {

        MaxCap = 4 * HostDriveSize;
    }

    if( MaxCap < 4 * 1024L * 1024L ) {

        MaxCap = 4 * 1024L * 1024L;

    } else if( MaxCap > 512 * 1024L * 1024L ) {

        MaxCap = 512 * 1024L * 1024L;
    }

    return MaxCap;
}

typedef struct _PACKED_CVF_HEADER {

    //
    //  First a typical start of a boot sector
    //

    UCHAR Jump[1];                                  // offset = 0x000   0
    UCHAR JmpOffset[2];
    UCHAR Oem[8];                                   // offset = 0x003   3
    PACKED_BIOS_PARAMETER_BLOCK PackedBpb;          // offset = 0x00B  11

    //
    //  Now the DblSpace extensions
    //

    UCHAR CvfFatExtensionsLbnMinus1[2];             // offset = 0x024  36
    UCHAR LogOfBytesPerSector[1];                   // offset = 0x026  38
    UCHAR DosBootSectorLbn[2];                      // offset = 0x027  39
    UCHAR DosRootDirectoryOffset[2];                // offset = 0x029  41
    UCHAR CvfHeapOffset[2];                         // offset = 0x02B  43
    UCHAR CvfFatFirstDataEntry[2];                  // offset = 0x02D  45
    UCHAR CvfBitmap2KSize[1];                       // offset = 0x02F  47
    UCHAR Reserved1[2];                             // offset = 0x030  48
    UCHAR LogOfSectorsPerCluster[1];                // offset = 0x032  50
    UCHAR Reserved2[2];                             // offset = 0x033
    UCHAR MinFile[4];                               // offset = 0x035
    UCHAR Reserved3[4];                             // offset = 0x039
    UCHAR Is12BitFat[1];                            // offset = 0x03D  61
    UCHAR CvfMaximumCapacity[2];                    // offset = 0x03E  62
    UCHAR StartBootCode;

} PACKED_CVF_HEADER;                                // sizeof = 0x040  64
typedef PACKED_CVF_HEADER *PPACKED_CVF_HEADER;

//
//  For the unpacked version we'll only define the necessary field and skip
//  the jump and oem fields.
//

typedef struct _CVF_HEADER {

    UCHAR Jump;
    USHORT JmpOffset;
 
    UCHAR Oem[8];
    BIOS_PARAMETER_BLOCK Bpb;

    USHORT CvfFatExtensionsLbnMinus1;
    UCHAR  LogOfBytesPerSector;
    USHORT DosBootSectorLbn;
    USHORT DosRootDirectoryOffset;
    USHORT CvfHeapOffset;
    USHORT CvfFatFirstDataEntry;
    UCHAR  CvfBitmap2KSize;
    UCHAR  LogOfSectorsPerCluster;
    UCHAR  Is12BitFat;
    ULONG  MinFile;
    USHORT CvfMaximumCapacity;

} CVF_HEADER;
typedef CVF_HEADER *PCVF_HEADER;

//
//  Here is NT's typical routine/macro to unpack the cvf header because DOS
//  doesn't bother to naturally align anything.
//
//      VOID
//      CvfUnpackCvfHeader (
//          IN OUT PCVF_HEADER UnpackedHeader,
//          IN PPACKED_CVF_HEADER PackedHeader
//          );
//

#define CvfUnpackCvfHeader(UH,PH) {                                                      \
                                                                                         \
    memcpy( &(UH)->Jump,        &(PH)->Jump,        1 );                                 \
    memcpy( &(UH)->JmpOffset,   &(PH)->JmpOffset,   2 );                                 \
    memcpy( &(UH)->Oem,     &(PH)->Oem,     8 );                                         \
    UnpackBios( &(UH)->Bpb, &(PH)->PackedBpb );                                          \
    CopyUchar2( &(UH)->CvfFatExtensionsLbnMinus1, &(PH)->CvfFatExtensionsLbnMinus1[0] ); \
    CopyUchar1( &(UH)->LogOfBytesPerSector,       &(PH)->LogOfBytesPerSector[0]       ); \
    CopyUchar2( &(UH)->DosBootSectorLbn,          &(PH)->DosBootSectorLbn[0]          ); \
    CopyUchar2( &(UH)->DosRootDirectoryOffset,    &(PH)->DosRootDirectoryOffset[0]    ); \
    CopyUchar2( &(UH)->CvfHeapOffset,             &(PH)->CvfHeapOffset[0]             ); \
    CopyUchar2( &(UH)->CvfFatFirstDataEntry,      &(PH)->CvfFatFirstDataEntry[0]      ); \
    CopyUchar1( &(UH)->CvfBitmap2KSize,           &(PH)->CvfBitmap2KSize[0]           ); \
    CopyUchar1( &(UH)->LogOfSectorsPerCluster,    &(PH)->LogOfSectorsPerCluster[0]    ); \
    CopyUchar1( &(UH)->Is12BitFat,                &(PH)->Is12BitFat[0]                ); \
    CopyUchar4( &(UH)->MinFile,                   &(PH)->MinFile[0]                   ); \
    CopyUchar2( &(UH)->CvfMaximumCapacity,        &(PH)->CvfMaximumCapacity[0]        ); \
}


#define CvfPackCvfHeader(PH,UH) {                                                    \
                                                                                     \
    memcpy( &(PH)->Jump,        &(UH)->Jump,        1 );                             \
    memcpy( &(PH)->JmpOffset,   &(UH)->JmpOffset,   2 );                             \
    memcpy( &(PH)->Oem,     &(UH)->Oem,     8 );                                     \
    PackBios( &(UH)->Bpb,   &(PH)->PackedBpb,  );                                    \
    CopyUchar2( (PH)->CvfFatExtensionsLbnMinus1, &(UH)->CvfFatExtensionsLbnMinus1 ); \
    CopyUchar1( (PH)->LogOfBytesPerSector,       &(UH)->LogOfBytesPerSector       ); \
    CopyUchar2( (PH)->DosBootSectorLbn,          &(UH)->DosBootSectorLbn          ); \
    CopyUchar2( (PH)->DosRootDirectoryOffset,    &(UH)->DosRootDirectoryOffset    ); \
    CopyUchar2( (PH)->CvfHeapOffset,             &(UH)->CvfHeapOffset             ); \
    CopyUchar2( (PH)->CvfFatFirstDataEntry,      &(UH)->CvfFatFirstDataEntry      ); \
    CopyUchar1( (PH)->CvfBitmap2KSize,           &(UH)->CvfBitmap2KSize           ); \
    CopyUchar1( (PH)->LogOfSectorsPerCluster,    &(UH)->LogOfSectorsPerCluster    ); \
    CopyUchar1( (PH)->Is12BitFat,                &(UH)->Is12BitFat                ); \
    CopyUchar4( (PH)->MinFile,                   &(UH)->MinFile                   ); \
    CopyUchar2( (PH)->CvfMaximumCapacity,        &(UH)->CvfMaximumCapacity        ); \
    memset( (PH)->Reserved1, 0,  2 );                                                \
    memset( (PH)->Reserved2, 0,  2 );                                                \
    memset( (PH)->Reserved3, 0,  4 );                                                \
}


//
//  The CVF FAT EXTENSIONS is a table is ULONG entries.  Each entry corresponds
//  to a FAT cluster.  The entries describe where in the CVF_HEAP to locate
//  the data for the cluster.  It indicates if the data is compressed and the
//  length of the compressed and uncompressed form.
//

typedef struct _CVF_FAT_EXTENSIONS {

    ULONG CvfHeapLbnMinus1               : 21;
    ULONG Reserved                       :  1;
    ULONG CompressedSectorLengthMinus1   :  4;
    ULONG UncompressedSectorLengthMinus1 :  4;
    ULONG IsDataUncompressed             :  1;
    ULONG IsEntryInUse                   :  1;

} CVF_FAT_EXTENSIONS;
typedef CVF_FAT_EXTENSIONS *PCVF_FAT_EXTENSIONS;


//
//  Some sizes are fixed so we'll declare them as manifest constants
//
#define CVF_MINIMUM_DISK_SIZE            (512 * 1024L)
#define CVF_FATFAILSAFE                  (1024L)
#define CVF_MIN_HEAP_SECTORS             (60)
#define CVF_RESERVED_AREA_1_SECTOR_SIZE  (1)
#define CVF_RESERVED_AREA_2_SECTOR_SIZE  (31)
#define CVF_RESERVED_AREA_4_SECTOR_SIZE  (2)


#endif // _UFATDB_DEFN_