b97db63030
* This fixes the registry path What's happening is the console is writing the Forcev2 setting, then the v1 console is ignoring those settings, then when you check the checkbox to save the v2 settings, we'll write the zeros out. That's obviously bad. So we'll only write the v2 settings back to the registry if the propsheet was launched from a v2 console. This does not fix the shortcut path. That'll be the next commit. * Fix the shortcut loading too fixes #2319 * remove the redundant property I added * add some notes to the bx.ps1 change
1014 lines
40 KiB
C++
1014 lines
40 KiB
C++
/*++
|
|
|
|
Copyright (c) Microsoft Corporation.
|
|
Licensed under the MIT license.
|
|
|
|
Module Name:
|
|
|
|
registry.c
|
|
|
|
Abstract:
|
|
|
|
This file contains functions to read and write values
|
|
to the registry.
|
|
|
|
Author:
|
|
|
|
Jerry Shea (JerrySh) 30-Sep-1994
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <shlwapi.h>
|
|
#include <strsafe.h>
|
|
#include <intsafe.h>
|
|
#include "../inc/conattrs.hpp"
|
|
#pragma hdrstop
|
|
|
|
#define CONSOLE_REGISTRY_CURRENTPAGE (L"CurrentPage")
|
|
|
|
extern BOOL g_fEditKeys;
|
|
|
|
BOOL GetConsoleBoolValue(__in PCWSTR pszValueName, __in BOOL fDefault)
|
|
{
|
|
return SHRegGetBoolUSValue(CONSOLE_REGISTRY_STRING,
|
|
pszValueName,
|
|
FALSE /*fIgnoreHKCU*/,
|
|
fDefault);
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine allocates a state info structure and fill it in with
|
|
default values.
|
|
|
|
Arguments:
|
|
|
|
none
|
|
|
|
Return Value:
|
|
|
|
pStateInfo - pointer to structure to receive information
|
|
|
|
--*/
|
|
|
|
VOID InitRegistryValues(
|
|
__out PCONSOLE_STATE_INFO pStateInfo)
|
|
{
|
|
pStateInfo->ScreenAttributes = 0x07; // white on black
|
|
pStateInfo->PopupAttributes = 0xf5; // purple on white
|
|
pStateInfo->InsertMode = FALSE;
|
|
pStateInfo->QuickEdit = FALSE;
|
|
pStateInfo->FullScreen = FALSE;
|
|
pStateInfo->ScreenBufferSize.X = 80;
|
|
pStateInfo->ScreenBufferSize.Y = 25;
|
|
pStateInfo->WindowSize.X = 80;
|
|
pStateInfo->WindowSize.Y = 25;
|
|
pStateInfo->WindowPosX = 0;
|
|
pStateInfo->WindowPosY = 0;
|
|
pStateInfo->AutoPosition = TRUE;
|
|
pStateInfo->FontSize.X = 0;
|
|
pStateInfo->FontSize.Y = 0;
|
|
pStateInfo->FontFamily = 0;
|
|
pStateInfo->FontWeight = 0;
|
|
pStateInfo->FaceName[0] = TEXT('\0');
|
|
pStateInfo->CursorSize = 25;
|
|
pStateInfo->HistoryBufferSize = 25;
|
|
pStateInfo->NumberOfHistoryBuffers = 4;
|
|
pStateInfo->HistoryNoDup = 0;
|
|
|
|
// clang-format off
|
|
if (pStateInfo->fIsV2Console)
|
|
{
|
|
// if we're servicing a v2 console instance, default to the new color defaults
|
|
pStateInfo->ColorTable[ 0] = RGB( 12, 12, 12); // Black
|
|
pStateInfo->ColorTable[ 1] = RGB( 0, 55, 218); // Dark Blue
|
|
pStateInfo->ColorTable[ 2] = RGB( 19, 161, 14); // Dark Green
|
|
pStateInfo->ColorTable[ 3] = RGB( 58, 150, 221); // Dark Cyan
|
|
pStateInfo->ColorTable[ 4] = RGB(197, 15, 31); // Dark Red
|
|
pStateInfo->ColorTable[ 5] = RGB(136, 23, 152); // Dark Magenta
|
|
pStateInfo->ColorTable[ 6] = RGB(193, 156, 0); // Dark Yellow
|
|
pStateInfo->ColorTable[ 7] = RGB(204, 204, 204); // Dark White
|
|
pStateInfo->ColorTable[ 8] = RGB(118, 118, 118); // Bright Black
|
|
pStateInfo->ColorTable[ 9] = RGB( 59, 120, 255); // Bright Blue
|
|
pStateInfo->ColorTable[10] = RGB( 22, 198, 12); // Bright Green
|
|
pStateInfo->ColorTable[11] = RGB( 97, 214, 214); // Bright Cyan
|
|
pStateInfo->ColorTable[12] = RGB(231, 72, 86); // Bright Red
|
|
pStateInfo->ColorTable[13] = RGB(180, 0, 158); // Bright Magenta
|
|
pStateInfo->ColorTable[14] = RGB(249, 241, 165); // Bright Yellow
|
|
pStateInfo->ColorTable[15] = RGB(242, 242, 242); // White
|
|
}
|
|
else
|
|
{
|
|
pStateInfo->ColorTable[ 0] = RGB(0, 0, 0 );
|
|
pStateInfo->ColorTable[ 1] = RGB(0, 0, 0x80);
|
|
pStateInfo->ColorTable[ 2] = RGB(0, 0x80,0 );
|
|
pStateInfo->ColorTable[ 3] = RGB(0, 0x80,0x80);
|
|
pStateInfo->ColorTable[ 4] = RGB(0x80,0, 0 );
|
|
pStateInfo->ColorTable[ 5] = RGB(0x80,0, 0x80);
|
|
pStateInfo->ColorTable[ 6] = RGB(0x80,0x80,0 );
|
|
pStateInfo->ColorTable[ 7] = RGB(0xC0,0xC0,0xC0);
|
|
pStateInfo->ColorTable[ 8] = RGB(0x80,0x80,0x80);
|
|
pStateInfo->ColorTable[ 9] = RGB(0, 0, 0xFF);
|
|
pStateInfo->ColorTable[10] = RGB(0, 0xFF,0 );
|
|
pStateInfo->ColorTable[11] = RGB(0, 0xFF,0xFF);
|
|
pStateInfo->ColorTable[12] = RGB(0xFF,0, 0 );
|
|
pStateInfo->ColorTable[13] = RGB(0xFF,0, 0xFF);
|
|
pStateInfo->ColorTable[14] = RGB(0xFF,0xFF,0 );
|
|
pStateInfo->ColorTable[15] = RGB(0xFF,0xFF,0xFF);
|
|
}
|
|
// clang-format on
|
|
|
|
pStateInfo->CodePage = OEMCP;
|
|
pStateInfo->hWnd = NULL;
|
|
pStateInfo->OriginalTitle = NULL;
|
|
pStateInfo->LinkTitle = NULL;
|
|
|
|
// v2 console state
|
|
pStateInfo->fWrapText = TRUE;
|
|
pStateInfo->fFilterOnPaste = TRUE;
|
|
pStateInfo->fCtrlKeyShortcutsDisabled = FALSE;
|
|
pStateInfo->fLineSelection = TRUE;
|
|
pStateInfo->bWindowTransparency = BYTE_MAX;
|
|
pStateInfo->CursorType = 0;
|
|
pStateInfo->CursorColor = INVALID_COLOR;
|
|
pStateInfo->InterceptCopyPaste = FALSE;
|
|
pStateInfo->DefaultForeground = INVALID_COLOR;
|
|
pStateInfo->DefaultBackground = INVALID_COLOR;
|
|
// end v2 console state
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine reads in values from the registry and places them
|
|
in the supplied structure.
|
|
|
|
Arguments:
|
|
|
|
pStateInfo - optional pointer to structure to receive information
|
|
|
|
Return Value:
|
|
|
|
current page number
|
|
|
|
--*/
|
|
|
|
DWORD GetRegistryValues(
|
|
__out_opt PCONSOLE_STATE_INFO pStateInfo)
|
|
{
|
|
HKEY hCurrentUserKey, hConsoleKey, hTitleKey;
|
|
NTSTATUS Status;
|
|
DWORD dwValue, dwRet = 0, i;
|
|
WCHAR awchBuffer[LF_FACESIZE];
|
|
|
|
// initial values for global v2 settings
|
|
g_fForceV2 = GetConsoleBoolValue(CONSOLE_REGISTRY_FORCEV2, TRUE);
|
|
g_fEditKeys = GetConsoleBoolValue(CONSOLE_REGISTRY_EXTENDEDEDITKEY, TRUE);
|
|
|
|
//
|
|
// Open the current user registry key and console key.
|
|
//
|
|
Status = RegistrySerialization::s_OpenConsoleKey(&hCurrentUserKey, &hConsoleKey);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// If there is no structure to fill out, just get the current
|
|
// page and bail out.
|
|
//
|
|
|
|
if (pStateInfo == nullptr)
|
|
{
|
|
Status = RegistrySerialization::s_QueryValue(hConsoleKey,
|
|
CONSOLE_REGISTRY_CURRENTPAGE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
dwRet = dwValue;
|
|
}
|
|
|
|
goto CloseKeys;
|
|
}
|
|
|
|
//
|
|
// Open the console title subkey unless we're changing the defaults.
|
|
//
|
|
if (pStateInfo->Defaults)
|
|
{
|
|
hTitleKey = hConsoleKey;
|
|
}
|
|
else
|
|
{
|
|
Status = RegistrySerialization::s_OpenKey(hConsoleKey,
|
|
pStateInfo->OriginalTitle,
|
|
&hTitleKey);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
RegCloseKey(hConsoleKey);
|
|
RegCloseKey(hCurrentUserKey);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initial screen fill
|
|
//
|
|
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FILLATTR,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->ScreenAttributes = (WORD)dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial popup fill
|
|
//
|
|
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_POPUPATTR,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->PopupAttributes = (WORD)dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial color table
|
|
//
|
|
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
StringCchPrintf(awchBuffer,
|
|
ARRAYSIZE(awchBuffer),
|
|
CONSOLE_REGISTRY_COLORTABLE,
|
|
i);
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
awchBuffer,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->ColorTable[i] = dwValue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initial insert mode.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_INSERTMODE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->InsertMode = !!dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial quick edit mode
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_QUICKEDIT,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->QuickEdit = !!dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial code page
|
|
//
|
|
|
|
FAIL_FAST_IF(!(OEMCP != 0));
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_CODEPAGE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
if (IsValidCodePage(dwValue))
|
|
{
|
|
pStateInfo->CodePage = (UINT)dwValue;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Initial screen buffer size.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_BUFFERSIZE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->ScreenBufferSize.X = LOWORD(dwValue);
|
|
pStateInfo->ScreenBufferSize.Y = HIWORD(dwValue);
|
|
}
|
|
|
|
//
|
|
// Initial window size.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWSIZE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->WindowSize.X = LOWORD(dwValue);
|
|
pStateInfo->WindowSize.Y = HIWORD(dwValue);
|
|
}
|
|
|
|
//
|
|
// Initial window position.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWPOS,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->WindowPosX = (SHORT)LOWORD(dwValue);
|
|
pStateInfo->WindowPosY = (SHORT)HIWORD(dwValue);
|
|
pStateInfo->AutoPosition = FALSE;
|
|
}
|
|
|
|
//
|
|
// Initial font size
|
|
//
|
|
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FONTSIZE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->FontSize.X = LOWORD(dwValue);
|
|
pStateInfo->FontSize.Y = HIWORD(dwValue);
|
|
}
|
|
|
|
//
|
|
// Initial font family.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FONTFAMILY,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->FontFamily = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial font weight.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FONTWEIGHT,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->FontWeight = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial font face name.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FACENAME,
|
|
sizeof(awchBuffer),
|
|
REG_SZ,
|
|
(PBYTE)awchBuffer,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
RtlCopyMemory(pStateInfo->FaceName, awchBuffer, sizeof(awchBuffer));
|
|
}
|
|
|
|
//
|
|
// Initial cursor size.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORSIZE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->CursorSize = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial history buffer size.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYSIZE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->HistoryBufferSize = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial number of history buffers.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYBUFS,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->NumberOfHistoryBuffers = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial history duplication mode.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYNODUP,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->HistoryNoDup = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial text wrapping.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_LINEWRAP,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->fWrapText = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial filter on paste.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_FILTERONPASTE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->fFilterOnPaste = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial ctrl shortcuts disabled.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_CTRLKEYSHORTCUTS_DISABLED,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->fCtrlKeyShortcutsDisabled = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial line selection.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_LINESELECTION,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->fLineSelection = dwValue;
|
|
}
|
|
|
|
//
|
|
// Initial transparency.
|
|
//
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWALPHA,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
if (dwValue <= BYTE_MAX)
|
|
{
|
|
pStateInfo->bWindowTransparency = (BYTE)dwValue;
|
|
}
|
|
}
|
|
|
|
// Initial Cursor Color
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORCOLOR,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->CursorColor = dwValue;
|
|
}
|
|
// Initial Cursor Shape
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORTYPE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->CursorType = dwValue;
|
|
}
|
|
|
|
// Initial Intercept Copy Paste
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_INTERCEPTCOPYPASTE,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->InterceptCopyPaste = !!dwValue;
|
|
}
|
|
|
|
// Initial Foreground Color
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_DEFAULTFOREGROUND,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->DefaultForeground = dwValue;
|
|
}
|
|
|
|
// Initial Background Color
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_DEFAULTBACKGROUND,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->DefaultBackground = dwValue;
|
|
}
|
|
|
|
// Initial Background Color
|
|
Status = RegistrySerialization::s_QueryValue(hTitleKey,
|
|
CONSOLE_REGISTRY_TERMINALSCROLLING,
|
|
sizeof(dwValue),
|
|
REG_DWORD,
|
|
(PBYTE)&dwValue,
|
|
NULL);
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
pStateInfo->TerminalScrolling = dwValue;
|
|
}
|
|
|
|
//
|
|
// Close the registry keys
|
|
//
|
|
|
|
if (hTitleKey != hConsoleKey)
|
|
{
|
|
RegCloseKey(hTitleKey);
|
|
}
|
|
|
|
CloseKeys:
|
|
RegCloseKey(hConsoleKey);
|
|
RegCloseKey(hCurrentUserKey);
|
|
|
|
return dwRet;
|
|
}
|
|
|
|
VOID SetGlobalRegistryValues()
|
|
{
|
|
// save global v2 settings
|
|
const DWORD dwForceV2 = g_fForceV2;
|
|
SHSetValue(HKEY_CURRENT_USER,
|
|
CONSOLE_REGISTRY_STRING,
|
|
CONSOLE_REGISTRY_FORCEV2,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwForceV2,
|
|
sizeof(dwForceV2));
|
|
|
|
const DWORD dwEditKeys = g_fEditKeys;
|
|
SHSetValue(HKEY_CURRENT_USER,
|
|
CONSOLE_REGISTRY_STRING,
|
|
CONSOLE_REGISTRY_EXTENDEDEDITKEY,
|
|
REG_DWORD,
|
|
(LPBYTE)&dwEditKeys,
|
|
sizeof(dwEditKeys));
|
|
}
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine writes values to the registry from the supplied
|
|
structure.
|
|
|
|
Arguments:
|
|
|
|
pStateInfo - optional pointer to structure containing information
|
|
dwPage - current page number
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
|
|
VOID SetRegistryValues(
|
|
PCONSOLE_STATE_INFO pStateInfo,
|
|
DWORD dwPage)
|
|
{
|
|
HKEY hCurrentUserKey, hConsoleKey, hTitleKey;
|
|
NTSTATUS Status;
|
|
DWORD dwValue, i;
|
|
WCHAR awchBuffer[LF_FACESIZE];
|
|
|
|
//
|
|
// Open the current user registry key and console registry key.
|
|
//
|
|
Status = RegistrySerialization::s_OpenConsoleKey(&hCurrentUserKey, &hConsoleKey);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Save the current page.
|
|
//
|
|
LOG_IF_FAILED(RegistrySerialization::s_SetValue(hConsoleKey,
|
|
CONSOLE_REGISTRY_CURRENTPAGE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwPage,
|
|
sizeof(dwPage)));
|
|
|
|
//
|
|
// Open the console title subkey unless we're changing the defaults.
|
|
//
|
|
if (pStateInfo->Defaults)
|
|
{
|
|
hTitleKey = hConsoleKey;
|
|
}
|
|
else
|
|
{
|
|
Status = RegistrySerialization::s_CreateKey(hConsoleKey,
|
|
pStateInfo->OriginalTitle,
|
|
&hTitleKey);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
RegCloseKey(hConsoleKey);
|
|
RegCloseKey(hCurrentUserKey);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save screen and popup colors and color table
|
|
//
|
|
|
|
dwValue = pStateInfo->ScreenAttributes;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FILLATTR,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->PopupAttributes;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_POPUPATTR,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
for (i = 0; i < 16; i++)
|
|
{
|
|
dwValue = pStateInfo->ColorTable[i];
|
|
if (SUCCEEDED(StringCchPrintf(awchBuffer, ARRAYSIZE(awchBuffer), CONSOLE_REGISTRY_COLORTABLE, i)))
|
|
{
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
awchBuffer,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
}
|
|
}
|
|
|
|
//
|
|
// Save insert, quickedit, and fullscreen mode settings
|
|
//
|
|
|
|
dwValue = pStateInfo->InsertMode;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_INSERTMODE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->QuickEdit;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_QUICKEDIT,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
FAIL_FAST_IF(!(OEMCP != 0));
|
|
if (g_fEastAsianSystem)
|
|
{
|
|
dwValue = (DWORD)pStateInfo->CodePage;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_CODEPAGE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
}
|
|
|
|
//
|
|
// Save screen buffer size
|
|
//
|
|
|
|
dwValue = MAKELONG(pStateInfo->ScreenBufferSize.X,
|
|
pStateInfo->ScreenBufferSize.Y);
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_BUFFERSIZE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
//
|
|
// Save window size
|
|
//
|
|
|
|
dwValue = MAKELONG(pStateInfo->WindowSize.X,
|
|
pStateInfo->WindowSize.Y);
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWSIZE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
//
|
|
// Save window position
|
|
//
|
|
|
|
if (pStateInfo->AutoPosition)
|
|
{
|
|
LOG_IF_FAILED(RegistrySerialization::s_DeleteValue(hTitleKey, CONSOLE_REGISTRY_WINDOWPOS));
|
|
}
|
|
else
|
|
{
|
|
dwValue = MAKELONG(pStateInfo->WindowPosX,
|
|
pStateInfo->WindowPosY);
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWPOS,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
}
|
|
|
|
//
|
|
// Save font size, family, weight, and face name
|
|
//
|
|
|
|
dwValue = MAKELONG(pStateInfo->FontSize.X,
|
|
pStateInfo->FontSize.Y);
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FONTSIZE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->FontFamily;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FONTFAMILY,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->FontWeight;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FONTWEIGHT,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FACENAME,
|
|
REG_SZ,
|
|
(BYTE*)(pStateInfo->FaceName),
|
|
(DWORD)(wcslen(pStateInfo->FaceName) + 1) * sizeof(TCHAR)));
|
|
|
|
//
|
|
// Save cursor size
|
|
//
|
|
|
|
dwValue = pStateInfo->CursorSize;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORSIZE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
//
|
|
// Save history buffer size and number
|
|
//
|
|
|
|
dwValue = pStateInfo->HistoryBufferSize;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYSIZE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->NumberOfHistoryBuffers;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYBUFS,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->HistoryNoDup;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_HISTORYNODUP,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
// Save per-title V2 console state
|
|
dwValue = pStateInfo->fWrapText;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_LINEWRAP,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->fFilterOnPaste;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_FILTERONPASTE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->fCtrlKeyShortcutsDisabled;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_CTRLKEYSHORTCUTS_DISABLED,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->fLineSelection;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_LINESELECTION,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->bWindowTransparency;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_WINDOWALPHA,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
SetGlobalRegistryValues();
|
|
|
|
// Only save the "Terminal" settings if we launched as a v2 propsheet. The
|
|
// v1 console doesn't know anything about these settings, and their value
|
|
// will be incorrectly zero'd if we save in this state.
|
|
// See microsoft/terminal#2319 for more details.
|
|
if (gpStateInfo->fIsV2Console)
|
|
{
|
|
// Save cursor type and color
|
|
dwValue = pStateInfo->CursorType;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORTYPE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
dwValue = pStateInfo->CursorColor;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_CURSORCOLOR,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
dwValue = pStateInfo->InterceptCopyPaste;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_INTERCEPTCOPYPASTE,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
|
|
dwValue = pStateInfo->TerminalScrolling;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_TERMINALSCROLLING,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->DefaultForeground;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_DEFAULTFOREGROUND,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
dwValue = pStateInfo->DefaultBackground;
|
|
LOG_IF_FAILED(RegistrySerialization::s_UpdateValue(hConsoleKey,
|
|
hTitleKey,
|
|
CONSOLE_REGISTRY_DEFAULTBACKGROUND,
|
|
REG_DWORD,
|
|
(BYTE*)&dwValue,
|
|
sizeof(dwValue)));
|
|
}
|
|
|
|
//
|
|
// Close the registry keys
|
|
//
|
|
if (hTitleKey != hConsoleKey)
|
|
{
|
|
RegCloseKey(hTitleKey);
|
|
}
|
|
|
|
RegCloseKey(hConsoleKey);
|
|
RegCloseKey(hCurrentUserKey);
|
|
}
|