test: cminit.c File Reference

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

# cminit.c File Reference

`#include "cmp.h"`

Go to the source code of this file.

## Functions

NTSTATUS | CmpOpenFileWithExtremePrejudice (OUT PHANDLE Primary, IN POBJECT_ATTRIBUTES Obja, IN ULONG IoFlags, IN ULONG AttributeFlags)
NTSTATUS | CmpOpenHiveFiles (PUNICODE_STRING BaseName, PWSTR Extension OPTIONAL, PHANDLE Primary, PHANDLE Secondary, PULONG PrimaryDisposition, PULONG SecondaryDisposition, BOOLEAN CreateAllowed, BOOLEAN MarkAsSystemHive, OUT OPTIONAL PULONG ClusterSize)
NTSTATUS | CmpInitializeHive (PCMHIVE *CmHive, ULONG OperationType, ULONG HiveFlags, ULONG FileType, PVOID HiveData OPTIONAL, HANDLE Primary, HANDLE Alternate, HANDLE Log, HANDLE External, PUNICODE_STRING FileName OPTIONAL)
BOOLEAN | CmpDestroyHive (IN PHHIVE Hive, IN HCELL_INDEX Cell)

## Variables

PCMHIVE | CmpMasterHive
LIST_ENTRY | CmpHiveListHead

## Function Documentation

BOOLEAN CmpDestroyHive | ( | IN PHHIVE | Hive,
|  | IN HCELL_INDEX | Cell
| ) |

Definition at line 667 of file cminit.c.

References ASSERT, Cell, CmpFreeKeyByCell(), CmpMasterHive, FALSE, HCELL_INDEX, Hive, HiveList, HvGetCell, _CELL_DATA::_u::KeyNode, NT_SUCCESS, NTSTATUS(), _CM_KEY_NODE::Parent, Status, TRUE, and _CELL_DATA::u.

Referenced by CmUnloadKey().

    00674                    :
    00675
    00676     This routine tears down a cmhive.
    00677
    00678 Arguments:
    00679
    00680     Hive - Supplies a pointer to the hive to be freed.
    00681
    00682     Cell - Supplies index of the hive's root cell.
    00683
    00684 Return Value:
    00685
    00686     TRUE if successful
    00687     FALSE if some failure occurred
    00688
    00689 --*/
    00690
    00691 {
    00692     PCELL_DATA CellData;
    00693     HCELL_INDEX LinkCell;
    00694     NTSTATUS Status;
    00695
    00696     //
    00697     // First find the link cell.
    00698     //
    00699     CellData = HvGetCell(Hive, Cell);
    00700     LinkCell = CellData->u.KeyNode.Parent;
    00701
    00702     //
    00703     // Now delete the link cell.
    00704     //
    00705     ASSERT(FIELD_OFFSET(CMHIVE, Hive) == 0);
    00706     Status = CmpFreeKeyByCell((PHHIVE)CmpMasterHive, LinkCell, TRUE);
    00707
    00708     if (NT_SUCCESS(Status)) {
    00709         //
    00710         // Take the hive out of the hive list
    00711         //
    00712         RemoveEntryList(&( ((PCMHIVE)Hive)->HiveList));
    00713         return(TRUE);
    00714     } else {
    00715         return(FALSE);
    00716     }
    00717 }

NTSTATUS CmpInitializeHive | ( | PCMHIVE * | CmHive,
|  | ULONG | OperationType,
|  | ULONG | HiveFlags,
|  | ULONG | FileType,
|  | PVOID HiveData | OPTIONAL,
|  | HANDLE | Primary,
|  | HANDLE | Alternate,
|  | HANDLE | Log,
|  | HANDLE | External,
|  | PUNICODE_STRING FileName | OPTIONAL
| ) |

Definition at line 471 of file cminit.c.

