|
|
/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
cmcontrl.c
Abstract:
The module contains CmGetSystemControlValues, see cmdat.c for data.
Author:
Bryan M. Willman (bryanwi) 12-May-92
Revision History:
--*/
#include "cmp.h"
extern WCHAR CmDefaultLanguageId[]; extern ULONG CmDefaultLanguageIdLength; extern ULONG CmDefaultLanguageIdType;
extern WCHAR CmInstallUILanguageId[]; extern ULONG CmInstallUILanguageIdLength; extern ULONG CmInstallUILanguageIdType;
HCELL_INDEX CmpWalkPath( PHHIVE SystemHive, HCELL_INDEX ParentCell, PWSTR Path );
LANGID CmpConvertLangId( PWSTR LangIdString, ULONG LangIdStringLength );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,CmGetSystemControlValues)
#pragma alloc_text(INIT,CmpWalkPath)
#pragma alloc_text(INIT,CmpConvertLangId)
#endif
VOID CmGetSystemControlValues( PVOID SystemHiveBuffer, 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; CMHIVE TempHive; HCELL_INDEX RootCell; HCELL_INDEX BaseCell; UNICODE_STRING Name; PHCELL_INDEX Index; HCELL_INDEX KeyCell; HCELL_INDEX ValueCell; PCM_KEY_VALUE ValueBody; PVOID ValueData; 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)&TempHive, sizeof(TempHive)); SystemHive = &(TempHive.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; }
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
--*/ { NTSTATUS status; UNICODE_STRING PathString; UNICODE_STRING NextName; BOOLEAN Last; PHCELL_INDEX Index; 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; } } }
LANGID CmpConvertLangId( PWSTR LangIdString, ULONG LangIdStringLength ) {
USHORT i, Digit; WCHAR c; LANGID LangId;
LangId = 0; LangIdStringLength = LangIdStringLength / sizeof( WCHAR ); for (i=0; i < LangIdStringLength; i++) { c = LangIdString[ i ];
if (c >= L'0' && c <= L'9') { Digit = c - L'0';
} else if (c >= L'A' && c <= L'F') { Digit = c - L'A' + 10;
} else if (c >= L'a' && c <= L'f') { Digit = c - L'a' + 10;
} else { break; }
if (Digit >= 16) { break; }
LangId = (LangId << 4) | Digit; }
return LangId; }
|