Leaked source code of windows server 2003
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.

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