1 /*++
2 
3 Copyright (c) 1989-2000 Microsoft Corporation
4 
5 Module Name:
6 
7     DumpSup.c
8 
9 Abstract:
10 
11     This module implements a collection of data structure dump routines
12     for debugging the Fat file system
13 
14 
15 --*/
16 
17 #include "fatprocs.h"
18 
19 #ifdef FASTFATDBG
20 
21 VOID FatDump(IN PVOID Ptr);
22 
23 VOID FatDumpDataHeader();
24 VOID FatDumpVcb(IN PVCB Ptr);
25 VOID FatDumpFcb(IN PFCB Ptr);
26 VOID FatDumpCcb(IN PCCB Ptr);
27 
28 ULONG FatDumpCurrentColumn;
29 
30 #define DumpNewLine() {       \
31     DbgPrint("\n");            \
32     FatDumpCurrentColumn = 1; \
33 }
34 
35 #define DumpLabel(Label,Width) {                                          \
36     size_t i, LastPeriod=0;                                                \
37     CHAR _Str[20];                                                        \
38     for(i=0;i<2;i++) { _Str[i] = UCHAR_SP;}                               \
39     for(i=0;i<strlen(#Label);i++) {if (#Label[i] == '.') LastPeriod = i;} \
40     strncpy(&_Str[2],&#Label[LastPeriod],Width);                          \
41     for(i=strlen(_Str);i<Width;i++) {_Str[i] = UCHAR_SP;}                 \
42     _Str[Width] = '\0';                                                   \
43     DbgPrint("%s", _Str);                                                  \
44 }
45 
46 #define DumpField(Field) {                                         \
47     if ((FatDumpCurrentColumn + 18 + 9 + 9) > 80) {DumpNewLine();} \
48     FatDumpCurrentColumn += 18 + 9 + 9;                            \
49     DumpLabel(Field,18);                                           \
50     DbgPrint(":%p", Ptr->Field);                                  \
51     DbgPrint("         ");                                          \
52 }
53 
54 #define DumpListEntry(Links) {                                     \
55     if ((FatDumpCurrentColumn + 18 + 9 + 9) > 80) {DumpNewLine();} \
56     FatDumpCurrentColumn += 18 + 9 + 9;                            \
57     DumpLabel(Links,18);                                           \
58     DbgPrint(":%p", Ptr->Links.Flink);                            \
59     DbgPrint(":%p", Ptr->Links.Blink);                            \
60 }
61 
62 #define DumpName(Field,Width) {                                    \
63     ULONG i;                                                       \
64     CHAR _String[256];                                             \
65     if ((FatDumpCurrentColumn + 18 + Width) > 80) {DumpNewLine();} \
66     FatDumpCurrentColumn += 18 + Width;                            \
67     DumpLabel(Field,18);                                           \
68     for(i=0;i<Width;i++) {_String[i] = (CHAR)Ptr->Field[i];}             \
69     _String[Width] = '\0';                                         \
70     DbgPrint("%s", _String);                                        \
71 }
72 
73 #define TestForNull(Name) {                                 \
74     if (Ptr == NULL) {                                      \
75         DbgPrint("%s - Cannot dump a NULL pointer\n", Name); \
76         return;                                             \
77     }                                                       \
78 }
79 
80 
81 VOID
82 FatDump (
83     IN PVOID Ptr
84     )
85 
86 /*++
87 
88 Routine Description:
89 
90     This routine determines the type of internal record reference by ptr and
91     calls the appropriate dump routine.
92 
93 Arguments:
94 
95     Ptr - Supplies the pointer to the record to be dumped
96 
97 Return Value:
98 
99     None
100 
101 --*/
102 
103 {
104     TestForNull("FatDump");
105 
106     switch (NodeType(Ptr)) {
107 
108     case FAT_NTC_DATA_HEADER:
109 
110         FatDumpDataHeader();
111         break;
112 
113     case FAT_NTC_VCB:
114 
115         FatDumpVcb(Ptr);
116         break;
117 
118     case FAT_NTC_FCB:
119     case FAT_NTC_DCB:
120     case FAT_NTC_ROOT_DCB:
121 
122         FatDumpFcb(Ptr);
123         break;
124 
125     case FAT_NTC_CCB:
126 
127         FatDumpCcb(Ptr);
128         break;
129 
130     default :
131 
132         DbgPrint("FatDump - Unknown Node type code %p\n", *((PNODE_TYPE_CODE)(Ptr)));
133         break;
134     }
135 
136     return;
137 }
138 
139 
140 VOID
141 FatDumpDataHeader (
142     )
143 
144 /*++
145 
146 Routine Description:
147 
148     Dump the top data structures and all Device structures
149 
150 Arguments:
151 
152     None
153 
154 Return Value:
155 
156     None
157 
158 --*/
159 
160 {
161     PFAT_DATA Ptr;
162     PLIST_ENTRY Links;
163 
164     Ptr = &FatData;
165 
166     TestForNull("FatDumpDataHeader");
167 
168     DumpNewLine();
169     DbgPrint("FatData@ %lx", (Ptr));
170     DumpNewLine();
171 
172     DumpField           (NodeTypeCode);
173     DumpField           (NodeByteSize);
174     DumpListEntry       (VcbQueue);
175     DumpField           (DriverObject);
176     DumpField           (OurProcess);
177     DumpNewLine();
178 
179     for (Links = Ptr->VcbQueue.Flink;
180          Links != &Ptr->VcbQueue;
181          Links = Links->Flink) {
182 
183         FatDumpVcb(CONTAINING_RECORD(Links, VCB, VcbLinks));
184     }
185 
186     return;
187 }
188 
189 
190 VOID
191 FatDumpVcb (
192     IN PVCB Ptr
193     )
194 
195 /*++
196 
197 Routine Description:
198 
199     Dump an Device structure, its Fcb queue amd direct access queue.
200 
201 Arguments:
202 
203     Ptr - Supplies the Device record to be dumped
204 
205 Return Value:
206 
207     None
208 
209 --*/
210 
211 {
212     TestForNull("FatDumpVcb");
213 
214     DumpNewLine();
215     DbgPrint("Vcb@ %lx", (Ptr));
216     DumpNewLine();
217 
218     DumpField           (VolumeFileHeader.NodeTypeCode);
219     DumpField           (VolumeFileHeader.NodeByteSize);
220     DumpListEntry       (VcbLinks);
221     DumpField           (TargetDeviceObject);
222     DumpField           (Vpb);
223     DumpField           (VcbState);
224     DumpField           (VcbCondition);
225     DumpField           (RootDcb);
226     DumpField           (DirectAccessOpenCount);
227     DumpField           (OpenFileCount);
228     DumpField           (ReadOnlyCount);
229     DumpField           (AllocationSupport);
230     DumpField           (AllocationSupport.RootDirectoryLbo);
231     DumpField           (AllocationSupport.RootDirectorySize);
232     DumpField           (AllocationSupport.FileAreaLbo);
233     DumpField           (AllocationSupport.NumberOfClusters);
234     DumpField           (AllocationSupport.NumberOfFreeClusters);
235     DumpField           (AllocationSupport.FatIndexBitSize);
236     DumpField           (AllocationSupport.LogOfBytesPerSector);
237     DumpField           (AllocationSupport.LogOfBytesPerCluster);
238     DumpField           (DirtyFatMcb);
239     DumpField           (FreeClusterBitMap);
240     DumpField           (VirtualVolumeFile);
241     DumpField           (SectionObjectPointers.DataSectionObject);
242     DumpField           (SectionObjectPointers.SharedCacheMap);
243     DumpField           (SectionObjectPointers.ImageSectionObject);
244     DumpField           (ClusterHint);
245     DumpNewLine();
246 
247     FatDumpFcb(Ptr->RootDcb);
248 
249     return;
250 }
251 
252 
253 VOID
254 FatDumpFcb (
255     IN PFCB Ptr
256     )
257 
258 /*++
259 
260 Routine Description:
261 
262     Dump an Fcb structure, its various queues
263 
264 Arguments:
265 
266     Ptr - Supplies the Fcb record to be dumped
267 
268 Return Value:
269 
270     None
271 
272 --*/
273 
274 {
275     PLIST_ENTRY Links;
276 
277     TestForNull("FatDumpFcb");
278 
279     DumpNewLine();
280     if      (NodeType(&Ptr->Header) == FAT_NTC_FCB)      {DbgPrint("Fcb@ %lx", (Ptr));}
281     else if (NodeType(&Ptr->Header) == FAT_NTC_DCB)      {DbgPrint("Dcb@ %lx", (Ptr));}
282     else if (NodeType(&Ptr->Header) == FAT_NTC_ROOT_DCB) {DbgPrint("RootDcb@ %lx", (Ptr));}
283     else {DbgPrint("NonFcb NodeType @ %lx", (Ptr));}
284     DumpNewLine();
285 
286     DumpField           (Header.NodeTypeCode);
287     DumpField           (Header.NodeByteSize);
288     DumpListEntry       (ParentDcbLinks);
289     DumpField           (ParentDcb);
290     DumpField           (Vcb);
291     DumpField           (FcbState);
292     DumpField           (FcbCondition);
293     DumpField           (UncleanCount);
294     DumpField           (OpenCount);
295     DumpField           (DirentOffsetWithinDirectory);
296     DumpField           (DirentFatFlags);
297     DumpField           (FullFileName.Length);
298     DumpField           (FullFileName.Buffer);
299     DumpName            (FullFileName.Buffer, 32);
300     DumpField           (ShortName.Name.Oem.Length);
301     DumpField           (ShortName.Name.Oem.Buffer);
302     DumpField           (NonPaged);
303     DumpField           (Header.AllocationSize.LowPart);
304     DumpField           (NonPaged->SectionObjectPointers.DataSectionObject);
305     DumpField           (NonPaged->SectionObjectPointers.SharedCacheMap);
306     DumpField           (NonPaged->SectionObjectPointers.ImageSectionObject);
307 
308     if ((Ptr->Header.NodeTypeCode == FAT_NTC_DCB) ||
309         (Ptr->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) {
310 
311         DumpListEntry   (Specific.Dcb.ParentDcbQueue);
312         DumpField       (Specific.Dcb.DirectoryFileOpenCount);
313         DumpField       (Specific.Dcb.DirectoryFile);
314 
315     } else if (Ptr->Header.NodeTypeCode == FAT_NTC_FCB) {
316 
317         DumpField       (Header.FileSize.LowPart);
318 
319     } else {
320 
321         DumpNewLine();
322         DbgPrint("Illegal Node type code");
323 
324     }
325     DumpNewLine();
326 
327     if ((Ptr->Header.NodeTypeCode == FAT_NTC_DCB) ||
328         (Ptr->Header.NodeTypeCode == FAT_NTC_ROOT_DCB)) {
329 
330         for (Links = Ptr->Specific.Dcb.ParentDcbQueue.Flink;
331              Links != &Ptr->Specific.Dcb.ParentDcbQueue;
332              Links = Links->Flink) {
333 
334             FatDumpFcb(CONTAINING_RECORD(Links, FCB, ParentDcbLinks));
335         }
336     }
337 
338     return;
339 }
340 
341 
342 VOID
343 FatDumpCcb (
344     IN PCCB Ptr
345     )
346 
347 /*++
348 
349 Routine Description:
350 
351     Dump a Ccb structure
352 
353 Arguments:
354 
355     Ptr - Supplies the Ccb record to be dumped
356 
357 Return Value:
358 
359     None
360 
361 --*/
362 
363 {
364     TestForNull("FatDumpCcb");
365 
366     DumpNewLine();
367     DbgPrint("Ccb@ %lx", (Ptr));
368     DumpNewLine();
369 
370     DumpField           (NodeTypeCode);
371     DumpField           (NodeByteSize);
372     DumpField           (UnicodeQueryTemplate.Length);
373     DumpName            (UnicodeQueryTemplate.Buffer, 32);
374     DumpField           (OffsetToStartSearchFrom);
375     DumpNewLine();
376 
377     return;
378 }
379 
380 #endif // FASTFATDBG
381 
382