summaryrefslogtreecommitdiffstats
path: root/private/utils/ufat/inc/cvfexts.hxx
blob: 7a7bcda9fe0c1fd10a0bdcec820a6211e1aa90c7 (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
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
/*++

Copyright (c) 1990 Microsoft Corporation

Module Name:

    cvfexts.hxx

Abstract:

    A class to manage the CVF_FAT_EXTENSIONS (otherwise known as
    the MDFAT) part of the doublespace volume.

Author:

    Matthew Bradburn (mattbr) 27-Sep-93

--*/

#ifndef CVF_EXTS_DEFN
#define CVF_EXTS_DEFN

//
//    secStart : 21        starting sector number, minus 1
//    Reserved : 1        unused
//    csecCoded : 4        number of compressed sectors required, minus 1
//    csecPlain : 4        number of uncompressed sectors required, minus 1
//    fUncoded : 1        0: data stored compressed    1: data uncompressed
//    fUsed : 1            0: mdfat entry not in use    1: mdfat entry in use
//

#define CFE_START_SHIFT     0
#define CFE_START_MASK      0x001fffff

#define CFE_RESVD_SHIFT     21
#define CFE_RESVD_MASK      0x00200000

#define CFE_CODED_SHIFT     22
#define CFE_CODED_MASK      0x03c00000

#define CFE_PLAIN_SHIFT     26
#define CFE_PLAIN_MASK      0x3c000000

#define CFE_UNCODED_SHIFT   30
#define CFE_UNCODED_MASK    0x40000000

#define CFE_USED_SHIFT      31
#define CFE_USED_MASK       0x80000000


DECLARE_CLASS( CVF_FAT_EXTENS );

class CVF_FAT_EXTENS : public SECRUN {
    public:
        DECLARE_CONSTRUCTOR(CVF_FAT_EXTENS);

        NONVIRTUAL
        ~CVF_FAT_EXTENS();

        NONVIRTUAL
        BOOLEAN
        Initialize(
            IN OUT PMEM Mem,
            IN OUT PLOG_IO_DP_DRIVE Drive,
            IN     LBN StartSetor,
            IN     ULONG NumberOfEntries,
            IN     ULONG FirstEntry
            );

        NONVIRTUAL
        BOOLEAN
        Create(
            );

        NONVIRTUAL
        BOOLEAN
        IsClusterInUse(
            IN         ULONG    Cluster
            ) CONST;

        NONVIRTUAL
        VOID
        SetClusterInUse(
            IN        ULONG     Cluster,
            IN        BOOLEAN   fInUse
            );
    
        NONVIRTUAL
        ULONG
        QuerySectorFromCluster(
            IN        ULONG     Cluster,
            OUT       PUCHAR    NumSectors DEFAULT NULL
            );
    
        NONVIRTUAL
        VOID
        SetSectorForCluster(
            IN        ULONG     Cluster,
            IN        ULONG     Sector,
            IN        UCHAR     SectorCount
            );
    
        NONVIRTUAL
        BOOLEAN
        IsClusterCompressed(
            IN        ULONG     Cluster
            ) CONST;
    
        NONVIRTUAL
        VOID
        SetClusterCompressed(
            IN        ULONG Cluster,
            IN        BOOLEAN   fCompressed
            );
    
        NONVIRTUAL
        UCHAR
        QuerySectorsRequiredForPlainData(
            IN        ULONG     Cluster
            ) CONST;
    
        NONVIRTUAL
        VOID
        SetSectorsRequiredForPlainData(
            IN        ULONG     Cluster,
            IN        UCHAR     SectorsRequired
            );

    private:

        NONVIRTUAL
        VOID
        Construct(
            );

        NONVIRTUAL
        VOID
        Destroy(
            );

        PULONG   _mdfat;
        ULONG    _num_entries;
        ULONG     _first_entry;
};

INLINE BOOLEAN
CVF_FAT_EXTENS::IsClusterInUse(
    IN         ULONG    Cluster
    ) CONST
{
    ULONG CfeEntry = _mdfat[Cluster];

    return BOOLEAN((CfeEntry & CFE_USED_MASK) >> CFE_USED_SHIFT);
}

INLINE VOID
CVF_FAT_EXTENS::SetClusterInUse(
    IN        ULONG    Cluster,
    IN        BOOLEAN    fInUse
    )
{
    ULONG CfeEntry = _mdfat[Cluster];

    CfeEntry &= ~CFE_USED_MASK;
    CfeEntry |= fInUse << CFE_USED_SHIFT;

    _mdfat[Cluster] = CfeEntry;
}

INLINE ULONG
CVF_FAT_EXTENS::QuerySectorFromCluster(
    IN        ULONG    Cluster,
    OUT       PUCHAR    NumSectors
    )
/*++

Routine Description:

    This routine takes a cluster number and uses the mdfat to return
    the sector number in which the data starts.  Also the number of
    sectors used to store the cluster data is returned.  Works for
    compressed and uncompressed sectors as well, and for clusters
    whether they're "In Use" or not.  The number returned is the
    value from the CVF_FAT_EXTENSIONS plus 1.

Arguments:

    Cluster - the cluster to get info for.

Return Value:

    ULONG - the CVF starting sector number.

--*/
{
    ULONG CfeEntry = _mdfat[Cluster];

    if (NULL != NumSectors) {
        *NumSectors = (UCHAR)((CfeEntry & CFE_CODED_MASK) >> CFE_CODED_SHIFT) + 1;
    }

    return ((CfeEntry & CFE_START_MASK) >> CFE_START_SHIFT) + 1;
}

INLINE VOID
CVF_FAT_EXTENS::SetSectorForCluster(
    IN        ULONG    Cluster,
    IN        ULONG    Sector,
    IN        UCHAR    SectorCount
    )
/*++

Routine Description:

    This routine sets the cluster->sector mapping, as well as
    the number of sectors required to store the compressed cluster.

Arguments:

    Cluster - cluster number
    Sector - starting CVF sector number
    SectorCount - number of sectors required

Return Value:

    None.

--*/
{
    ULONG CfeEntry = _mdfat[Cluster];

    DbgAssert(Sector > 0);
    DbgAssert(SectorCount > 0);

    CfeEntry &= ~CFE_START_MASK;
    CfeEntry |= (Sector - 1) << CFE_START_SHIFT;

    CfeEntry &= ~CFE_CODED_MASK;
    CfeEntry |= ((ULONG)(SectorCount - 1) << CFE_CODED_SHIFT);

    _mdfat[Cluster] = CfeEntry;
}

INLINE UCHAR
CVF_FAT_EXTENS::QuerySectorsRequiredForPlainData(
    IN        ULONG    Cluster
    ) CONST
{
    ULONG CfeEntry = _mdfat[Cluster];

    return (UCHAR)((CfeEntry & CFE_PLAIN_MASK) >> CFE_PLAIN_SHIFT) + 1;
}

INLINE VOID
CVF_FAT_EXTENS::SetSectorsRequiredForPlainData(
    IN        ULONG    Cluster,
    IN        UCHAR    SectorsRequired
    )
{
    ULONG CfeEntry = _mdfat[Cluster];

    DbgAssert(SectorsRequired > 0);

    CfeEntry &= ~CFE_PLAIN_MASK;
    CfeEntry |= (ULONG)(SectorsRequired - 1) << CFE_PLAIN_SHIFT;

    _mdfat[Cluster] = CfeEntry;
}

INLINE BOOLEAN
CVF_FAT_EXTENS::IsClusterCompressed(
    IN        ULONG    Cluster
    ) CONST
{
    ULONG CfeEntry = _mdfat[Cluster];

    return ! ((CfeEntry & CFE_UNCODED_MASK) >> CFE_UNCODED_SHIFT);
}

INLINE VOID
CVF_FAT_EXTENS::SetClusterCompressed(
    IN        ULONG    Cluster,
    IN        BOOLEAN  fCompressed
    )
{
    ULONG CfeEntry = _mdfat[Cluster];

    CfeEntry &= ~CFE_UNCODED_MASK;
    CfeEntry |= (ULONG)!fCompressed << CFE_UNCODED_SHIFT;

    _mdfat[Cluster] = CfeEntry;
}

#endif // CVF_EXTS_DEFN