References ASSERT, ASSERT_PASSIVE_LEVEL, CmCheckRegistry(), CMHIVE, CML_MAJOR, CMLOG, CmpAllocate(), CmpFileFlush(), CmpFileRead(), CmpFileSetSize(), CmpFileWrite(), CmpFree(), CmpHiveListHead, CMS_INIT, CMS_INIT_ERROR, ExAllocatePoolWithTag, ExFreePool(), ExInitializeFastMutex, FALSE, _CMHIVE::FileHandles, FileName, HBLOCK_SIZE, HFILE_TYPE_ALTERNATE, HFILE_TYPE_EXTERNAL, HFILE_TYPE_LOG, HFILE_TYPE_MAX, HFILE_TYPE_PRIMARY, HINIT_FILE, HINIT_MEMORY, HINIT_MEMORY_INPLACE, _CMHIVE::Hive, HIVE_VOLATILE, _CMHIVE::HiveList, _CMHIVE::HiveLock, HSECTOR_SIZE, HvFreeHive(), HvInitializeHive(), NonPagedPool, _CMHIVE::NotifyList, NT_SUCCESS, NTSTATUS(), NULL, Status, and TRUE.

Referenced by CmInitSystem1(), CmpCreateTemporaryHive(), CmpInitHiveFromFile(), CmpInitializeSystemHive(), CmpLoadHiveVolatile(), CmpValidateAlternate(), CmRestoreKey(), EhOpenHive(), and MyCmpInitHiveFromFile().

    00485                    :
    00486
    00487     Initialize a hive.
    00488
    00489 Arguments:
    00490
    00491     CmHive - pointer to a variable to receive a pointer to the CmHive structure
    00492
    00493     OperationType - specifies whether to create a new hive from scratch,
    00494             from a memory image, or by reading a file from disk.
    00495             [HINIT_CREATE | HINIT_MEMORY | HINIT_FILE ]
    00496
    00497     HiveFlags - HIVE_VOLATILE - Entire hive is to be volatile, regardless
    00498                                    of the types of cells allocated
    00499                 HIVE_NO_LAZY_FLUSH - Data in this hive is never written
    00500                                    to disk except by an explicit FlushKey
    00501
    00502     FileType - HFILE_TYPE_*, HFILE_TYPE_LOG or HFILE_TYPE_ALTERNATE set
    00503             up for logging or alternate support respectively.
    00504
    00505     HiveData - if present, supplies a pointer to an in memory image of
    00506             from which to init the hive.  Only useful when OperationType
    00507             is set to HINIT_MEMORY.
    00508
    00509     Primary - File handle for primary hive file (e.g. SYSTEM)
    00510
    00511     Alternate - File handle for alternate hive file (e.g. SYSTEM.ALT)
    00512
    00513     Log - File handle for log hive file (e.g. SOFTWARE.LOG)
    00514
    00515     External - File handle for primary hive file  (e.g.  BACKUP.REG)
    00516
    00517     FileName - some path like "...\system32\config\system", which will
    00518                 be written into the base block as an aid to debugging.
    00519                 may be NULL.
    00520
    00521 Return Value:
    00522
    00523     NTSTATUS
    00524
    00525 --*/
    00526 {
    00527     FILE_FS_SIZE_INFORMATION    FsSizeInformation;
    00528     IO_STATUS_BLOCK             IoStatusBlock;
    00529     ULONG                       Cluster;
    00530     NTSTATUS                    Status;
    00531     PCMHIVE                     cmhive2;
    00532     ULONG                       rc;
    00533
    00534     CMLOG(CML_MAJOR, CMS_INIT) {
    00535         KdPrint(("CmpInitializeHive:\t\n"));
    00536     }
    00537
    00538     //
    00539     // Reject illegal parms
    00540     //
    00541     if ( (Alternate && Log)  ||
    00542          (External && (Primary || Alternate || Log)) ||
    00543          (Alternate && !Primary) ||
    00544          (Log && !Primary) ||
    00545          ((HiveFlags & HIVE_VOLATILE) && (Alternate || Primary || External || Log)) ||
    00546          ((OperationType == HINIT_MEMORY) && (!ARGUMENT_PRESENT(HiveData))) ||
    00547          (Log && (FileType != HFILE_TYPE_LOG)) ||
    00548          (Alternate && (FileType != HFILE_TYPE_ALTERNATE))
    00549        )
    00550     {
    00551         return (STATUS_INVALID_PARAMETER);
    00552     }
    00553
    00554     //
    00555     // compute control
    00556     //
    00557     if (Primary) {
    00558
    00559         ASSERT_PASSIVE_LEVEL();
    00560         Status = ZwQueryVolumeInformationFile(
    00561                     Primary,
    00562                     &IoStatusBlock,
    00563                     &FsSizeInformation,
    00564                     sizeof(FILE_FS_SIZE_INFORMATION),
    00565                     FileFsSizeInformation
    00566                     );
    00567         if (!NT_SUCCESS(Status)) {
    00568             return (Status);
    00569         }
    00570         if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE) {
    00571             return (STATUS_REGISTRY_IO_FAILED);
    00572         }
    00573         Cluster = FsSizeInformation.BytesPerSector / HSECTOR_SIZE;
    00574         Cluster = (Cluster < 1) ? 1 : Cluster;
    00575     } else {
    00576         Cluster = 1;
    00577     }
    00578
    00579     cmhive2 = CmpAllocate(sizeof(CMHIVE), FALSE);
    00580     if (cmhive2 == NULL) {
    00581         return (STATUS_INSUFFICIENT_RESOURCES);
    00582     }
    00583
    00584     //
    00585     // Allocate the mutex from NonPagedPool so it will not be swapped to the disk
    00586     //
    00587     cmhive2->HiveLock = (PFAST_MUTEX)ExAllocatePoolWithTag(NonPagedPool, sizeof(FAST_MUTEX), CM_POOL_TAG );
    00588     if( cmhive2->HiveLock == NULL ) {
    00589         CmpFree(cmhive2, sizeof(CMHIVE));
    00590         return (STATUS_INSUFFICIENT_RESOURCES);
    00591     }
    00592
    00593     //
    00594     // Initialize the Cm hive control block
    00595     //
    00596     //
    00597     ASSERT((HFILE_TYPE_EXTERNAL+1) == HFILE_TYPE_MAX);
    00598     cmhive2->FileHandles[HFILE_TYPE_PRIMARY] = Primary;
    00599     cmhive2->FileHandles[HFILE_TYPE_ALTERNATE] = Alternate;
    00600     cmhive2->FileHandles[HFILE_TYPE_LOG] = Log;
    00601     cmhive2->FileHandles[HFILE_TYPE_EXTERNAL] = External;
    00602
    00603     cmhive2->NotifyList.Flink = NULL;
    00604     cmhive2->NotifyList.Blink = NULL;
    00605
    00606     ExInitializeFastMutex(cmhive2->HiveLock);
    00607
    00608     //
    00609     // Initialize the Hv hive control block
    00610     //
    00611     Status = HvInitializeHive(
    00612                 &(cmhive2->Hive),
    00613                 OperationType,
    00614                 HiveFlags,
    00615                 FileType,
    00616                 HiveData,
    00617                 CmpAllocate,
    00618                 CmpFree,
    00619                 CmpFileSetSize,
    00620                 CmpFileWrite,
    00621                 CmpFileRead,
    00622                 CmpFileFlush,
    00623                 Cluster,
    00624                 FileName
    00625                 );
    00626     if (!NT_SUCCESS(Status)) {
    00627         CMLOG(CML_MAJOR, CMS_INIT_ERROR) {
    00628             KdPrint(("CmpInitializeHive: "));
    00629             KdPrint(("HvInitializeHive failed, Status = %08lx\n", Status));
    00630         }
    00631         ASSERT( cmhive2->HiveLock );
    00632         ExFreePool(cmhive2->HiveLock);
    00633         CmpFree(cmhive2, sizeof(CMHIVE));
    00634         return (Status);
    00635     }
    00636     if ( (OperationType == HINIT_FILE) ||
    00637          (OperationType == HINIT_MEMORY) ||
    00638          (OperationType == HINIT_MEMORY_INPLACE))
    00639     {
    00640         rc = CmCheckRegistry(cmhive2, TRUE);
    00641         if (rc != 0) {
    00642             CMLOG(CML_MAJOR, CMS_INIT_ERROR) {
    00643                 KdPrint(("CmpInitializeHive: "));
    00644                 KdPrint(("CmCheckRegistry failed, rc = %08lx\n",rc));
    00645             }
    00646             //
    00647             // in theory we should do this for MEMORY and MEMORY_INPLACE
    00648             // as well, but they're only used at init time.
    00649             //
    00650             if (OperationType == HINIT_FILE) {
    00651                 HvFreeHive((PHHIVE)cmhive2);
    00652             }
    00653             ASSERT( cmhive2->HiveLock );
    00654             ExFreePool(cmhive2->HiveLock);
    00655             CmpFree(cmhive2, sizeof(CMHIVE));
    00656             return(STATUS_REGISTRY_CORRUPT);
    00657         }
    00658     }
    00659
    00660     InsertHeadList(&CmpHiveListHead, &(cmhive2->HiveList));
    00661     *CmHive = cmhive2;
    00662     return (STATUS_SUCCESS);
    00663 }

