VOID CmGetSystemControlValues( __in PVOID SystemHiveBuffer, __inout PCM_SYSTEM_CONTROL_VECTOR ControlVector ) /*++ Routine Description: Look for registry values in current control set, as specified by entries in ControlVector. Report data for value entries (if any) to variables ControlVector points to. Arguments: SystemHiveBuffer - pointer to flat image of the system hive ControlVector - pointer to structure that describes what values to pull out and store Return Value: NONE. --*/ { NTSTATUS status; PHHIVE SystemHive; HCELL_INDEX RootCell; HCELL_INDEX BaseCell; UNICODE_STRING Name; HCELL_INDEX KeyCell; HCELL_INDEX ValueCell; PCM_KEY_VALUE ValueBody; ULONG Length; BOOLEAN AutoSelect; BOOLEAN small; ULONG tmplength; PCM_KEY_NODE Node; // // set up to read flat system hive image loader passes us // RtlZeroMemory((PVOID)&CmControlHive, sizeof(CmControlHive)); SystemHive = &(CmControlHive.Hive); CmpInitHiveViewList((PCMHIVE)SystemHive); CmpInitSecurityCache((PCMHIVE)SystemHive); status = HvInitializeHive( SystemHive, HINIT_FLAT, HIVE_VOLATILE, HFILE_TYPE_PRIMARY, SystemHiveBuffer, NULL, NULL, NULL, NULL, NULL, NULL, 1, NULL ); if (!NT_SUCCESS(status)) { CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,1,SystemHive,status); } // // don't bother locking/releasing cells // ASSERT( SystemHive->ReleaseCellRoutine == NULL ); // // get hive.cell of root of current control set // RootCell = ((PHBASE_BLOCK)SystemHiveBuffer)->RootCell; RtlInitUnicodeString(&Name, L"current"); BaseCell = CmpFindControlSet( SystemHive, RootCell, &Name, &AutoSelect ); if (BaseCell == HCELL_NIL) { CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,2,SystemHive,&Name); } Node = (PCM_KEY_NODE)HvGetCell(SystemHive,BaseCell); if( Node == NULL ) { // // we couldn't map a view for the bin containing this cell // return; } RtlInitUnicodeString(&Name, L"control"); BaseCell = CmpFindSubKeyByName(SystemHive, Node, &Name); if (BaseCell == HCELL_NIL) { CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,3,Node,&Name); } // // SystemHive.BaseCell = \registry\machine\system\currentcontrolset\control // // // step through vector, trying to fetch each value // while (ControlVector->KeyPath != NULL) { // // Assume we will fail to find the key or value. // Length = (ULONG)-1; KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath); if (KeyCell != HCELL_NIL) { // // found the key, look for the value entry // Node = (PCM_KEY_NODE)HvGetCell(SystemHive,KeyCell); if( Node == NULL ) { // // we couldn't map a view for the bin containing this cell // return; } RtlInitUnicodeString(&Name, ControlVector->ValueName); ValueCell = CmpFindValueByName(SystemHive, Node, &Name); if (ValueCell != HCELL_NIL) { // // SystemHive.ValueCell is value entry body // if (ControlVector->BufferLength == NULL) { tmplength = sizeof(ULONG); } else { tmplength = *(ControlVector->BufferLength); } ValueBody = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell); if( ValueBody == NULL ) { // // we couldn't map a view for the bin containing this cell // return; } small = CmpIsHKeyValueSmall(Length, ValueBody->DataLength); if (tmplength < Length) { Length = tmplength; } if (Length > 0) { PCELL_DATA Buffer; BOOLEAN BufferAllocated; ULONG realsize; HCELL_INDEX CellToRelease; ASSERT((small ? (Length <= CM_KEY_VALUE_SMALL) : TRUE)); // // get the data from source, regardless of the size // if( CmpGetValueData(SystemHive,ValueBody,&realsize,&Buffer,&BufferAllocated,&CellToRelease) == FALSE ) { // // insufficient resources; return NULL // ASSERT( BufferAllocated == FALSE ); ASSERT( Buffer == NULL ); return; } RtlCopyMemory( ControlVector->Buffer, Buffer, Length ); // // cleanup the temporary buffer // if( BufferAllocated == TRUE ) { ExFreePool( Buffer ); } if( CellToRelease != HCELL_NIL ) { HvReleaseCell(SystemHive,CellToRelease); } } if (ControlVector->Type != NULL) { *(ControlVector->Type) = ValueBody->Type; } } } // // Stash the length of result (-1 if nothing was found) // if (ControlVector->BufferLength != NULL) { *(ControlVector->BufferLength) = Length; } ControlVector++; } // // Get the default locale ID for the system from the registry. // if (CmDefaultLanguageIdType == REG_SZ) { PsDefaultSystemLocaleId = (LCID) CmpConvertLangId( CmDefaultLanguageId, CmDefaultLanguageIdLength); } else { PsDefaultSystemLocaleId = 0x00000409; } // // Get the install (native UI) language ID for the system from the registry. // if (CmInstallUILanguageIdType == REG_SZ) { PsInstallUILanguageId = CmpConvertLangId( CmInstallUILanguageId, CmInstallUILanguageIdLength); } else { PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId); } // // Set the default thread locale to the default system locale // for now. This will get changed as soon as somebody logs in. // Use the install (native) language id as our default UI language id. // This also will get changed as soon as somebody logs in. // PsDefaultThreadLocaleId = PsDefaultSystemLocaleId; PsDefaultUILanguageId = PsInstallUILanguageId; }
NTSTATUS BiOpenKey( _In_ HANDLE ParentHandle, _In_ PWCHAR KeyName, _Out_ PHANDLE Handle ) { PBI_KEY_OBJECT ParentKey, NewKey; PBI_KEY_HIVE ParentHive; NTSTATUS Status; ULONG NameLength, SubNameLength, NameBytes; PWCHAR NameStart, NameBuffer; UNICODE_STRING KeyString; HCELL_INDEX KeyCell; PHHIVE Hive; PCM_KEY_NODE ParentNode; /* Convert from a handle to our key object */ ParentKey = (PBI_KEY_OBJECT)ParentHandle; /* Extract the hive and node information */ ParentHive = ParentKey->KeyHive; ParentNode = ParentKey->KeyNode; Hive = &ParentKey->KeyHive->Hive.Hive; /* Initialize variables */ KeyCell = HCELL_NIL; Status = STATUS_SUCCESS; NameBuffer = NULL; /* Loop as long as there's still portions of the key name in play */ NameLength = wcslen(KeyName); while (NameLength) { /* Find the first path separator */ NameStart = wcschr(KeyName, OBJ_NAME_PATH_SEPARATOR); if (NameStart) { /* Look only at the key before the separator */ SubNameLength = NameStart - KeyName; ++NameStart; } else { /* No path separator, this is the final leaf key */ SubNameLength = NameLength; } /* Free the name buffer from the previous pass if needed */ if (NameBuffer) { BlMmFreeHeap(NameBuffer); } /* Allocate a buffer to hold the name of this specific subkey only */ NameBytes = SubNameLength * sizeof(WCHAR); NameBuffer = BlMmAllocateHeap(NameBytes + sizeof(UNICODE_NULL)); if (!NameBuffer) { Status = STATUS_NO_MEMORY; goto Quickie; } /* Copy and null-terminate the name of the subkey */ RtlCopyMemory(NameBuffer, KeyName, NameBytes); NameBuffer[SubNameLength] = UNICODE_NULL; /* Convert it into a UNICODE_STRING and try to find it */ RtlInitUnicodeString(&KeyString, NameBuffer); KeyCell = CmpFindSubKeyByName(Hive, ParentNode, &KeyString); if (KeyCell == HCELL_NIL) { Status = STATUS_OBJECT_NAME_NOT_FOUND; goto Quickie; } /* We found it -- get the key node out of it */ ParentNode = (PCM_KEY_NODE)HvGetCell(Hive, KeyCell); if (!ParentNode) { Status = STATUS_REGISTRY_CORRUPT; goto Quickie; } /* Update the key name to the next remaining path element */ KeyName = NameStart; if (NameStart) { /* Update the length to the remainder of the path */ NameLength += -1 - SubNameLength; } else { /* There's nothing left, this was the leaf key */ NameLength = 0; } } /* Allocate a key object */ NewKey = BlMmAllocateHeap(sizeof(*NewKey)); if (!NewKey) { /* Bail out if we had no memory for it */ Status = STATUS_NO_MEMORY; goto Quickie; } /* Fill out the key object data */ NewKey->KeyNode = ParentNode; NewKey->KeyHive = ParentHive; NewKey->KeyName = NameBuffer; NewKey->KeyCell = KeyCell; /* Add a reference to the hive */ ++ParentHive->ReferenceCount; /* Return the object back to the caller */ *Handle = NewKey; Quickie: /* If we had a name buffer, free it */ if (NameBuffer) { BlMmFreeHeap(NameBuffer); } /* Return status of the open operation */ return Status; }
HCELL_INDEX CmpWalkPath( PHHIVE SystemHive, HCELL_INDEX ParentCell, PWSTR Path ) /*++ Routine Description: Walk the path. Arguments: SystemHive - hive ParentCell - where to start Path - string to walk Return Value: HCELL_INDEX of found key cell, or HCELL_NIL for error --*/ { UNICODE_STRING PathString; UNICODE_STRING NextName; BOOLEAN Last; HCELL_INDEX KeyCell; PCM_KEY_NODE Node; // // don't bother counting/releasing used cells // ASSERT( SystemHive->ReleaseCellRoutine == NULL ); KeyCell = ParentCell; RtlInitUnicodeString(&PathString, Path); while (TRUE) { CmpGetNextName(&PathString, &NextName, &Last); if (NextName.Length == 0) { return KeyCell; } Node = (PCM_KEY_NODE)HvGetCell(SystemHive,KeyCell); if( Node == NULL ) { // // we couldn't map a view for the bin containing this cell // return HCELL_NIL; } KeyCell = CmpFindSubKeyByName(SystemHive, Node, &NextName); if (KeyCell == HCELL_NIL) { return HCELL_NIL; } } }