Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

408 lines
10 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. cmcontrl.c
  5. Abstract:
  6. The module contains CmGetSystemControlValues, see cmdat.c for data.
  7. Author:
  8. Bryan M. Willman (bryanwi) 12-May-92
  9. Revision History:
  10. --*/
  11. #include "cmp.h"
  12. extern WCHAR CmDefaultLanguageId[];
  13. extern ULONG CmDefaultLanguageIdLength;
  14. extern ULONG CmDefaultLanguageIdType;
  15. extern WCHAR CmInstallUILanguageId[];
  16. extern ULONG CmInstallUILanguageIdLength;
  17. extern ULONG CmInstallUILanguageIdType;
  18. HCELL_INDEX
  19. CmpWalkPath(
  20. PHHIVE SystemHive,
  21. HCELL_INDEX ParentCell,
  22. PWSTR Path
  23. );
  24. LANGID
  25. CmpConvertLangId(
  26. PWSTR LangIdString,
  27. ULONG LangIdStringLength
  28. );
  29. #ifdef ALLOC_PRAGMA
  30. #pragma alloc_text(INIT,CmGetSystemControlValues)
  31. #pragma alloc_text(INIT,CmpWalkPath)
  32. #pragma alloc_text(INIT,CmpConvertLangId)
  33. #endif
  34. VOID
  35. CmGetSystemControlValues(
  36. PVOID SystemHiveBuffer,
  37. PCM_SYSTEM_CONTROL_VECTOR ControlVector
  38. )
  39. /*++
  40. Routine Description:
  41. Look for registry values in current control set, as specified
  42. by entries in ControlVector. Report data for value entries
  43. (if any) to variables ControlVector points to.
  44. Arguments:
  45. SystemHiveBuffer - pointer to flat image of the system hive
  46. ControlVector - pointer to structure that describes what values
  47. to pull out and store
  48. Return Value:
  49. NONE.
  50. --*/
  51. {
  52. NTSTATUS status;
  53. PHHIVE SystemHive;
  54. CMHIVE TempHive;
  55. HCELL_INDEX RootCell;
  56. HCELL_INDEX BaseCell;
  57. UNICODE_STRING Name;
  58. PHCELL_INDEX Index;
  59. HCELL_INDEX KeyCell;
  60. HCELL_INDEX ValueCell;
  61. PCM_KEY_VALUE ValueBody;
  62. PVOID ValueData;
  63. ULONG Length;
  64. BOOLEAN AutoSelect;
  65. BOOLEAN small;
  66. ULONG tmplength;
  67. PCM_KEY_NODE Node;
  68. //
  69. // set up to read flat system hive image loader passes us
  70. //
  71. RtlZeroMemory((PVOID)&TempHive, sizeof(TempHive));
  72. SystemHive = &(TempHive.Hive);
  73. CmpInitHiveViewList((PCMHIVE)SystemHive);
  74. CmpInitSecurityCache((PCMHIVE)SystemHive);
  75. status = HvInitializeHive(
  76. SystemHive,
  77. HINIT_FLAT,
  78. HIVE_VOLATILE,
  79. HFILE_TYPE_PRIMARY,
  80. SystemHiveBuffer,
  81. NULL,
  82. NULL,
  83. NULL,
  84. NULL,
  85. NULL,
  86. NULL,
  87. 1,
  88. NULL
  89. );
  90. if (!NT_SUCCESS(status)) {
  91. CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,1,SystemHive,status);
  92. }
  93. //
  94. // don't bother locking/releasing cells
  95. //
  96. ASSERT( SystemHive->ReleaseCellRoutine == NULL );
  97. //
  98. // get hive.cell of root of current control set
  99. //
  100. RootCell = ((PHBASE_BLOCK)SystemHiveBuffer)->RootCell;
  101. RtlInitUnicodeString(&Name, L"current");
  102. BaseCell = CmpFindControlSet(
  103. SystemHive,
  104. RootCell,
  105. &Name,
  106. &AutoSelect
  107. );
  108. if (BaseCell == HCELL_NIL) {
  109. CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,2,SystemHive,&Name);
  110. }
  111. Node = (PCM_KEY_NODE)HvGetCell(SystemHive,BaseCell);
  112. if( Node == NULL ) {
  113. //
  114. // we couldn't map a view for the bin containing this cell
  115. //
  116. return;
  117. }
  118. RtlInitUnicodeString(&Name, L"control");
  119. BaseCell = CmpFindSubKeyByName(SystemHive,
  120. Node,
  121. &Name);
  122. if (BaseCell == HCELL_NIL) {
  123. CM_BUGCHECK(BAD_SYSTEM_CONFIG_INFO,BAD_SYSTEM_CONTROL_VALUES,3,Node,&Name);
  124. }
  125. //
  126. // SystemHive.BaseCell = \registry\machine\system\currentcontrolset\control
  127. //
  128. //
  129. // step through vector, trying to fetch each value
  130. //
  131. while (ControlVector->KeyPath != NULL) {
  132. //
  133. // Assume we will fail to find the key or value.
  134. //
  135. Length = (ULONG)-1;
  136. KeyCell = CmpWalkPath(SystemHive, BaseCell, ControlVector->KeyPath);
  137. if (KeyCell != HCELL_NIL) {
  138. //
  139. // found the key, look for the value entry
  140. //
  141. Node = (PCM_KEY_NODE)HvGetCell(SystemHive,KeyCell);
  142. if( Node == NULL ) {
  143. //
  144. // we couldn't map a view for the bin containing this cell
  145. //
  146. return;
  147. }
  148. RtlInitUnicodeString(&Name, ControlVector->ValueName);
  149. ValueCell = CmpFindValueByName(SystemHive,
  150. Node,
  151. &Name);
  152. if (ValueCell != HCELL_NIL) {
  153. //
  154. // SystemHive.ValueCell is value entry body
  155. //
  156. if (ControlVector->BufferLength == NULL) {
  157. tmplength = sizeof(ULONG);
  158. } else {
  159. tmplength = *(ControlVector->BufferLength);
  160. }
  161. ValueBody = (PCM_KEY_VALUE)HvGetCell(SystemHive, ValueCell);
  162. if( ValueBody == NULL ) {
  163. //
  164. // we couldn't map a view for the bin containing this cell
  165. //
  166. return;
  167. }
  168. small = CmpIsHKeyValueSmall(Length, ValueBody->DataLength);
  169. if (tmplength < Length) {
  170. Length = tmplength;
  171. }
  172. if (Length > 0) {
  173. PCELL_DATA Buffer;
  174. BOOLEAN BufferAllocated;
  175. ULONG realsize;
  176. HCELL_INDEX CellToRelease;
  177. ASSERT((small ? (Length <= CM_KEY_VALUE_SMALL) : TRUE));
  178. //
  179. // get the data from source, regardless of the size
  180. //
  181. if( CmpGetValueData(SystemHive,ValueBody,&realsize,&Buffer,&BufferAllocated,&CellToRelease) == FALSE ) {
  182. //
  183. // insufficient resources; return NULL
  184. //
  185. ASSERT( BufferAllocated == FALSE );
  186. ASSERT( Buffer == NULL );
  187. return;
  188. }
  189. RtlCopyMemory(
  190. ControlVector->Buffer,
  191. Buffer,
  192. Length
  193. );
  194. //
  195. // cleanup the temporary buffer
  196. //
  197. if( BufferAllocated == TRUE ) {
  198. ExFreePool( Buffer );
  199. }
  200. if( CellToRelease != HCELL_NIL ) {
  201. HvReleaseCell(SystemHive,CellToRelease);
  202. }
  203. }
  204. if (ControlVector->Type != NULL) {
  205. *(ControlVector->Type) = ValueBody->Type;
  206. }
  207. }
  208. }
  209. //
  210. // Stash the length of result (-1 if nothing was found)
  211. //
  212. if (ControlVector->BufferLength != NULL) {
  213. *(ControlVector->BufferLength) = Length;
  214. }
  215. ControlVector++;
  216. }
  217. //
  218. // Get the default locale ID for the system from the registry.
  219. //
  220. if (CmDefaultLanguageIdType == REG_SZ) {
  221. PsDefaultSystemLocaleId = (LCID) CmpConvertLangId(
  222. CmDefaultLanguageId,
  223. CmDefaultLanguageIdLength);
  224. } else {
  225. PsDefaultSystemLocaleId = 0x00000409;
  226. }
  227. //
  228. // Get the install (native UI) language ID for the system from the registry.
  229. //
  230. if (CmInstallUILanguageIdType == REG_SZ) {
  231. PsInstallUILanguageId = CmpConvertLangId(
  232. CmInstallUILanguageId,
  233. CmInstallUILanguageIdLength);
  234. } else {
  235. PsInstallUILanguageId = LANGIDFROMLCID(PsDefaultSystemLocaleId);
  236. }
  237. //
  238. // Set the default thread locale to the default system locale
  239. // for now. This will get changed as soon as somebody logs in.
  240. // Use the install (native) language id as our default UI language id.
  241. // This also will get changed as soon as somebody logs in.
  242. //
  243. PsDefaultThreadLocaleId = PsDefaultSystemLocaleId;
  244. PsDefaultUILanguageId = PsInstallUILanguageId;
  245. }
  246. HCELL_INDEX
  247. CmpWalkPath(
  248. PHHIVE SystemHive,
  249. HCELL_INDEX ParentCell,
  250. PWSTR Path
  251. )
  252. /*++
  253. Routine Description:
  254. Walk the path.
  255. Arguments:
  256. SystemHive - hive
  257. ParentCell - where to start
  258. Path - string to walk
  259. Return Value:
  260. HCELL_INDEX of found key cell, or HCELL_NIL for error
  261. --*/
  262. {
  263. NTSTATUS status;
  264. UNICODE_STRING PathString;
  265. UNICODE_STRING NextName;
  266. BOOLEAN Last;
  267. PHCELL_INDEX Index;
  268. HCELL_INDEX KeyCell;
  269. PCM_KEY_NODE Node;
  270. //
  271. // don't bother counting/releasing used cells
  272. //
  273. ASSERT( SystemHive->ReleaseCellRoutine == NULL );
  274. KeyCell = ParentCell;
  275. RtlInitUnicodeString(&PathString, Path);
  276. while (TRUE) {
  277. CmpGetNextName(&PathString, &NextName, &Last);
  278. if (NextName.Length == 0) {
  279. return KeyCell;
  280. }
  281. Node = (PCM_KEY_NODE)HvGetCell(SystemHive,KeyCell);
  282. if( Node == NULL ) {
  283. //
  284. // we couldn't map a view for the bin containing this cell
  285. //
  286. return HCELL_NIL;
  287. }
  288. KeyCell = CmpFindSubKeyByName(SystemHive,
  289. Node,
  290. &NextName);
  291. if (KeyCell == HCELL_NIL) {
  292. return HCELL_NIL;
  293. }
  294. }
  295. }
  296. LANGID
  297. CmpConvertLangId(
  298. PWSTR LangIdString,
  299. ULONG LangIdStringLength
  300. )
  301. {
  302. USHORT i, Digit;
  303. WCHAR c;
  304. LANGID LangId;
  305. LangId = 0;
  306. LangIdStringLength = LangIdStringLength / sizeof( WCHAR );
  307. for (i=0; i < LangIdStringLength; i++) {
  308. c = LangIdString[ i ];
  309. if (c >= L'0' && c <= L'9') {
  310. Digit = c - L'0';
  311. } else if (c >= L'A' && c <= L'F') {
  312. Digit = c - L'A' + 10;
  313. } else if (c >= L'a' && c <= L'f') {
  314. Digit = c - L'a' + 10;
  315. } else {
  316. break;
  317. }
  318. if (Digit >= 16) {
  319. break;
  320. }
  321. LangId = (LangId << 4) | Digit;
  322. }
  323. return LangId;
  324. }