NTSTATUS CmpOpenFileWithExtremePrejudice | ( | OUT PHANDLE | Primary,
|  | IN POBJECT_ATTRIBUTES | Obja,
|  | IN ULONG | IoFlags,
|  | IN ULONG | AttributeFlags
| ) |

Definition at line 721 of file cminit.c.

References ASSERT_PASSIVE_LEVEL, Handle, NT_SUCCESS, NTSTATUS(), NULL, Status, ZwCreateFile(), ZwOpenFile(), ZwQueryAttributesFile(), and ZwSetInformationFile().

Referenced by CmpOpenHiveFiles().

    00730                    :
    00731
    00732     This routine opens a hive file that some foolish person has put a
    00733     read-only attribute on. It is used to prevent people from hurting
    00734     themselves by making the critical system hive files read-only.
    00735
    00736 Arguments:
    00737
    00738     Primary - Returns handle to file
    00739
    00740     Obja - Supplies Object Attributes of file.
    00741
    00742     IoFlags - Supplies flags to pass to ZwCreateFile
    00743
    00744 Return Value:
    00745
    00746     NTSTATUS
    00747
    00748 --*/
    00749
    00750 {
    00751     NTSTATUS Status;
    00752     HANDLE Handle;
    00753     IO_STATUS_BLOCK IoStatusBlock;
    00754     FILE_BASIC_INFORMATION FileInfo;
    00755
    00756     //
    00757     // Get the current file attributes
    00758     //
    00759     ASSERT_PASSIVE_LEVEL();
    00760     Status = ZwQueryAttributesFile(Obja, &FileInfo);
    00761     if (!NT_SUCCESS(Status)) {
    00762         return(Status);
    00763     }
    00764
    00765     //
    00766     // Clear the readonly bit.
    00767     //
    00768     FileInfo.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
    00769
    00770     //
    00771     // Open the file
    00772     //
    00773     Status = ZwOpenFile(&Handle,
    00774                         FILE_WRITE_ATTRIBUTES,
    00775                         Obja,
    00776                         &IoStatusBlock,
    00777                         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
    00778                         FILE_OPEN_FOR_BACKUP_INTENT);
    00779     if (!NT_SUCCESS(Status)) {
    00780         return(Status);
    00781     }
    00782
    00783     //
    00784     // Set the new attributes
    00785     //
    00786     Status = ZwSetInformationFile(Handle,
    00787                                   &IoStatusBlock,
    00788                                   &FileInfo,
    00789                                   sizeof(FileInfo),
    00790                                   FileBasicInformation);
    00791     ZwClose(Handle);
    00792     if (NT_SUCCESS(Status)) {
    00793         //
    00794         // Reopen the file with the access that we really need.
    00795         //
    00796         Status = ZwCreateFile(Primary,
    00797                               FILE_READ_DATA | FILE_WRITE_DATA,
    00798                               Obja,
    00799                               &IoStatusBlock,
    00800                               NULL,
    00801                               AttributeFlags,
    00802                               0,
    00803                               FILE_OPEN,
    00804                               IoFlags,
    00805                               NULL,
    00806                               0);
    00807     }
    00808
    00809     return(Status);
    00810
    00811 }
    }

