test: hiveinit.c Source File

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

# hiveinit.c

Go to the documentation of this file.

    00001 /*++
    00002
    00003 Copyright (c) 1991  Microsoft Corporation
    00004
    00005 Module Name:
    00006
    00007     hiveinit.c
    00008
    00009 Abstract:
    00010
    00011     Hive initialization code.
    00012
    00013 Author:
    00014
    00015     Bryan M. Willman (bryanwi) 12-Sep-91
    00016
    00017 Environment:
    00018
    00019
    00020 Revision History:
    00021     Dragos C. Sambotin (dragoss) 25-Jan-99
    00022         Implementation of bin-size chunk loading of hives.
    00023 --*/
    00024
    00025 #include    "cmp.h"
    00026
    00027 VOID
    00028 HvpFillFileName(
    00029     PHBASE_BLOCK            BaseBlock,
    00030     PUNICODE_STRING         FileName
    00031     );
    00032
    00033 #ifdef ALLOC_PRAGMA
    00034 #pragma alloc_text(PAGE,HvInitializeHive)
    00035 #pragma alloc_text(PAGE,HvpFillFileName)
    00036 #pragma alloc_text(PAGE,HvpFreeAllocatedBins)
    00037 #endif
    00038
    00039
    00040
    00041 #if 0
    00042
    00043 VOID
    00044 HvpDumpFreeDisplay(     PHHIVE Hive
    00045                    )
    00046 {
    00047     ULONG       Index;
    00048     ULONG       Mask;
    00049     HCELL_INDEX cell;
    00050     PHCELL      pcell;
    00051
    00052     KdPrint(("\nHvpDumpFreeDisplay:\n"));
    00053
    00054     for( Index =0;Index<HHIVE_FREE_DISPLAY_SIZE;Index++){
    00055         Mask = 1;
    00056         Mask <<= Index;
    00057         KdPrint(("\nFreeDisplay[%lu]\n",Index));
    00058         if(Hive->Storage[Stable].FreeSummary & Mask) {
    00059         //
    00060         // there is something on this list
    00061         //
    00062
    00063             cell = Hive->Storage[Stable].FreeDisplay[Index];
    00064             while (cell != HCELL_NIL) {
    00065
    00066                 KdPrint(("0x%08lx ",cell));
    00067                 pcell = HvpGetHCell(Hive, cell);
    00068
    00069                 if (USE_OLD_CELL(Hive)) {
    00070                     cell = pcell->u.OldCell.u.Next;
    00071                 } else {
    00072                     cell = pcell->u.NewCell.u.Next;
    00073                 }
    00074             }
    00075         }
    00076     }
    00077 }
    00078 #else
    00079
    00080 #define HvpDumpFreeDisplay(Hive) //nothing
    00081
    00082 #endif
    00083
    00084 VOID
    00085 HvpFreeAllocatedBins(
    00086     PHHIVE Hive
    00087     )
    00088 /*++
    00089
    00090 Routine Description:
    00091
    00092     Free all the bins allocated for the specified hive.
    00093     It applies only to stable storage. Not all bins are allocated.
    00094     Those that are not allocated have BinAddress set to 0
    00095
    00096 Arguments:
    00097
    00098     Hive - supplies a pointer to hive control structure for hive who's bin to free.
    00099
    00100 Return Value:
    00101
    00102     NONE.
    00103
    00104 --*/
    00105 {
    00106     ULONG           Length;
    00107     PHBIN           Bin;
    00108     ULONG           MapSlots;
    00109     ULONG           Tables;
    00110     PHMAP_ENTRY     Me;
    00111     PHMAP_TABLE     Tab;
    00112     ULONG           i;
    00113     ULONG           j;
    00114
    00115     //
    00116     // calculate the number of tables in the map
    00117     //
    00118     Length = Hive->Storage[Stable].Length;
    00119     MapSlots = Length / HBLOCK_SIZE;
    00120     if( MapSlots > 0 ) {
    00121         Tables = (MapSlots-1) / HTABLE_SLOTS;
    00122     } else {
    00123         Tables = 0;
    00124     }
    00125
    00126     if( Hive->Storage[Stable].Map ) {
    00127         //
    00128         // iterate through the directory
    00129         //
    00130         for (i = 0; i <= Tables; i++) {
    00131             Tab = Hive->Storage[Stable].Map->Directory[i];
    00132
    00133             ASSERT(Tab);
    00134
    00135             //
    00136             // iterate through the slots in the directory
    00137             //
    00138             for(j=0;j<HTABLE_SLOTS;j++) {
    00139                 Me = &(Tab->Table[j]);
    00140                 //
    00141                 // BinAddress non-zero means allocated bin
    00142                 //
    00143                 if( Me->BinAddress ) {
    00144                     if( Me->BinAddress & HMAP_NEWALLOC ) {
    00145                         Bin = (PHBIN)(Me->BinAddress & HMAP_BASE);
    00146                         (Hive->Free)(Bin, Bin->MemAlloc);
    00147                     }
    00148
    00149                     Me->BinAddress = 0;
    00150                 }
    00151             }
    00152         }
    00153     }
    00154
    00155 }
    00156
    00157 NTSTATUS
    00158 HvInitializeHive(
    00159     PHHIVE                  Hive,
    00160     ULONG                   OperationType,
    00161     ULONG                   HiveFlags,
    00162     ULONG                   FileType,
    00163     PVOID                   HiveData OPTIONAL,
    00164     PALLOCATE_ROUTINE       AllocateRoutine,
    00165     PFREE_ROUTINE           FreeRoutine,
    00166     PFILE_SET_SIZE_ROUTINE  FileSetSizeRoutine,
    00167     PFILE_WRITE_ROUTINE     FileWriteRoutine,
    00168     PFILE_READ_ROUTINE      FileReadRoutine,
    00169     PFILE_FLUSH_ROUTINE     FileFlushRoutine,
    00170     ULONG                   Cluster,
    00171     PUNICODE_STRING         FileName OPTIONAL
    00172     )
    00173 /*++
    00174
    00175 Routine Description:
    00176
    00177     Initialize a hive.
    00178
    00179     Core HHive fields are always inited.
    00180
    00181     File calls WILL be made BEFORE this call returns.
    00182
    00183     Caller is expected to create/open files and store file handles
    00184     in a way that can be derived from the hive pointer.
    00185
    00186     Three kinds of initialization can be done, selected by OperationType:
    00187
    00188         HINIT_CREATE
    00189
    00190             Create a new hive from scratch.  Will have 0 storage.
    00191             [Used to do things like create HARDWARE hive and for parts
    00192              of SaveKey and RestoreKey]
    00193
    00194
    00195         HINIT_MEMORY_INPLACE
    00196
    00197             Build a hive control structure which allows read only
    00198             access to a contiguous in-memory image of a hive.
    00199             No part of the image will be copied, but a map will
    00200             be made.
    00201             [Used by osloader.]
    00202
    00203
    00204         HINIT_FLAT
    00205
    00206             Support very limited (read-only, no checking code) operation
    00207             against a hive image.
    00208
    00209
    00210         HINIT_MEMORY
    00211
    00212             Create a new hive, using a hive image already in memory,
    00213             at address supplied by pointer HiveData.  The data will
    00214             be copied.  Caller is expected to free HiveData.
    00215             [Used for SYSTEM hive]
    00216
    00217
    00218         HINIT_FILE
    00219
    00220             Create a hive, reading its data from a file.  Recovery processing
    00221             via log file will be done if a log is available.  If a log
    00222             is recovered, flush and clear operation will proceed.
    00223
    00224
    00225     NOTE:   The HHive is not a completely opaque structure, because it
    00226             is really only used by a limited set of code.  Do not assume
    00227             that only this routine sets all of these values.
    00228
    00229
    00230 Arguments:
    00231
    00232     Hive - supplies a pointer to hive control structure to be initialized
    00233             to describe this hive.
    00234
    00235     OperationType - specifies whether to create a new hive from scratch,
    00236             from a memory image, or by reading a file from disk.
    00237
    00238     HiveFlags - HIVE_VOLATILE - Entire hive is to be volatile, regardless
    00239                                    of the types of cells allocated
    00240                 HIVE_NO_LAZY_FLUSH - Data in this hive is never written
    00241                                    to disk except by an explicit FlushKey
    00242
    00243     FileType - HFILE_TYPE_*, HFILE_TYPE_LOG or HFILE_TYPE_ALTERNATE set
    00244             up for logging or alternate support respectively.
    00245
    00246     HiveData - if present, supplies a pointer to an in memory image of
    00247             from which to init the hive.  Only useful when OperationType
    00248             is set to HINIT_MEMORY.
    00249
    00250     AllocateRoutine - supplies a pointer to routine called to allocate
    00251                         memory.  WILL be called before this routine returns.
    00252
    00253     FreeRoutine - supplies a pointer to routine called to free memory.
    00254                    CAN be called before this routine returns.
    00255
    00256     FileSetSizeRoutine - supplies a pointer to a routine used to set the
    00257                          size of a file. CAN be called before this
    00258                          routine returns.
    00259
    00260     FileWriteRoutine - supplies a pointer to routine called to write memory
    00261                         to a file.
    00262
    00263     FileReadRoutine - supplies a pointer to routine called to read from
    00264                         a file into memory. CAN be called before this
    00265                         routine returns.
    00266
    00267     FileFlushRoutine - supplies a pointer to routine called to flush a file.
    00268
    00269     Cluster - clustering factor in HSECTOR_SIZE units.  (i.e.  Size of
    00270             physical sector in media / HSECTOR_SIZE.  1 for 512 byte
    00271             physical sectors (or smaller), 2 for 1024, 4 for 2048, etc.
    00272             (Numbers greater than 8 won't work.)
    00273
    00274     FileName - some path like "...\system32\config\system", last
    00275                 32 or so characters will be copied into baseblock
    00276                 (and thus to disk) as a debugging aid.  May be null.
    00277
    00278
    00279 Return Value:
    00280
    00281     NTSTATUS code.
    00282
    00283 --*/
    00284 {
    00285     BOOLEAN         UseForIo;
    00286     PHBASE_BLOCK    BaseBlock = NULL;
    00287     NTSTATUS        Status;
    00288     NTSTATUS        Status2;
    00289     PVOID           Image;
    00290     ULONG           i;
    00291     PHBIN           Pbin;
    00292     ULONG           Alignment;
    00293
    00294     //
    00295     // this array stores the last elements in each free cell list for the stable storage
    00296     //
    00297     HCELL_INDEX     TailDisplay[HHIVE_FREE_DISPLAY_SIZE];
    00298
    00299     CMLOG(CML_MAJOR, CMS_INIT) {
    00300         KdPrint(("HvInitializeHive:\n"));
    00301         KdPrint(("\tHive=%08lx\n", Hive));
    00302     }
    00303
    00304     //
    00305     // reject invalid parameter combinations
    00306     //
    00307     if ( (! ARGUMENT_PRESENT(HiveData)) &&
    00308          ((OperationType == HINIT_MEMORY) ||
    00309           (OperationType == HINIT_FLAT) ||
    00310           (OperationType == HINIT_MEMORY_INPLACE))
    00311        )
    00312     {
    00313         return STATUS_INVALID_PARAMETER;
    00314     }
    00315
    00316     if ( ! ((OperationType == HINIT_CREATE) ||
    00317             (OperationType == HINIT_MEMORY) ||
    00318             (OperationType == HINIT_MEMORY_INPLACE) ||
    00319             (OperationType == HINIT_FLAT) ||
    00320             (OperationType == HINIT_FILE))
    00321        )
    00322     {
    00323         return STATUS_INVALID_PARAMETER;
    00324     }
    00325
    00326
    00327     //
    00328     // static and global control values
    00329     //
    00330     Hive->Signature = HHIVE_SIGNATURE;
    00331
    00332     Hive->Allocate = AllocateRoutine;
    00333     Hive->Free = FreeRoutine;
    00334     Hive->FileSetSize = FileSetSizeRoutine;
    00335     Hive->FileWrite = FileWriteRoutine;
    00336     Hive->FileRead = FileReadRoutine;
    00337     Hive->FileFlush = FileFlushRoutine;
    00338
    00339     Hive->Log = (BOOLEAN)((FileType == HFILE_TYPE_LOG) ? TRUE : FALSE);
    00340     Hive->Alternate = (BOOLEAN)((FileType == HFILE_TYPE_ALTERNATE) ? TRUE : FALSE);
    00341
    00342     if ((Hive->Log || Hive->Alternate)  && (HiveFlags & HIVE_VOLATILE)) {
    00343         return STATUS_INVALID_PARAMETER;
    00344     }
    00345
    00346     Hive->HiveFlags = HiveFlags;
    00347
    00348     if ((Cluster == 0) || (Cluster > HSECTOR_COUNT)) {
    00349         return STATUS_INVALID_PARAMETER;
    00350     }
    00351     Hive->Cluster = Cluster;
    00352
    00353     Hive->RefreshCount = 0;
    00354
    00355     Hive->StorageTypeCount = HTYPE_COUNT;
    00356
    00357
    00358     Hive->Storage[Volatile].Length = 0;
    00359     Hive->Storage[Volatile].Map = NULL;
    00360     Hive->Storage[Volatile].SmallDir = NULL;
    00361     Hive->Storage[Volatile].Guard = (ULONG)-1;
    00362     Hive->Storage[Volatile].FreeSummary = 0;
    00363     InitializeListHead(&Hive->Storage[Volatile].FreeBins);
    00364     for (i = 0; i < HHIVE_FREE_DISPLAY_SIZE; i++) {
    00365         Hive->Storage[Volatile].FreeDisplay[i] = HCELL_NIL;
    00366     }
    00367
    00368     Hive->Storage[Stable].Length = 0;
    00369     Hive->Storage[Stable].Map = NULL;
    00370     Hive->Storage[Stable].SmallDir = NULL;
    00371     Hive->Storage[Stable].Guard = (ULONG)-1;
    00372     Hive->Storage[Stable].FreeSummary = 0;
    00373     InitializeListHead(&Hive->Storage[Stable].FreeBins);
    00374     for (i = 0; i < HHIVE_FREE_DISPLAY_SIZE; i++) {
    00375         Hive->Storage[Stable].FreeDisplay[i] = HCELL_NIL;
    00376         TailDisplay[i] = HCELL_NIL;
    00377     }
    00378
    00379     RtlInitializeBitMap(&(Hive->DirtyVector), NULL, 0);
    00380     Hive->DirtyCount = 0;
    00381     Hive->DirtyAlloc = 0;
    00382     Hive->LogSize = 0;
    00383
    00384     Hive->GetCellRoutine = HvpGetCellPaged;
    00385     Hive->Flat = FALSE;
    00386     Hive->ReadOnly = FALSE;
    00387     UseForIo = (BOOLEAN)!(Hive->HiveFlags & HIVE_VOLATILE);
    00388
    00389     //
    00390     // new create case
    00391     //
    00392     if (OperationType == HINIT_CREATE) {
    00393
    00394         BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(sizeof(HBASE_BLOCK), UseForIo));
    00395         if (BaseBlock == NULL) {
    00396             return STATUS_INSUFFICIENT_RESOURCES;
    00397         }
    00398         //
    00399         // Make sure the buffer we got back is cluster-aligned. If not, try
    00400         // harder to get an aligned buffer.
    00401         //
    00402         Alignment = Cluster * HSECTOR_SIZE - 1;
    00403         if (((ULONG_PTR)BaseBlock & Alignment) != 0) {
    00404             (Hive->Free)(BaseBlock, sizeof(HBASE_BLOCK));
    00405             BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(PAGE_SIZE, TRUE));
    00406             if (BaseBlock == NULL) {
    00407                 return STATUS_INSUFFICIENT_RESOURCES;
    00408             }
    00409
    00410             //
    00411             // Return the quota for the extra allocation, as we are not really using
    00412             // it and it will not be accounted for later when we free it.
    00413             //
    00414             CmpReleaseGlobalQuota(PAGE_SIZE - sizeof(HBASE_BLOCK));
    00415         }
    00416
    00417         BaseBlock->Signature = HBASE_BLOCK_SIGNATURE;
    00418         BaseBlock->Sequence1 = 1;
    00419         BaseBlock->Sequence2 = 1;
    00420         BaseBlock->TimeStamp.HighPart = 0;
    00421         BaseBlock->TimeStamp.LowPart = 0;
    00422         BaseBlock->Major = HSYS_MAJOR;
    00423         BaseBlock->Minor = HSYS_MINOR;
    00424         BaseBlock->Type = HFILE_TYPE_PRIMARY;
    00425         BaseBlock->Format = HBASE_FORMAT_MEMORY;
    00426         BaseBlock->RootCell = HCELL_NIL;
    00427         BaseBlock->Length = 0;
    00428         BaseBlock->Cluster = Cluster;
    00429         BaseBlock->CheckSum = 0;
    00430         HvpFillFileName(BaseBlock, FileName);
    00431         Hive->BaseBlock = BaseBlock;
    00432         Hive->Version = HSYS_MINOR;
    00433
    00434         return STATUS_SUCCESS;
    00435     }
    00436
    00437     //
    00438     // flat image case
    00439     //
    00440     if (OperationType == HINIT_FLAT) {
    00441         Hive->BaseBlock = (PHBASE_BLOCK)HiveData;
    00442         Hive->Version = Hive->BaseBlock->Minor;
    00443         Hive->Flat = TRUE;
    00444         Hive->ReadOnly = TRUE;
    00445         Hive->GetCellRoutine = HvpGetCellFlat;
    00446         Hive->Storage[Stable].Length = Hive->BaseBlock->Length;
    00447         Hive->StorageTypeCount = 1;
    00448         return STATUS_SUCCESS;
    00449     }
    00450
    00451     //
    00452     // readonly image case
    00453     //
    00454     if (OperationType == HINIT_MEMORY_INPLACE) {
    00455         BaseBlock = (PHBASE_BLOCK)HiveData;
    00456
    00457         if ( (BaseBlock->Signature != HBASE_BLOCK_SIGNATURE)   ||
    00458              (BaseBlock->Type != HFILE_TYPE_PRIMARY)           ||
    00459              (BaseBlock->Major != HSYS_MAJOR)                  ||
    00460              (BaseBlock->Minor > HSYS_MINOR)                   ||
    00461              (BaseBlock->Format != HBASE_FORMAT_MEMORY)        ||
    00462              (BaseBlock->Sequence1 != BaseBlock->Sequence2)    ||
    00463              (HvpHeaderCheckSum(BaseBlock) !=
    00464               (BaseBlock->CheckSum))
    00465            )
    00466         {
    00467             return STATUS_REGISTRY_CORRUPT;
    00468         }
    00469
    00470         Hive->BaseBlock = BaseBlock;
    00471         Hive->Version = BaseBlock->Minor;
    00472         Hive->ReadOnly = TRUE;
    00473         Hive->StorageTypeCount = 1;
    00474
    00475         if (FileType == HFILE_TYPE_ALTERNATE) {
    00476             //
    00477             // Mark the baseblock with Type==HFILE_TYPE_ALTERNATE.  This
    00478             // case will never show up on disk, because we always flush
    00479             // Type==HFILE_TYPE_PRIMARY to the alternate file.  Any
    00480             // baseblock with Type==HFILE_TYPE_ALTERNATE indicates that
    00481             // the primary is corrupt and must be rewritten.
    00482             //
    00483             BaseBlock->Type=HFILE_TYPE_ALTERNATE;
    00484
    00485             //
    00486             // baseblock has changed, recompute the checksum.
    00487             //
    00488             BaseBlock->CheckSum=HvpHeaderCheckSum(BaseBlock);
    00489         }
    00490
    00491         if ( !NT_SUCCESS(HvpBuildMap(
    00492                             Hive,
    00493                             (PUCHAR)HiveData + HBLOCK_SIZE,
    00494                             TailDisplay
    00495                             )))
    00496         {
    00497             return STATUS_REGISTRY_CORRUPT;
    00498         }
    00499
    00500         // debug-only
    00501         HvpDumpFreeDisplay(Hive);
    00502
    00503         return(STATUS_SUCCESS);
    00504     }
    00505
    00506     //
    00507     // memory copy case
    00508     //
    00509     if (OperationType == HINIT_MEMORY) {
    00510         BaseBlock = (PHBASE_BLOCK)HiveData;
    00511
    00512         if ( (BaseBlock->Signature != HBASE_BLOCK_SIGNATURE)   ||
    00513              ((BaseBlock->Type != HFILE_TYPE_PRIMARY)    &&
    00514               (BaseBlock->Type != HFILE_TYPE_ALTERNATE))       ||
    00515              (BaseBlock->Format != HBASE_FORMAT_MEMORY)        ||
    00516              (BaseBlock->Major != HSYS_MAJOR)                  ||
    00517              (BaseBlock->Minor > HSYS_MINOR)                   ||
    00518              (HvpHeaderCheckSum(BaseBlock) !=
    00519               (BaseBlock->CheckSum))
    00520            )
    00521         {
    00522             return STATUS_REGISTRY_CORRUPT;
    00523         }
    00524
    00525         Hive->BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(sizeof(HBASE_BLOCK), UseForIo));
    00526         if (Hive->BaseBlock==NULL) {
    00527             return(STATUS_INSUFFICIENT_RESOURCES);
    00528         }
    00529         //
    00530         // Make sure the buffer we got back is cluster-aligned. If not, try
    00531         // harder to get an aligned buffer.
    00532         //
    00533         Alignment = Cluster * HSECTOR_SIZE - 1;
    00534         if (((ULONG_PTR)Hive->BaseBlock & Alignment) != 0) {
    00535             (Hive->Free)(Hive->BaseBlock, sizeof(HBASE_BLOCK));
    00536             Hive->BaseBlock = (PHBASE_BLOCK)((Hive->Allocate)(PAGE_SIZE, TRUE));
    00537             if (Hive->BaseBlock == NULL) {
    00538                 return (STATUS_INSUFFICIENT_RESOURCES);
    00539             }
    00540         }
    00541         RtlCopyMemory(Hive->BaseBlock, BaseBlock, HSECTOR_SIZE);
    00542
    00543         Hive->Version = Hive->BaseBlock->Minor;
    00544
    00545         if ( !NT_SUCCESS(HvpBuildMapAndCopy(Hive,
    00546                                             (PUCHAR)HiveData + HBLOCK_SIZE,
    00547                                             TailDisplay))) {
    00548
    00549             (Hive->Free)(Hive->BaseBlock, sizeof(HBASE_BLOCK));
    00550             Hive->BaseBlock = NULL;
    00551             return STATUS_REGISTRY_CORRUPT;
    00552         }
    00553
    00554         if (BaseBlock->Type == HFILE_TYPE_ALTERNATE) {
    00555             //
    00556             // Note that Type==HFILE_TYPE_ALTERNATE will NEVER occur in
    00557             // an on-disk image.  The only way this can show up in the
    00558             // baseblock is when the osloader rejects the SYSTEM hive and
    00559             // successfully loads SYSTEM.ALT.  When this happens, it
    00560             // forces HFILE_TYPE_ALTERNATE into the in-memory image of
    00561             // the baseblock.
    00562             //
    00563             // We've booted from SYSTEM.ALT.  Mark the whole hive dirty
    00564             // so everything gets flushed to SYSTEM as soon as we can
    00565             // do I/O.
    00566             //
    00567             RtlSetAllBits(&(Hive->DirtyVector));
    00568             Hive->DirtyCount=Hive->DirtyVector.SizeOfBitMap;
    00569
    00570         }
    00571         HvpFillFileName(Hive->BaseBlock, FileName);
    00572
    00573         // debug - only
    00574         HvpDumpFreeDisplay(Hive);
    00575
    00576         return(STATUS_SUCCESS);
    00577     }
    00578
    00579     //
    00580     // file read case
    00581     //
    00582     if (OperationType == HINIT_FILE) {
    00583
    00584         CMLOG(CML_BIN, CMS_BIN_MAP) {
    00585             KdPrint(("HvInitializeHive(%wZ,HINIT_FILE) :\n", FileName));
    00586         }
    00587         //
    00588         // get the file image (possible recovered via log) into memory
    00589         //
    00590         Status = HvLoadHive(Hive, TailDisplay);
    00591         if ((Status != STATUS_SUCCESS) && (Status != STATUS_REGISTRY_RECOVERED)) {
    00592             return Status;
    00593         }
    00594
    00595         CMLOG(CML_BIN, CMS_BIN_MAP) {
    00596             KdPrint(("\n"));
    00597         }
    00598
    00599         if (Status == STATUS_REGISTRY_RECOVERED) {
    00600
    00601             //
    00602             // We have a good hive, with a log, and a dirty map,
    00603             // all set up.  Only problem is that we need to flush
    00604             // the file so the log can be cleared and new writes
    00605             // posted against the hive.  Since we know we have
    00606             // a good log in hand, we just write the hive image.
    00607             //
    00608             if ( ! HvpDoWriteHive(Hive, HFILE_TYPE_PRIMARY)) {
    00609                 //
    00610                 // DRAGOS: Here we need cleanup
    00611                 // Clean up the bins already allocated
    00612                 //
    00613                 HvpFreeAllocatedBins( Hive );
    00614
    00615                 return STATUS_REGISTRY_IO_FAILED;
    00616             }
    00617
    00618             //
    00619             // If we get here, we have recovered the hive, and
    00620             // written it out to disk correctly.  So we clear
    00621             // the log here.
    00622             //
    00623             RtlClearAllBits(&(Hive->DirtyVector));
    00624             Hive->DirtyCount = 0;
    00625             (Hive->FileSetSize)(Hive, HFILE_TYPE_LOG, 0);
    00626             Hive->LogSize = 0;
    00627         }
    00628
    00629         //
    00630         // slam debug name data into base block
    00631         //
    00632         HvpFillFileName(Hive->BaseBlock, FileName);
    00633
    00634         // debug - only
    00635         HvpDumpFreeDisplay(Hive);
    00636
    00637         return STATUS_SUCCESS;
    00638     }
    00639
    00640     return STATUS_INVALID_PARAMETER;
    00641 }
    00642
    00643
    00644 VOID
    00645 HvpFillFileName(
    00646     PHBASE_BLOCK            BaseBlock,
    00647     PUNICODE_STRING         FileName
    00648     )
    00649 /*++
    00650
    00651 Routine Description:
    00652
    00653     Zero out the filename portion of the base block.
    00654     If FileName is not NULL, copy last 64 bytes into name tail
    00655         field of base block
    00656
    00657 Arguments:
    00658
    00659     BaseBlock - supplies pointer to a base block
    00660
    00661     FileName - supplies pointer to a unicode STRING
    00662
    00663 Return Value:
    00664
    00665     None.
    00666
    00667 --*/
    00668 {
    00669     ULONG   offset;
    00670     ULONG   length;
    00671     PUCHAR  sptr;
    00672
    00673 #if 0
    00674     KdPrint(("HvpFillFileName: %wZ\n", FileName));
    00675 #endif
    00676
    00677     RtlZeroMemory((PVOID)&(BaseBlock->FileName[0]), HBASE_NAME_ALLOC);
    00678
    00679     if (FileName == NULL) {
    00680         return;
    00681     }
    00682
    00683     if (FileName->Length <= HBASE_NAME_ALLOC) {
    00684         offset = 0;
    00685         length = FileName->Length;
    00686     } else {
    00687         offset = FileName->Length - HBASE_NAME_ALLOC;
    00688         length = HBASE_NAME_ALLOC;
    00689     }
    00690
    00691     sptr = (PUCHAR)&(FileName->Buffer[0]);
    00692     RtlMoveMemory(
    00693         (PVOID)&(BaseBlock->FileName[0]),
    00694         (PVOID)&(sptr[offset]),
    00695         length
    00696         );
    00697 }