registry.c
Upload User: caisha3
Upload Date: 2013-09-21
Package Size: 208739k
Code Size: 24k
Category:

Windows Develop

Development Platform:

Visual C++

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