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
|