Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

hivechek.c File Reference

#include "cmp.h"

Go to the source code of this file.

Functions

ULONG HvCheckHive (PHHIVE Hive, PULONG Storage OPTIONAL)
ULONG HvCheckBin (PHHIVE Hive, PHBIN Bin, PULONG Storage)

Variables

struct {
   PHHIVE   Hive
   ULONG   Status
   ULONG   Space
   HCELL_INDEX   MapPoint
   PHBIN   BinPoint
HvCheckHiveDebug
struct {
   PHBIN   Bin
   ULONG   Status
   PHCELL   CellPoint
HvCheckBinDebug


Function Documentation

ULONG HvCheckBin PHHIVE  Hive,
PHBIN  Bin,
PULONG  Storage
 

Definition at line 175 of file hivechek.c.

References Bin, HBIN_NIL, Hive, HvCheckBinDebug, L, _HBIN::Size, and USE_OLD_CELL.

Referenced by HvCheckHive().

00182 : 00183 00184 Step through all of the cells in the bin. Make sure that 00185 they are consistent with each other, and with the bin header. 00186 00187 Arguments: 00188 00189 Hive - pointer to the hive control structure 00190 00191 Bin - pointer to bin to check 00192 00193 Storage - pointer to a ulong to get allocated user data size 00194 00195 Return Value: 00196 00197 0 if Bin is OK. Number of test in procedure that failed if not. 00198 00199 RANGE: 1 - 1999 00200 00201 --*/ 00202 { 00203 PHCELL p; 00204 PHCELL np; 00205 PHCELL lp; 00206 ULONG freespace = 0L; 00207 ULONG allocated = 0L; 00208 ULONG userallocated = 0L; 00209 00210 HvCheckBinDebug.Bin = Bin; 00211 HvCheckBinDebug.Status = 0; 00212 HvCheckBinDebug.CellPoint = 0; 00213 00214 // 00215 // Scan all the cells in the bin, total free and allocated, check 00216 // for impossible pointers. 00217 // 00218 p = (PHCELL)((PUCHAR)Bin + sizeof(HBIN)); 00219 lp = p; 00220 00221 // DRAGOS: 00222 // The way allocated and freespace are computed implies the following invariants: 00223 // 1. allocated + freespace = p + p->Size - (Bin + sizeof(HBIN)). This is because p->Size is added either to allocated or to freespace. 00224 // So, assuming that allocated > Bin->Size , then 00225 // ==> p + p->Size - (Bin + sizeof(HBIN)) > Bin->Size. 00226 // ==> p + p->Size > Bin + Bin->Size + sizeof(HBIN) 00227 // ==> p + p->Size > Bin + Bin->Size 00228 // This proves that the test "NeverFail 1" (see bellow) will never fail, because when something is wrong, the test above it (namely "Fail 1") will fail 00229 // and the function will exit. 00230 // 00231 // The same logic applies to the test "NeverFail 2", so it can be removed also. 00232 // 00233 // 2. The new value of p is always calculated as p = p + p->Size. By the time this is done, the new value of p (ie. p + p->Size) is already checked against 00234 // Bin + Bin->Size (see tests "Fail 1" and "Fail 2"). So, if p > Bin + Bin->Size, either "Fail 1" or "Fail 2" will fail before asigning the new bogus value 00235 // to p. Therefore, the only possible path to exit the while loop (except a return 20 or return 40), is when p == Bin + Bin->Size. 00236 // ==> test "NeverFail 3" can be removed as it will never fail ! 00237 // 00238 // 3. Considering 1 (where p + p->Size became p) 00239 // ==> allocated + freespace = p - (Bin + sizeof(HBIN)) 00240 // But, Considering 2 (above), when the while loop exits, p = Bin + Bin->Size 00241 // ==> allocated + freespace = Bin + Bin->Size - (Bin + sizeof(HBIN)) 00242 // ==> allocated + freespace + sizeof(HBIN) = Bin->Size 00243 // This proves that test "NeverFail 4" (see bellow) will never fail as the expresion tested is always true (if the flow of execution reaches the test point). 00244 // 00245 00246 while (p < (PHCELL)((PUCHAR)Bin + Bin->Size)) { 00247 00248 // 00249 // Check last pointer 00250 // 00251 if (USE_OLD_CELL(Hive)) { 00252 if (lp == p) { 00253 if (p->u.OldCell.Last != HBIN_NIL) { 00254 KdPrint(("HvCheckBin 20: First cell has wrong last pointer\n")); 00255 KdPrint(("Bin = %08lx\n", Bin)); 00256 HvCheckBinDebug.Status = 20; 00257 HvCheckBinDebug.CellPoint = p; 00258 return 20; 00259 } 00260 } else { 00261 if ((PHCELL)(p->u.OldCell.Last + (PUCHAR)Bin) != lp) { 00262 KdPrint(("HvCheckBin 30: incorrect last pointer\n")); 00263 KdPrint(("Bin = %08lx\n", Bin)); 00264 KdPrint(("p = %08lx\n", (ULONG_PTR)p)); 00265 HvCheckBinDebug.Status = 30; 00266 HvCheckBinDebug.CellPoint = p; 00267 return 30; 00268 } 00269 } 00270 } 00271 00272 00273 // 00274 // Check size 00275 // 00276 if (p->Size < 0) { 00277 00278 // 00279 // allocated cell 00280 // 00281 00282 // DRAGOS: Fail 1 00283 // This test will alway fail prior to the failure of the bellow test 00284 // 00285 if ( ((ULONG)(p->Size * -1) > Bin->Size) || 00286 ( (PHCELL)((p->Size * -1) + (PUCHAR)p) > 00287 (PHCELL)((PUCHAR)Bin + Bin->Size) ) 00288 ) 00289 { 00290 KdPrint(("HvCheckBin 40: impossible allocation\n")); 00291 KdPrint(("Bin = %08lx\n", Bin)); 00292 HvCheckBinDebug.Status = 40; 00293 HvCheckBinDebug.CellPoint = p; 00294 return 40; 00295 } 00296 00297 allocated += (p->Size * -1); 00298 if (USE_OLD_CELL(Hive)) { 00299 userallocated += (p->Size * -1) - FIELD_OFFSET(HCELL, u.OldCell.u.UserData); 00300 } else { 00301 userallocated += (p->Size * -1) - FIELD_OFFSET(HCELL, u.NewCell.u.UserData); 00302 } 00303 00304 // 00305 // DRAGOS: NeverFail 1 00306 // This test will never fail. If a size is wrong the above test (Fail 1)will fail. We can remove this test (it's useless). 00307 // 00308 if (allocated > Bin->Size) { 00309 KdPrint(("HvCheckBin 50: allocated exceeds available\n")); 00310 KdPrint(("Bin = %08lx\n", Bin)); 00311 HvCheckBinDebug.Status = 50; 00312 HvCheckBinDebug.CellPoint = p; 00313 return 50; 00314 } 00315 00316 np = (PHCELL)((PUCHAR)p + (p->Size * -1)); 00317 00318 00319 00320 } else { 00321 00322 // 00323 // free cell 00324 // 00325 00326 // DRAGOS: Fail 2 00327 // This test will alway fail prior to the failure of the bellow test 00328 // 00329 if ( ((ULONG)p->Size > Bin->Size) || 00330 ( (PHCELL)(p->Size + (PUCHAR)p) > 00331 (PHCELL)((PUCHAR)Bin + Bin->Size) ) || 00332 (p->Size == 0) ) 00333 { 00334 KdPrint(("HvCheckBin 60: impossible free block\n")); 00335 KdPrint(("Bin = %08lx\n", Bin)); 00336 HvCheckBinDebug.Status = 60; 00337 HvCheckBinDebug.CellPoint = p; 00338 return 60; 00339 } 00340 00341 freespace = freespace + p->Size; 00342 00343 // 00344 // DRAGOS: NeverFail 2 00345 // This test will never fail. If a size is wrong the above test (Fail 2) will fail. We can remove this test (it's useless). 00346 // 00347 if (freespace > Bin->Size) { 00348 KdPrint(("HvCheckBin 70: free exceeds available\n")); 00349 KdPrint(("Bin = %08lx\n", Bin)); 00350 HvCheckBinDebug.Status = 70; 00351 HvCheckBinDebug.CellPoint = p; 00352 return 70; 00353 } 00354 00355 np = (PHCELL)((PUCHAR)p + p->Size); 00356 00357 } 00358 00359 lp = p; 00360 p = np; 00361 } 00362 00363 // DRAGOS: NeverFail 4 00364 // This test never fails. If the while loop exits, the condition tested here is always true!!! 00365 // We can remove this test (it's useless) 00366 // 00367 if ((freespace + allocated + sizeof(HBIN)) != Bin->Size) { 00368 KdPrint(("HvCheckBin 995: sizes do not add up\n")); 00369 KdPrint(("Bin = %08lx\n", Bin)); 00370 KdPrint(("freespace = %08lx ", freespace)); 00371 KdPrint(("allocated = %08lx ", allocated)); 00372 KdPrint(("size = %08lx\n", Bin->Size)); 00373 HvCheckBinDebug.Status = 995; 00374 return 995; 00375 } 00376 00377 // DRAGOS: NeverFail 3 00378 // This test never fails. The only way out of the while loop is when p == Bin + Bin->Size !!!!!!! 00379 // We can remove this test (it's useless) 00380 // 00381 if (p != (PHCELL)((PUCHAR)Bin + Bin->Size)) { 00382 KdPrint(("HvCheckBin 1000: last cell points off the end\n")); 00383 KdPrint(("Bin = %08lx\n", Bin)); 00384 HvCheckBinDebug.Status = 1000; 00385 return 1000; 00386 } 00387 00388 if (ARGUMENT_PRESENT(Storage)) { 00389 *Storage += userallocated; 00390 } 00391 return 0; 00392 } }

ULONG HvCheckHive PHHIVE  Hive,
PULONG Storage  OPTIONAL
 

Definition at line 54 of file hivechek.c.

References Bin, _HBIN::FileOffset, HBIN_SIGNATURE, HCELL_INDEX, HCELL_NIL, Hive, HMAP_BASE, HMAP_DISCARDABLE, HvCheckBin(), HvCheckHiveDebug, HvpGetCellMap(), NULL, _HBIN::Signature, _FREE_HBIN::Size, _HBIN::Size, t(), and Volatile.

Referenced by CmCheckRegistry(), and HvRefreshHive().

00060 : 00061 00062 Check the consistency of a hive. Apply CheckBin to bins, make sure 00063 all pointers in the cell map point to correct places. 00064 00065 Arguments: 00066 00067 Hive - supplies a pointer to the hive control structure for the 00068 hive of interest. 00069 00070 Storage - supplies adddress of ULONG to receive size of allocated user data 00071 00072 Return Value: 00073 00074 0 if Hive is OK. Error return indicator if not. Error value 00075 comes from one of the check procedures. 00076 00077 RANGE: 2000 - 2999 00078 00079 --*/ 00080 { 00081 HCELL_INDEX p; 00082 ULONG Length; 00083 ULONG localstorage = 0; 00084 PHMAP_ENTRY t; 00085 PHBIN Bin; 00086 ULONG i; 00087 ULONG rc; 00088 PFREE_HBIN FreeBin; 00089 00090 HvCheckHiveDebug.Hive = Hive; 00091 HvCheckHiveDebug.Status = 0; 00092 HvCheckHiveDebug.Space = (ULONG)-1; 00093 HvCheckHiveDebug.MapPoint = HCELL_NIL; 00094 HvCheckHiveDebug.BinPoint = 0; 00095 00096 p = 0; 00097 00098 00099 // 00100 // one pass for Stable space, one pass for Volatile 00101 // 00102 for (i = 0; i <= Volatile; i++) { 00103 Length = Hive->Storage[i].Length; 00104 00105 // 00106 // for each bin in the space 00107 // 00108 while (p < Length) { 00109 t = HvpGetCellMap(Hive, p); 00110 if (t == NULL) { 00111 KdPrint(("HvCheckHive:")); 00112 KdPrint(("\tBin@:%08lx invalid\n", Bin)); 00113 HvCheckHiveDebug.Status = 2005; 00114 HvCheckHiveDebug.Space = i; 00115 HvCheckHiveDebug.MapPoint = p; 00116 return 2005; 00117 } 00118 00119 00120 if ((t->BinAddress & HMAP_DISCARDABLE) == 0) { 00121 00122 Bin = (PHBIN)((t->BinAddress) & HMAP_BASE); 00123 00124 // 00125 // bin header valid? 00126 // 00127 if ( (Bin->Size > Length) || 00128 (Bin->Signature != HBIN_SIGNATURE) || 00129 (Bin->FileOffset != p) 00130 ) 00131 { 00132 KdPrint(("HvCheckHive:")); 00133 KdPrint(("\tBin@:%08lx invalid\n", Bin)); 00134 HvCheckHiveDebug.Status = 2010; 00135 HvCheckHiveDebug.Space = i; 00136 HvCheckHiveDebug.MapPoint = p; 00137 HvCheckHiveDebug.BinPoint = Bin; 00138 return 2010; 00139 } 00140 00141 // 00142 // structure inside the bin valid? 00143 // 00144 rc = HvCheckBin(Hive, Bin, &localstorage); 00145 if (rc != 0) { 00146 HvCheckHiveDebug.Status = rc; 00147 HvCheckHiveDebug.Space = i; 00148 HvCheckHiveDebug.MapPoint = p; 00149 HvCheckHiveDebug.BinPoint = Bin; 00150 return rc; 00151 } 00152 00153 p = (ULONG)p + Bin->Size; 00154 00155 } else { 00156 // 00157 // Bin is not present, skip it and advance to the next one. 00158 // 00159 FreeBin = (PFREE_HBIN)t->BlockAddress; 00160 p+=FreeBin->Size; 00161 } 00162 } 00163 00164 p = 0x80000000; // Beginning of Volatile space 00165 } 00166 00167 if (ARGUMENT_PRESENT(Storage)) { 00168 *Storage = localstorage; 00169 } 00170 return 0; 00171 }


Variable Documentation

PHBIN Bin
 

Definition at line 43 of file hivechek.c.

PHBIN BinPoint
 

Definition at line 39 of file hivechek.c.

PHCELL CellPoint
 

Definition at line 45 of file hivechek.c.

PHHIVE Hive
 

Definition at line 35 of file hivechek.c.

struct { ... } HvCheckBinDebug
 

struct { ... } HvCheckHiveDebug
 

HCELL_INDEX MapPoint
 

Definition at line 38 of file hivechek.c.

ULONG Space
 

Definition at line 37 of file hivechek.c.

ULONG Status
 

Definition at line 44 of file hivechek.c.


Generated on Sat May 15 19:44:05 2004 for test by doxygen 1.3.7