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.


Generated on Sat May 15 19:43:08 2004 for test by doxygen 1.3.7