NTSTATUS CmpOpenHiveFiles | ( | PUNICODE_STRING | BaseName,
|  | PWSTR Extension | OPTIONAL,
|  | PHANDLE | Primary,
|  | PHANDLE | Secondary,
|  | PULONG | PrimaryDisposition,
|  | PULONG | SecondaryDisposition,
|  | BOOLEAN | CreateAllowed,
|  | BOOLEAN | MarkAsSystemHive,
|  | OUT OPTIONAL PULONG | ClusterSize
| ) |

Definition at line 46 of file cminit.c.

References ASSERT_PASSIVE_LEVEL, BaseName, CML_BUGCHECK, CMLOG, CmpCreateEvent(), CmpOpenFileWithExtremePrejudice(), CMS_INIT_ERROR, ExAllocatePool, Executive, ExFreePool(), FALSE, HBLOCK_SIZE, HSECTOR_SIZE, KernelMode, KeWaitForSingleObject(), L, NT_SUCCESS, NTSTATUS(), NULL, ObDereferenceObject, ObjectAttributes, PagedPool, RtlAppendStringToString(), RtlInitUnicodeString(), USHORT, WorkName, and ZwCreateFile().

    00059                    :
    00060
    00061     Open/Create Primary, Alternate, and Log files for Hives.
    00062
    00063     BaseName is some name like "\winnt\system32\config\system".
    00064     Extension is ".alt" or ".log" or NULL.
    00065
    00066     If extension is NULL skip secondary work.
    00067
    00068     If extension is .alt or .log, open/create a secondary file
    00069     (e.g. "\winnt\system32\config\system.alt")
    00070
    00071     If extension is .log, open secondary for buffered I/O, else,
    00072     open for non-buffered I/O.  Primary always uses non-buffered I/O.
    00073
    00074     If primary is newly created, supersede secondary.  If secondary
    00075     does not exist, simply create (other code will complain if Log
    00076     is needed but does not exist.)
    00077
    00078     WARNING:    If Secondary handle is NULL, you have no log
    00079                 or alternate!
    00080
    00081 Arguments:
    00082
    00083     BaseName - unicode string of base hive file, must have space for
    00084                 extension if that is used.
    00085
    00086     Extension - unicode type extension of secondary file, including
    00087                 the leading "."
    00088
    00089     Primary - will get handle to primary file
    00090
    00091     Secondary - will get handle to secondary, or NULL
    00092
    00093     PrimaryDisposition - STATUS_SUCCESS or STATUS_CREATED, of primary file.
    00094
    00095     SecondaryDisposition - STATUS_SUCCESS or STATUS_CREATED, of secondary file.
    00096
    00097     CreateAllowed - if TRUE will create nonexistent primary, if FALSE will
    00098                     fail if primary does not exist.  no effect on log
    00099
    00100     MarkAsSystemHive - if TRUE will call into file system to mark this
    00101                        as a critical system hive.
    00102
    00103     ClusterSize - if not NULL, will compute and return the appropriate
    00104         cluster size for the primary file.
    00105
    00106 Return Value:
    00107
    00108     status - if status is success, Primay succeeded, check Secondary
    00109              value to see if it succeeded.
    00110
    00111 --*/
    00112 {
    00113     IO_STATUS_BLOCK     IoStatus;
    00114     IO_STATUS_BLOCK     FsctlIoStatus;
    00115     FILE_FS_SIZE_INFORMATION FsSizeInformation;
    00116     ULONG Cluster;
    00117     ULONG               CreateDisposition;
    00118     OBJECT_ATTRIBUTES   ObjectAttributes;
    00119     NTSTATUS            status;
    00120     UNICODE_STRING      ExtName;
    00121     UNICODE_STRING      WorkName;
    00122     PVOID               WorkBuffer;
    00123     USHORT              NameSize;
    00124     ULONG               IoFlags;
    00125     ULONG               AttributeFlags;
    00126     USHORT              CompressionState;
    00127     HANDLE              hEvent;
    00128     PKEVENT             pEvent;
    00129
    00130     //
    00131     // Allocate an event to use for our overlapped I/O
    00132     //
    00133     status = CmpCreateEvent(NotificationEvent, &hEvent, &pEvent);
    00134     if (!NT_SUCCESS(status)) {
    00135         return(status);
    00136     }
    00137
    00138     //
    00139     // Allocate a buffer big enough to hold the full name
    00140     //
    00141     WorkName.Length = 0;
    00142     WorkName.MaximumLength = 0;
    00143     WorkName.Buffer = NULL;
    00144     WorkBuffer = NULL;
    00145
    00146     NameSize = BaseName->Length;
    00147     if (ARGUMENT_PRESENT(Extension)) {
    00148         NameSize += (wcslen(Extension)+1) * sizeof(WCHAR);
    00149         WorkBuffer = ExAllocatePool(PagedPool, NameSize);
    00150         WorkName.Buffer = WorkBuffer;
    00151         if (WorkBuffer == NULL) {
    00152             ObDereferenceObject(pEvent);
    00153             ZwClose(hEvent);
    00154             return STATUS_NO_MEMORY;
    00155         }
    00156         WorkName.MaximumLength = NameSize;
    00157         RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)BaseName);
    00158     } else {
    00159         WorkName = *BaseName;
    00160     }
    00161
    00162
    00163     //
    00164     // Open/Create the primary
    00165     //
    00166     InitializeObjectAttributes(
    00167         &ObjectAttributes,
    00168         &WorkName,
    00169         OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    00170         NULL,
    00171         NULL
    00172         );
    00173
    00174     if (CreateAllowed) {
    00175         CreateDisposition = FILE_OPEN_IF;
    00176     } else {
    00177         CreateDisposition = FILE_OPEN;
    00178     }
    00179
    00180     ASSERT_PASSIVE_LEVEL();
    00181
    00182     status = ZwCreateFile(
    00183                 Primary,
    00184                 FILE_READ_DATA | FILE_WRITE_DATA,
    00185                 &ObjectAttributes,
    00186                 &IoStatus,
    00187                 NULL,                               // alloc size = none
    00188                 FILE_ATTRIBUTE_NORMAL,
    00189                 0,                                  // share nothing
    00190                 CreateDisposition,
    00191                 FILE_NO_INTERMEDIATE_BUFFERING |
    00192                 FILE_OPEN_FOR_BACKUP_INTENT |
    00193                 FILE_NO_COMPRESSION,
    00194                 NULL,                               // eabuffer
    00195                 0                                   // ealength
    00196                 );
    00197     if (status == STATUS_ACCESS_DENIED) {
    00198
    00199         //
    00200         // This means some foolish person has put a read-only attribute
    00201         // on one of the critical system hive files. Remove it so they
    00202         // don't hurt themselves.
    00203         //
    00204
    00205         status = CmpOpenFileWithExtremePrejudice(Primary,
    00206                                                  &ObjectAttributes,
    00207                                                  FILE_NO_INTERMEDIATE_BUFFERING |
    00208                                                  FILE_OPEN_FOR_BACKUP_INTENT |
    00209                                                  FILE_NO_COMPRESSION,
    00210                                                  FILE_ATTRIBUTE_NORMAL);
    00211     }
    00212
    00213     if ((MarkAsSystemHive) &&
    00214         (NT_SUCCESS(status))) {
    00215
    00216         ASSERT_PASSIVE_LEVEL();
    00217         status = ZwFsControlFile(*Primary,
    00218                                  hEvent,
    00219                                  NULL,
    00220                                  NULL,
    00221                                  &FsctlIoStatus,
    00222                                  FSCTL_MARK_AS_SYSTEM_HIVE,
    00223                                  NULL,
    00224                                  0,
    00225                                  NULL,
    00226                                  0);
    00227         if (status == STATUS_PENDING) {
    00228             KeWaitForSingleObject(pEvent,
    00229                                   Executive,
    00230                                   KernelMode,
    00231                                   FALSE,
    00232                                   NULL);
    00233             status = FsctlIoStatus.Status;
    00234         }
    00235
    00236         //
    00237         //  STATUS_INVALID_DEVICE_REQUEST is OK.
    00238         //
    00239
    00240         if (status == STATUS_INVALID_DEVICE_REQUEST) {
    00241             status = STATUS_SUCCESS;
    00242
    00243         } else if (!NT_SUCCESS(status)) {
    00244             ZwClose(*Primary);
    00245         }
    00246     }
    00247
    00248     if (!NT_SUCCESS(status)) {
    00249         CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
    00250             KdPrint(("CMINIT: CmpOpenHiveFile: "));
    00251             KdPrint(("\tPrimary Open/Create failed for:\n"));
    00252             KdPrint(("\t%wZ\n", &WorkName));
    00253             KdPrint(("\tstatus = %08lx\n", status));
    00254         }
    00255         if (WorkBuffer != NULL) {
    00256             ExFreePool(WorkBuffer);
    00257         }
    00258         ObDereferenceObject(pEvent);
    00259         ZwClose(hEvent);
    00260         return status;
    00261     }
    00262
    00263     //
    00264     // Make sure the file is uncompressed in order to prevent the filesystem
    00265     // from failing our updates due to disk full conditions.
    00266     //
    00267     // Do not fail to open the file if this fails, we don't want to prevent
    00268     // people from booting just because their disk is full. Although they
    00269     // will not be able to update their registry, they will at lease be
    00270     // able to delete some files.
    00271     //
    00272     CompressionState = 0;
    00273     ASSERT_PASSIVE_LEVEL();
    00274     status = ZwFsControlFile(*Primary,
    00275                              hEvent,
    00276                              NULL,
    00277                              NULL,
    00278                              &FsctlIoStatus,
    00279                              FSCTL_SET_COMPRESSION,
    00280                              &CompressionState,
    00281                              sizeof(CompressionState),
    00282                              NULL,
    00283                              0);
    00284     if (status == STATUS_PENDING) {
    00285         KeWaitForSingleObject(pEvent,
    00286                               Executive,
    00287                               KernelMode,
    00288                               FALSE,
    00289                               NULL);
    00290     }
    00291
    00292     *PrimaryDisposition = (ULONG) IoStatus.Information;
    00293
    00294     if (ARGUMENT_PRESENT(ClusterSize)) {
    00295
    00296         ASSERT_PASSIVE_LEVEL();
    00297         status = ZwQueryVolumeInformationFile(*Primary,
    00298                                               &IoStatus,
    00299                                               &FsSizeInformation,
    00300                                               sizeof(FILE_FS_SIZE_INFORMATION),
    00301                                               FileFsSizeInformation);
    00302         if (!NT_SUCCESS(status)) {
    00303             ObDereferenceObject(pEvent);
    00304             ZwClose(hEvent);
    00305             return(status);
    00306         }
    00307         if (FsSizeInformation.BytesPerSector > HBLOCK_SIZE) {
    00308             CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
    00309                 KdPrint(("CmpOpenHiveFiles: sectorsize %lx > HBLOCK_SIZE\n"));
    00310             }
    00311             ObDereferenceObject(pEvent);
    00312             ZwClose(hEvent);
    00313             return(STATUS_CANNOT_LOAD_REGISTRY_FILE);
    00314         }
    00315
    00316         Cluster = FsSizeInformation.BytesPerSector / HSECTOR_SIZE;
    00317         *ClusterSize = (Cluster < 1) ? 1 : Cluster;
    00318
    00319     }
    00320
    00321     if ( ! ARGUMENT_PRESENT(Extension)) {
    00322         if (WorkBuffer != NULL) {
    00323             ExFreePool(WorkBuffer);
    00324         }
    00325         ObDereferenceObject(pEvent);
    00326         ZwClose(hEvent);
    00327         return STATUS_SUCCESS;
    00328     }
    00329
    00330     //
    00331     // Open/Create the secondary
    00332     //
    00333     CreateDisposition = FILE_OPEN_IF;
    00334     if (*PrimaryDisposition == FILE_CREATED) {
    00335         CreateDisposition = FILE_SUPERSEDE;
    00336     }
    00337
    00338     RtlInitUnicodeString(&ExtName,Extension);
    00339     status = RtlAppendStringToString((PSTRING)&WorkName, (PSTRING)&ExtName);
    00340
    00341     InitializeObjectAttributes(&ObjectAttributes,
    00342                                &WorkName,
    00343                                OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    00344                                NULL,
    00345                                NULL);
    00346
    00347     IoFlags = FILE_NO_COMPRESSION;
    00348     if (_wcsnicmp(Extension, L".log", 4) != 0) {
    00349         IoFlags |= FILE_NO_INTERMEDIATE_BUFFERING;
    00350         AttributeFlags = FILE_ATTRIBUTE_NORMAL;
    00351     } else {
    00352         AttributeFlags = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_HIDDEN;
    00353     }
    00354
    00355     ASSERT_PASSIVE_LEVEL();
    00356     status = ZwCreateFile(
    00357                 Secondary,
    00358                 FILE_READ_DATA | FILE_WRITE_DATA,
    00359                 &ObjectAttributes,
    00360                 &IoStatus,
    00361                 NULL,                               // alloc size = none
    00362                 AttributeFlags,
    00363                 0,                                  // share nothing
    00364                 CreateDisposition,
    00365                 IoFlags,
    00366                 NULL,                               // eabuffer
    00367                 0                                   // ealength
    00368                 );
    00369
    00370     if (status == STATUS_ACCESS_DENIED) {
    00371
    00372         //
    00373         // This means some foolish person has put a read-only attribute
    00374         // on one of the critical system hive files. Remove it so they
    00375         // don't hurt themselves.
    00376         //
    00377
    00378         status = CmpOpenFileWithExtremePrejudice(Secondary,
    00379                                                  &ObjectAttributes,
    00380                                                  IoFlags,
    00381                                                  AttributeFlags);
    00382     }
    00383
    00384     if ((MarkAsSystemHive) &&
    00385         (NT_SUCCESS(status))) {
    00386
    00387         ASSERT_PASSIVE_LEVEL();
    00388         status = ZwFsControlFile(*Secondary,
    00389                                  hEvent,
    00390                                  NULL,
    00391                                  NULL,
    00392                                  &FsctlIoStatus,
    00393                                  FSCTL_MARK_AS_SYSTEM_HIVE,
    00394                                  NULL,
    00395                                  0,
    00396                                  NULL,
    00397                                  0);
    00398         if (status == STATUS_PENDING) {
    00399             KeWaitForSingleObject(pEvent,
    00400                                   Executive,
    00401                                   KernelMode,
    00402                                   FALSE,
    00403                                   NULL);
    00404             status = FsctlIoStatus.Status;
    00405         }
    00406         //
    00407         //  STATUS_INVALID_DEVICE_REQUEST is OK.
    00408         //
    00409
    00410         if (status == STATUS_INVALID_DEVICE_REQUEST) {
    00411             status = STATUS_SUCCESS;
    00412
    00413         } else if (!NT_SUCCESS(status)) {
    00414
    00415             ZwClose(*Secondary);
    00416         }
    00417     }
    00418
    00419     if (!NT_SUCCESS(status)) {
    00420         CMLOG(CML_BUGCHECK, CMS_INIT_ERROR) {
    00421             KdPrint(("CMINIT: CmpOpenHiveFile: "));
    00422             KdPrint(("\tSecondary Open/Create failed for:\n"));
    00423             KdPrint(("\t%wZ\n", &WorkName));
    00424             KdPrint(("\tstatus = %08lx\n", status));
    00425         }
    00426         *Secondary = NULL;
    00427     }
    00428
    00429     *SecondaryDisposition = (ULONG) IoStatus.Information;
    00430
    00431     //
    00432     // Make sure the file is uncompressed in order to prevent the filesystem
    00433     // from failing our updates due to disk full conditions.
    00434     //
    00435     // Do not fail to open the file if this fails, we don't want to prevent
    00436     // people from booting just because their disk is full. Although they
    00437     // will not be able to update their registry, they will at lease be
    00438     // able to delete some files.
    00439     //
    00440     CompressionState = 0;
    00441
    00442     ASSERT_PASSIVE_LEVEL();
    00443     status = ZwFsControlFile(*Secondary,
    00444                              hEvent,
    00445                              NULL,
    00446                              NULL,
    00447                              &FsctlIoStatus,
    00448                              FSCTL_SET_COMPRESSION,
    00449                              &CompressionState,
    00450                              sizeof(CompressionState),
    00451                              NULL,
    00452                              0);
    00453     if (status == STATUS_PENDING) {
    00454         KeWaitForSingleObject(pEvent,
    00455                               Executive,
    00456                               KernelMode,
    00457                               FALSE,
    00458                               NULL);
    00459     }
    00460
    00461     if (WorkBuffer != NULL) {
    00462         ExFreePool(WorkBuffer);
    00463     }
    00464     ObDereferenceObject(pEvent);
    00465     ZwClose(hEvent);
    00466     return STATUS_SUCCESS;
    00467 }

## Variable Documentation

LIST_ENTRY CmpHiveListHead

| Definition at line 43 of file cminit.c.

PCMHIVE CmpMasterHive

| Definition at line 42 of file cminit.c.