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.

979 lines
25 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. registry.c
  5. Abstract:
  6. This file contains functions to read and _rite values
  7. to the registry.
  8. Author:
  9. Jerry Shea (JerrySh) 30-Sep-1994
  10. Revision History:
  11. --*/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. #include <shlwapi.h>
  15. #define CONSOLE_REGISTRY_CURRENTPAGE (L"CurrentPage")
  16. extern BOOL g_fAutoComplete;
  17. extern BOOL g_fSaveAutoCompleteState;
  18. NTSTATUS
  19. MyRegOpenKey(
  20. IN HANDLE hKey,
  21. IN LPWSTR lpSubKey,
  22. OUT PHANDLE phResult
  23. )
  24. {
  25. OBJECT_ATTRIBUTES Obja;
  26. UNICODE_STRING SubKey;
  27. //
  28. // Convert the subkey to a counted Unicode string.
  29. //
  30. RtlInitUnicodeString( &SubKey, lpSubKey );
  31. //
  32. // Initialize the OBJECT_ATTRIBUTES structure and open the key.
  33. //
  34. InitializeObjectAttributes(
  35. &Obja,
  36. &SubKey,
  37. OBJ_CASE_INSENSITIVE,
  38. hKey,
  39. NULL
  40. );
  41. return NtOpenKey(
  42. phResult,
  43. KEY_READ,
  44. &Obja
  45. );
  46. }
  47. NTSTATUS
  48. MyRegDeleteKey(
  49. IN HANDLE hKey,
  50. IN LPWSTR lpSubKey
  51. )
  52. {
  53. UNICODE_STRING SubKey;
  54. //
  55. // Convert the subkey to a counted Unicode string.
  56. //
  57. RtlInitUnicodeString( &SubKey, lpSubKey );
  58. //
  59. // Delete the subkey
  60. //
  61. return NtDeleteValueKey(
  62. hKey,
  63. &SubKey
  64. );
  65. }
  66. NTSTATUS
  67. MyRegCreateKey(
  68. IN HANDLE hKey,
  69. IN LPWSTR lpSubKey,
  70. OUT PHANDLE phResult
  71. )
  72. {
  73. OBJECT_ATTRIBUTES Obja;
  74. UNICODE_STRING SubKey;
  75. //
  76. // Convert the subkey to a counted Unicode string.
  77. //
  78. RtlInitUnicodeString( &SubKey, lpSubKey );
  79. //
  80. // Initialize the OBJECT_ATTRIBUTES structure and open the key.
  81. //
  82. InitializeObjectAttributes(
  83. &Obja,
  84. &SubKey,
  85. OBJ_CASE_INSENSITIVE,
  86. hKey,
  87. NULL
  88. );
  89. return NtCreateKey(
  90. phResult,
  91. KEY_READ | KEY_WRITE,
  92. &Obja,
  93. 0,
  94. NULL,
  95. 0,
  96. NULL
  97. );
  98. }
  99. NTSTATUS
  100. MyRegQueryValue(
  101. IN HANDLE hKey,
  102. IN LPWSTR lpValueName,
  103. IN DWORD dwValueLength,
  104. OUT LPBYTE lpData
  105. )
  106. {
  107. UNICODE_STRING ValueName;
  108. ULONG BufferLength;
  109. ULONG ResultLength;
  110. PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation;
  111. NTSTATUS Status;
  112. //
  113. // Convert the subkey to a counted Unicode string.
  114. //
  115. RtlInitUnicodeString( &ValueName, lpValueName );
  116. BufferLength = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + dwValueLength;
  117. KeyValueInformation = HeapAlloc(RtlProcessHeap(),0,BufferLength);
  118. if (KeyValueInformation == NULL)
  119. return STATUS_NO_MEMORY;
  120. Status = NtQueryValueKey(
  121. hKey,
  122. &ValueName,
  123. KeyValuePartialInformation,
  124. KeyValueInformation,
  125. BufferLength,
  126. &ResultLength
  127. );
  128. if (NT_SUCCESS(Status)) {
  129. ASSERT(KeyValueInformation->DataLength <= dwValueLength);
  130. RtlCopyMemory(lpData,
  131. KeyValueInformation->Data,
  132. KeyValueInformation->DataLength);
  133. if (KeyValueInformation->Type == REG_SZ) {
  134. if (KeyValueInformation->DataLength + sizeof(WCHAR) > dwValueLength) {
  135. KeyValueInformation->DataLength -= sizeof(WCHAR);
  136. }
  137. lpData[KeyValueInformation->DataLength++] = 0;
  138. lpData[KeyValueInformation->DataLength] = 0;
  139. }
  140. }
  141. HeapFree(RtlProcessHeap(),0,KeyValueInformation);
  142. return Status;
  143. }
  144. #if defined(FE_SB)
  145. NTSTATUS
  146. MyRegEnumValue(
  147. IN HANDLE hKey,
  148. IN DWORD dwIndex,
  149. OUT DWORD dwValueLength,
  150. OUT LPWSTR lpValueName,
  151. OUT DWORD dwDataLength,
  152. OUT LPBYTE lpData
  153. )
  154. {
  155. ULONG BufferLength;
  156. ULONG ResultLength;
  157. PKEY_VALUE_FULL_INFORMATION KeyValueInformation;
  158. NTSTATUS Status;
  159. //
  160. // Convert the subkey to a counted Unicode string.
  161. //
  162. BufferLength = sizeof(KEY_VALUE_FULL_INFORMATION) + dwValueLength + dwDataLength;
  163. KeyValueInformation = LocalAlloc(LPTR,BufferLength);
  164. if (KeyValueInformation == NULL)
  165. return STATUS_NO_MEMORY;
  166. Status = NtEnumerateValueKey(
  167. hKey,
  168. dwIndex,
  169. KeyValueFullInformation,
  170. KeyValueInformation,
  171. BufferLength,
  172. &ResultLength
  173. );
  174. if (NT_SUCCESS(Status)) {
  175. ASSERT(KeyValueInformation->NameLength <= dwValueLength);
  176. RtlMoveMemory(lpValueName,
  177. KeyValueInformation->Name,
  178. KeyValueInformation->NameLength);
  179. lpValueName[ KeyValueInformation->NameLength >> 1 ] = UNICODE_NULL;
  180. ASSERT(KeyValueInformation->DataLength <= dwDataLength);
  181. RtlMoveMemory(lpData,
  182. (PBYTE)KeyValueInformation + KeyValueInformation->DataOffset,
  183. KeyValueInformation->DataLength);
  184. if (KeyValueInformation->Type == REG_SZ ||
  185. KeyValueInformation->Type ==REG_MULTI_SZ
  186. ) {
  187. if (KeyValueInformation->DataLength + sizeof(WCHAR) > dwDataLength) {
  188. KeyValueInformation->DataLength -= sizeof(WCHAR);
  189. }
  190. lpData[KeyValueInformation->DataLength++] = 0;
  191. lpData[KeyValueInformation->DataLength] = 0;
  192. }
  193. }
  194. LocalFree(KeyValueInformation);
  195. return Status;
  196. }
  197. #endif
  198. LPWSTR
  199. TranslateConsoleTitle(
  200. LPWSTR ConsoleTitle
  201. )
  202. /*++
  203. this routine translates path characters into '_' characters because
  204. the NT registry apis do not allow the creation of keys with
  205. names that contain path characters. it allocates a buffer that
  206. must be freed.
  207. --*/
  208. {
  209. int ConsoleTitleLength, i;
  210. LPWSTR TranslatedTitle;
  211. ConsoleTitleLength = lstrlenW(ConsoleTitle) + 1;
  212. TranslatedTitle = HeapAlloc(RtlProcessHeap(), 0,
  213. ConsoleTitleLength * sizeof(WCHAR));
  214. if (TranslatedTitle == NULL) {
  215. return NULL;
  216. }
  217. for (i = 0; i < ConsoleTitleLength; i++) {
  218. if (ConsoleTitle[i] == '\\') {
  219. TranslatedTitle[i] = (WCHAR)'_';
  220. } else {
  221. TranslatedTitle[i] = ConsoleTitle[i];
  222. }
  223. }
  224. return TranslatedTitle;
  225. }
  226. NTSTATUS
  227. MyRegSetValue(
  228. IN HANDLE hKey,
  229. IN LPWSTR lpValueName,
  230. IN DWORD dwType,
  231. IN LPVOID lpData,
  232. IN DWORD cbData
  233. )
  234. {
  235. UNICODE_STRING ValueName;
  236. //
  237. // Convert the subkey to a counted Unicode string.
  238. //
  239. RtlInitUnicodeString( &ValueName, lpValueName );
  240. return NtSetValueKey(
  241. hKey,
  242. &ValueName,
  243. 0,
  244. dwType,
  245. lpData,
  246. cbData
  247. );
  248. }
  249. NTSTATUS
  250. MyRegUpdateValue(
  251. IN HANDLE hConsoleKey,
  252. IN HANDLE hKey,
  253. IN LPWSTR lpValueName,
  254. IN DWORD dwType,
  255. IN LPVOID lpData,
  256. IN DWORD cbData
  257. )
  258. {
  259. NTSTATUS Status;
  260. BYTE Data[MAX_PATH];
  261. //
  262. // If this is not the main console key but the value is the same,
  263. // delete it. Otherwise, set it.
  264. //
  265. if (hConsoleKey != hKey) {
  266. Status = MyRegQueryValue(hConsoleKey, lpValueName, sizeof(Data), Data);
  267. if (NT_SUCCESS(Status)) {
  268. if (RtlCompareMemory(lpData, Data, cbData) == cbData) {
  269. return MyRegDeleteKey(hKey, lpValueName);
  270. }
  271. }
  272. }
  273. return MyRegSetValue(hKey, lpValueName, dwType, lpData, cbData);
  274. }
  275. PCONSOLE_STATE_INFO
  276. InitRegistryValues(VOID)
  277. /*++
  278. Routine Description:
  279. This routine allocates a state info structure and fill it in with
  280. default values.
  281. Arguments:
  282. none
  283. Return Value:
  284. pStateInfo - pointer to structure to receive information
  285. --*/
  286. {
  287. PCONSOLE_STATE_INFO pStateInfo;
  288. pStateInfo = HeapAlloc(RtlProcessHeap(), 0, sizeof(CONSOLE_STATE_INFO));
  289. if (pStateInfo == NULL) {
  290. return NULL;
  291. }
  292. pStateInfo->Length = sizeof(CONSOLE_STATE_INFO);
  293. pStateInfo->ScreenAttributes = 0x07; // white on black
  294. pStateInfo->PopupAttributes = 0xf5; // purple on white
  295. pStateInfo->InsertMode = FALSE;
  296. pStateInfo->QuickEdit = FALSE;
  297. pStateInfo->FullScreen = FALSE;
  298. pStateInfo->ScreenBufferSize.X = 80;
  299. pStateInfo->ScreenBufferSize.Y = 25;
  300. pStateInfo->WindowSize.X = 80;
  301. pStateInfo->WindowSize.Y = 25;
  302. pStateInfo->WindowPosX = 0;
  303. pStateInfo->WindowPosY = 0;
  304. pStateInfo->AutoPosition = TRUE;
  305. pStateInfo->FontSize.X = 0;
  306. pStateInfo->FontSize.Y = 0;
  307. pStateInfo->FontFamily = 0;
  308. pStateInfo->FontWeight = 0;
  309. pStateInfo->FaceName[0] = TEXT('\0');
  310. pStateInfo->CursorSize = 25;
  311. pStateInfo->HistoryBufferSize = 25;
  312. pStateInfo->NumberOfHistoryBuffers = 4;
  313. pStateInfo->HistoryNoDup = 0;
  314. pStateInfo->ColorTable[ 0] = RGB(0, 0, 0 );
  315. pStateInfo->ColorTable[ 1] = RGB(0, 0, 0x80);
  316. pStateInfo->ColorTable[ 2] = RGB(0, 0x80,0 );
  317. pStateInfo->ColorTable[ 3] = RGB(0, 0x80,0x80);
  318. pStateInfo->ColorTable[ 4] = RGB(0x80,0, 0 );
  319. pStateInfo->ColorTable[ 5] = RGB(0x80,0, 0x80);
  320. pStateInfo->ColorTable[ 6] = RGB(0x80,0x80,0 );
  321. pStateInfo->ColorTable[ 7] = RGB(0xC0,0xC0,0xC0);
  322. pStateInfo->ColorTable[ 8] = RGB(0x80,0x80,0x80);
  323. pStateInfo->ColorTable[ 9] = RGB(0, 0, 0xFF);
  324. pStateInfo->ColorTable[10] = RGB(0, 0xFF,0 );
  325. pStateInfo->ColorTable[11] = RGB(0, 0xFF,0xFF);
  326. pStateInfo->ColorTable[12] = RGB(0xFF,0, 0 );
  327. pStateInfo->ColorTable[13] = RGB(0xFF,0, 0xFF);
  328. pStateInfo->ColorTable[14] = RGB(0xFF,0xFF,0 );
  329. pStateInfo->ColorTable[15] = RGB(0xFF,0xFF,0xFF);
  330. #if defined(FE_SB)
  331. pStateInfo->CodePage = OEMCP; // scotthsu
  332. #endif
  333. pStateInfo->hWnd = NULL;
  334. pStateInfo->ConsoleTitle[0] = TEXT('\0');
  335. g_fAutoComplete = TRUE;
  336. return pStateInfo;
  337. }
  338. #define SZ_REGKEY_CMDAUTOCOMPLETE TEXT("Software\\Microsoft\\Command Processor")
  339. #define SZ_REGVALUE_CMDAUTOCOMPLETE TEXT("CompletionChar")
  340. #define DWORD_CMD_TAB_AUTOCOMPLETE_ON 0x00000009 // 9 is tab
  341. #define DWORD_CMD_TAB_AUTOCOMPLETE_OFF 0x00000020 // 20 is space which turns it off.
  342. BOOL
  343. IsAutoCompleteOn(
  344. void
  345. )
  346. {
  347. DWORD dwType;
  348. DWORD dwValue = DWORD_CMD_TAB_AUTOCOMPLETE_ON;
  349. DWORD cbSize = sizeof(dwValue);
  350. if ((ERROR_SUCCESS != SHGetValue(HKEY_CURRENT_USER, SZ_REGKEY_CMDAUTOCOMPLETE, SZ_REGVALUE_CMDAUTOCOMPLETE, &dwType, (LPBYTE)&dwValue, &cbSize)) ||
  351. (REG_DWORD != dwType))
  352. {
  353. dwValue = DWORD_CMD_TAB_AUTOCOMPLETE_ON; // Fall back to the default value.
  354. }
  355. return (DWORD_CMD_TAB_AUTOCOMPLETE_ON == dwValue);
  356. }
  357. void
  358. SaveAutoCompleteSetting(
  359. IN BOOL fAutoComplete
  360. )
  361. {
  362. // Only over write the registry value if someone has changed the value.
  363. if (g_fSaveAutoCompleteState)
  364. {
  365. DWORD dwValue = (fAutoComplete ? DWORD_CMD_TAB_AUTOCOMPLETE_ON : DWORD_CMD_TAB_AUTOCOMPLETE_OFF);
  366. SHSetValue(HKEY_CURRENT_USER, SZ_REGKEY_CMDAUTOCOMPLETE, SZ_REGVALUE_CMDAUTOCOMPLETE, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue));
  367. }
  368. }
  369. DWORD
  370. GetRegistryValues(
  371. PCONSOLE_STATE_INFO pStateInfo
  372. )
  373. /*++
  374. Routine Description:
  375. This routine reads in values from the registry and places them
  376. in the supplied structure.
  377. Arguments:
  378. pStateInfo - optional pointer to structure to receive information
  379. Return Value:
  380. current page number
  381. --*/
  382. {
  383. HANDLE hCurrentUserKey;
  384. HANDLE hConsoleKey;
  385. HANDLE hTitleKey;
  386. NTSTATUS Status;
  387. LPWSTR TranslatedTitle;
  388. DWORD dwValue;
  389. DWORD dwRet = 0;
  390. DWORD i;
  391. WCHAR awchBuffer[LF_FACESIZE];
  392. //
  393. // Open the current user registry key
  394. //
  395. Status = RtlOpenCurrentUser(MAXIMUM_ALLOWED, &hCurrentUserKey);
  396. if (!NT_SUCCESS(Status)) {
  397. return 0;
  398. }
  399. //
  400. // Open the console registry key
  401. //
  402. Status = MyRegOpenKey(hCurrentUserKey,
  403. CONSOLE_REGISTRY_STRING,
  404. &hConsoleKey);
  405. if (!NT_SUCCESS(Status)) {
  406. NtClose(hCurrentUserKey);
  407. return 0;
  408. }
  409. //
  410. // If there is no structure to fill out, just get the current
  411. // page and bail out.
  412. //
  413. if (pStateInfo == NULL) {
  414. if (NT_SUCCESS(MyRegQueryValue(hConsoleKey,
  415. CONSOLE_REGISTRY_CURRENTPAGE,
  416. sizeof(dwValue), (PBYTE)&dwValue))) {
  417. dwRet = dwValue;
  418. }
  419. goto CloseKeys;
  420. }
  421. //
  422. // Open the console title subkey, if there is one
  423. //
  424. if (pStateInfo->ConsoleTitle[0] != TEXT('\0')) {
  425. TranslatedTitle = TranslateConsoleTitle(pStateInfo->ConsoleTitle);
  426. if (TranslatedTitle == NULL) {
  427. NtClose(hConsoleKey);
  428. NtClose(hCurrentUserKey);
  429. return 0;
  430. }
  431. Status = MyRegOpenKey(hConsoleKey,
  432. TranslatedTitle,
  433. &hTitleKey);
  434. HeapFree(RtlProcessHeap(),0,TranslatedTitle);
  435. if (!NT_SUCCESS(Status)) {
  436. NtClose(hConsoleKey);
  437. NtClose(hCurrentUserKey);
  438. return 0;
  439. }
  440. } else {
  441. hTitleKey = hConsoleKey;
  442. }
  443. //
  444. // Initial screen fill
  445. //
  446. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  447. CONSOLE_REGISTRY_FILLATTR,
  448. sizeof(dwValue), (PBYTE)&dwValue))) {
  449. pStateInfo->ScreenAttributes = (WORD)dwValue;
  450. }
  451. //
  452. // Initial popup fill
  453. //
  454. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  455. CONSOLE_REGISTRY_POPUPATTR,
  456. sizeof(dwValue), (PBYTE)&dwValue))) {
  457. pStateInfo->PopupAttributes = (WORD)dwValue;
  458. }
  459. //
  460. // Initial color table
  461. //
  462. for (i = 0; i < 16; i++) {
  463. wsprintf(awchBuffer, CONSOLE_REGISTRY_COLORTABLE, i);
  464. if (NT_SUCCESS(MyRegQueryValue(hTitleKey, awchBuffer,
  465. sizeof(dwValue), (PBYTE)&dwValue))) {
  466. pStateInfo->ColorTable[i] = dwValue;
  467. }
  468. }
  469. //
  470. // Initial insert mode
  471. //
  472. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  473. CONSOLE_REGISTRY_INSERTMODE,
  474. sizeof(dwValue), (PBYTE)&dwValue))) {
  475. pStateInfo->InsertMode = !!dwValue;
  476. }
  477. //
  478. // Initial quick edit mode
  479. //
  480. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  481. CONSOLE_REGISTRY_QUICKEDIT,
  482. sizeof(dwValue), (PBYTE)&dwValue))) {
  483. pStateInfo->QuickEdit = !!dwValue;
  484. }
  485. //
  486. // Initial autocomplete mode
  487. //
  488. g_fAutoComplete = IsAutoCompleteOn();
  489. #ifdef i386
  490. //
  491. // Initial full screen mode
  492. //
  493. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  494. CONSOLE_REGISTRY_FULLSCR,
  495. sizeof(dwValue), (PBYTE)&dwValue))) {
  496. pStateInfo->FullScreen = !!dwValue;
  497. }
  498. #endif
  499. #if defined(FE_SB) // scotthsu
  500. //
  501. // Initial code page
  502. //
  503. ASSERT(OEMCP != 0);
  504. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  505. CONSOLE_REGISTRY_CODEPAGE,
  506. sizeof(dwValue), (PBYTE)&dwValue))) {
  507. if (IsValidCodePage(dwValue)) {
  508. pStateInfo->CodePage = (UINT) dwValue;
  509. }
  510. }
  511. #endif
  512. //
  513. // Initial screen buffer size
  514. //
  515. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  516. CONSOLE_REGISTRY_BUFFERSIZE,
  517. sizeof(dwValue), (PBYTE)&dwValue))) {
  518. pStateInfo->ScreenBufferSize.X = LOWORD(dwValue);
  519. pStateInfo->ScreenBufferSize.Y = HIWORD(dwValue);
  520. }
  521. //
  522. // Initial window size
  523. //
  524. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  525. CONSOLE_REGISTRY_WINDOWSIZE,
  526. sizeof(dwValue), (PBYTE)&dwValue))) {
  527. pStateInfo->WindowSize.X = LOWORD(dwValue);
  528. pStateInfo->WindowSize.Y = HIWORD(dwValue);
  529. }
  530. //
  531. // Initial window position
  532. //
  533. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  534. CONSOLE_REGISTRY_WINDOWPOS,
  535. sizeof(dwValue), (PBYTE)&dwValue))) {
  536. pStateInfo->WindowPosX = (SHORT)LOWORD(dwValue);
  537. pStateInfo->WindowPosY = (SHORT)HIWORD(dwValue);
  538. pStateInfo->AutoPosition = FALSE;
  539. }
  540. //
  541. // Initial font size
  542. //
  543. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  544. CONSOLE_REGISTRY_FONTSIZE,
  545. sizeof(dwValue), (PBYTE)&dwValue))) {
  546. pStateInfo->FontSize.X = LOWORD(dwValue);
  547. pStateInfo->FontSize.Y = HIWORD(dwValue);
  548. }
  549. //
  550. // Initial font family
  551. //
  552. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  553. CONSOLE_REGISTRY_FONTFAMILY,
  554. sizeof(dwValue), (PBYTE)&dwValue))) {
  555. pStateInfo->FontFamily = dwValue;
  556. }
  557. //
  558. // Initial font weight
  559. //
  560. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  561. CONSOLE_REGISTRY_FONTWEIGHT,
  562. sizeof(dwValue), (PBYTE)&dwValue))) {
  563. pStateInfo->FontWeight = dwValue;
  564. }
  565. //
  566. // Initial font face name
  567. //
  568. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  569. CONSOLE_REGISTRY_FACENAME,
  570. sizeof(awchBuffer), (PBYTE)awchBuffer))) {
  571. RtlCopyMemory(pStateInfo->FaceName, awchBuffer, sizeof(awchBuffer));
  572. }
  573. //
  574. // Initial cursor size
  575. //
  576. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  577. CONSOLE_REGISTRY_CURSORSIZE,
  578. sizeof(dwValue), (PBYTE)&dwValue))) {
  579. pStateInfo->CursorSize = dwValue;
  580. }
  581. //
  582. // Initial history buffer size
  583. //
  584. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  585. CONSOLE_REGISTRY_HISTORYSIZE,
  586. sizeof(dwValue), (PBYTE)&dwValue))) {
  587. pStateInfo->HistoryBufferSize = dwValue;
  588. }
  589. //
  590. // Initial number of history buffers
  591. //
  592. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  593. CONSOLE_REGISTRY_HISTORYBUFS,
  594. sizeof(dwValue), (PBYTE)&dwValue))) {
  595. pStateInfo->NumberOfHistoryBuffers = dwValue;
  596. }
  597. //
  598. // Initial history duplication mode
  599. //
  600. if (NT_SUCCESS(MyRegQueryValue(hTitleKey,
  601. CONSOLE_REGISTRY_HISTORYNODUP,
  602. sizeof(dwValue), (PBYTE)&dwValue))) {
  603. pStateInfo->HistoryNoDup = dwValue;
  604. }
  605. //
  606. // Close the registry keys
  607. //
  608. if (hTitleKey != hConsoleKey) {
  609. NtClose(hTitleKey);
  610. }
  611. CloseKeys:
  612. NtClose(hConsoleKey);
  613. NtClose(hCurrentUserKey);
  614. return dwRet;
  615. }
  616. VOID
  617. SetRegistryValues(
  618. PCONSOLE_STATE_INFO pStateInfo,
  619. DWORD dwPage
  620. )
  621. /*++
  622. Routine Description:
  623. This routine writes values to the registry from the supplied
  624. structure.
  625. Arguments:
  626. pStateInfo - optional pointer to structure containing information
  627. dwPage - current page number
  628. Return Value:
  629. none
  630. --*/
  631. {
  632. HANDLE hCurrentUserKey;
  633. HANDLE hConsoleKey;
  634. HANDLE hTitleKey;
  635. NTSTATUS Status;
  636. LPWSTR TranslatedTitle;
  637. DWORD dwValue;
  638. DWORD i;
  639. WCHAR awchBuffer[LF_FACESIZE];
  640. //
  641. // Open the current user registry key
  642. //
  643. Status = RtlOpenCurrentUser(MAXIMUM_ALLOWED, &hCurrentUserKey);
  644. if (!NT_SUCCESS(Status)) {
  645. return;
  646. }
  647. //
  648. // Open the console registry key
  649. //
  650. Status = MyRegCreateKey(hCurrentUserKey,
  651. CONSOLE_REGISTRY_STRING,
  652. &hConsoleKey);
  653. if (!NT_SUCCESS(Status)) {
  654. NtClose(hCurrentUserKey);
  655. return;
  656. }
  657. //
  658. // Save the current page
  659. //
  660. MyRegSetValue(hConsoleKey,
  661. CONSOLE_REGISTRY_CURRENTPAGE,
  662. REG_DWORD, &dwPage, sizeof(dwPage));
  663. //
  664. // If we only want to save the current page, bail out
  665. //
  666. if (pStateInfo == NULL) {
  667. goto CloseKeys;
  668. }
  669. //
  670. // Open the console title subkey, if there is one
  671. //
  672. if (pStateInfo->ConsoleTitle[0] != TEXT('\0')) {
  673. TranslatedTitle = TranslateConsoleTitle(pStateInfo->ConsoleTitle);
  674. if (TranslatedTitle == NULL) {
  675. NtClose(hConsoleKey);
  676. NtClose(hCurrentUserKey);
  677. return;
  678. }
  679. Status = MyRegCreateKey(hConsoleKey,
  680. TranslatedTitle,
  681. &hTitleKey);
  682. HeapFree(RtlProcessHeap(),0,TranslatedTitle);
  683. if (!NT_SUCCESS(Status)) {
  684. NtClose(hConsoleKey);
  685. NtClose(hCurrentUserKey);
  686. return;
  687. }
  688. } else {
  689. hTitleKey = hConsoleKey;
  690. }
  691. //
  692. // Save screen and popup colors and color table
  693. //
  694. dwValue = pStateInfo->ScreenAttributes;
  695. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FILLATTR,
  696. REG_DWORD, &dwValue, sizeof(dwValue));
  697. dwValue = pStateInfo->PopupAttributes;
  698. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_POPUPATTR,
  699. REG_DWORD, &dwValue, sizeof(dwValue));
  700. for (i = 0; i < 16; i++) {
  701. dwValue = pStateInfo->ColorTable[i];
  702. wsprintf(awchBuffer, CONSOLE_REGISTRY_COLORTABLE, i);
  703. MyRegUpdateValue(hConsoleKey, hTitleKey, awchBuffer,
  704. REG_DWORD, &dwValue, sizeof(dwValue));
  705. }
  706. //
  707. // Save insert, quickedit, and fullscreen mode settings
  708. //
  709. dwValue = pStateInfo->InsertMode;
  710. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_INSERTMODE,
  711. REG_DWORD, &dwValue, sizeof(dwValue));
  712. dwValue = pStateInfo->QuickEdit;
  713. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_QUICKEDIT,
  714. REG_DWORD, &dwValue, sizeof(dwValue));
  715. SaveAutoCompleteSetting(g_fAutoComplete);
  716. #ifdef i386
  717. dwValue = pStateInfo->FullScreen;
  718. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FULLSCR,
  719. REG_DWORD, &dwValue, sizeof(dwValue));
  720. #endif
  721. #if defined(FE_SB) // scotthsu
  722. ASSERT(OEMCP != 0);
  723. if (gfFESystem) {
  724. dwValue = (DWORD) pStateInfo->CodePage;
  725. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_CODEPAGE,
  726. REG_DWORD, &dwValue, sizeof(dwValue));
  727. }
  728. #endif
  729. //
  730. // Save screen buffer size
  731. //
  732. dwValue = MAKELONG(pStateInfo->ScreenBufferSize.X,
  733. pStateInfo->ScreenBufferSize.Y);
  734. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_BUFFERSIZE,
  735. REG_DWORD, &dwValue, sizeof(dwValue));
  736. //
  737. // Save window size
  738. //
  739. dwValue = MAKELONG(pStateInfo->WindowSize.X,
  740. pStateInfo->WindowSize.Y);
  741. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_WINDOWSIZE,
  742. REG_DWORD, &dwValue, sizeof(dwValue));
  743. //
  744. // Save window position
  745. //
  746. if (pStateInfo->AutoPosition) {
  747. MyRegDeleteKey(hTitleKey, CONSOLE_REGISTRY_WINDOWPOS);
  748. } else {
  749. dwValue = MAKELONG(pStateInfo->WindowPosX,
  750. pStateInfo->WindowPosY);
  751. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_WINDOWPOS,
  752. REG_DWORD, &dwValue, sizeof(dwValue));
  753. }
  754. //
  755. // Save font size, family, weight, and face name
  756. //
  757. dwValue = MAKELONG(pStateInfo->FontSize.X,
  758. pStateInfo->FontSize.Y);
  759. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FONTSIZE,
  760. REG_DWORD, &dwValue, sizeof(dwValue));
  761. dwValue = pStateInfo->FontFamily;
  762. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FONTFAMILY,
  763. REG_DWORD, &dwValue, sizeof(dwValue));
  764. dwValue = pStateInfo->FontWeight;
  765. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FONTWEIGHT,
  766. REG_DWORD, &dwValue, sizeof(dwValue));
  767. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_FACENAME,
  768. REG_SZ, pStateInfo->FaceName,
  769. (_tcslen(pStateInfo->FaceName) + 1) * sizeof(TCHAR));
  770. //
  771. // Save cursor size
  772. //
  773. dwValue = pStateInfo->CursorSize;
  774. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_CURSORSIZE,
  775. REG_DWORD, &dwValue, sizeof(dwValue));
  776. //
  777. // Save history buffer size and number
  778. //
  779. dwValue = pStateInfo->HistoryBufferSize;
  780. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_HISTORYSIZE,
  781. REG_DWORD, &dwValue, sizeof(dwValue));
  782. dwValue = pStateInfo->NumberOfHistoryBuffers;
  783. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_HISTORYBUFS,
  784. REG_DWORD, &dwValue, sizeof(dwValue));
  785. dwValue = pStateInfo->HistoryNoDup;
  786. MyRegUpdateValue(hConsoleKey, hTitleKey, CONSOLE_REGISTRY_HISTORYNODUP,
  787. REG_DWORD, &dwValue, sizeof(dwValue));
  788. //
  789. // Close the registry keys
  790. //
  791. if (hTitleKey != hConsoleKey) {
  792. NtClose(hTitleKey);
  793. }
  794. CloseKeys:
  795. NtClose(hConsoleKey);
  796. NtClose(hCurrentUserKey);
  797. }