00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
#include "cmp.h"
00025
00026
#ifdef ALLOC_PRAGMA
00027
#pragma alloc_text(PAGE,HvCheckHive)
00028
#pragma alloc_text(PAGE,HvCheckBin)
00029
#endif
00030
00031
00032
00033
00034
extern struct {
00035 PHHIVE Hive;
00036 ULONG
Status;
00037 ULONG
Space;
00038 HCELL_INDEX MapPoint;
00039 PHBIN BinPoint;
00040 }
HvCheckHiveDebug;
00041
00042
extern struct {
00043 PHBIN Bin;
00044 ULONG
Status;
00045 PHCELL CellPoint;
00046 }
HvCheckBinDebug;
00047
00048
00049
#if DBG
00050
ULONG HvHiveChecking=0;
00051
#endif
00052
00053 ULONG
00054 HvCheckHive(
00055
PHHIVE Hive,
00056 PULONG Storage OPTIONAL
00057 )
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
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
00101
00102
for (i = 0; i <=
Volatile; i++) {
00103 Length =
Hive->Storage[i].Length;
00104
00105
00106
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
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
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
00158
00159 FreeBin = (
PFREE_HBIN)
t->BlockAddress;
00160 p+=FreeBin->
Size;
00161 }
00162 }
00163
00164 p = 0x80000000;
00165 }
00166
00167
if (ARGUMENT_PRESENT(Storage)) {
00168 *Storage = localstorage;
00169 }
00170
return 0;
00171 }
00172
00173
00174 ULONG
00175 HvCheckBin(
00176
PHHIVE Hive,
00177
PHBIN Bin,
00178 PULONG Storage
00179 )
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 {
00203
PHCELL p;
00204
PHCELL np;
00205
PHCELL lp;
00206 ULONG freespace = 0
L;
00207 ULONG allocated = 0
L;
00208 ULONG userallocated = 0
L;
00209
00210
HvCheckBinDebug.Bin =
Bin;
00211
HvCheckBinDebug.Status = 0;
00212
HvCheckBinDebug.CellPoint = 0;
00213
00214
00215
00216
00217
00218 p = (
PHCELL)((PUCHAR)
Bin +
sizeof(
HBIN));
00219 lp = p;
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
while (p < (
PHCELL)((PUCHAR)
Bin +
Bin->
Size)) {
00247
00248
00249
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
00275
00276
if (p->Size < 0) {
00277
00278
00279
00280
00281
00282
00283
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
00306
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
00324
00325
00326
00327
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
00345
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
00364
00365
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
00378
00379
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 }