From 5cdf75a235571fd03aee1a6286cd13c1409c9530 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herm=C3=A8s=20B=C3=A9lusca-Ma=C3=AFto?= Date: Sun, 5 Apr 2015 23:04:42 +0000 Subject: [PATCH] [CONSRV][CONSOLE.DLL] - Correctly retrieve/set the default console properties. - (for console.dll only): split ApplyConsoleInfo so that it only deals with displaying the confirmation dialog (and set the correct return value for the PSN_APPLY notification message); the code that really sets console properties and save them in the registry is done in the main CPL function, after the property dialog is destroyed and before the CPL returns. svn path=/trunk/; revision=67068 --- reactos/dll/cpl/console/colors.c | 13 +- reactos/dll/cpl/console/console.c | 154 ++++++++++-------- reactos/dll/cpl/console/console.h | 3 +- reactos/dll/cpl/console/font.c | 13 +- reactos/dll/cpl/console/options.c | 12 +- reactos/win32ss/user/winsrv/concfg/settings.c | 68 ++++---- reactos/win32ss/user/winsrv/concfg/settings.h | 17 +- reactos/win32ss/user/winsrv/consrv/console.c | 26 +-- 8 files changed, 147 insertions(+), 159 deletions(-) diff --git a/reactos/dll/cpl/console/colors.c b/reactos/dll/cpl/console/colors.c index 8c5dfaf8dd3..11ef6ea9efe 100644 --- a/reactos/dll/cpl/console/colors.c +++ b/reactos/dll/cpl/console/colors.c @@ -81,17 +81,8 @@ ColorsProc(HWND hwndDlg, { case PSN_APPLY: { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - break; + ApplyConsoleInfo(hwndDlg); + return TRUE; } case UDN_DELTAPOS: diff --git a/reactos/dll/cpl/console/console.c b/reactos/dll/cpl/console/console.c index 375aa3ceb30..0d3a6f185b4 100644 --- a/reactos/dll/cpl/console/console.c +++ b/reactos/dll/cpl/console/console.c @@ -18,10 +18,12 @@ INT_PTR CALLBACK LayoutProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPara INT_PTR CALLBACK ColorsProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); HINSTANCE hApplet = NULL; -BOOLEAN AppliedConfig = FALSE; -/* Local copy of the console informations */ +/* Local copy of the console information */ PCONSOLE_STATE_INFO ConInfo = NULL; +/* What to do with the console information */ +static BOOL SetConsoleInfo = FALSE; +static BOOL SaveConsoleInfo = FALSE; static VOID InitPropSheetPage(PROPSHEETPAGEW *psp, @@ -40,8 +42,8 @@ InitPropSheetPage(PROPSHEETPAGEW *psp, static VOID InitDefaultConsoleInfo(PCONSOLE_STATE_INFO pConInfo) { - /* FIXME: Get also the defaults from the registry */ - ConCfgInitDefaultSettings(pConInfo); + // FIXME: Also retrieve the value of REG_DWORD CurrentPage. + ConCfgGetDefaultSettings(pConInfo); } static INT_PTR @@ -82,90 +84,53 @@ ApplyProc(HWND hwndDlg, return FALSE; } -BOOL -ApplyConsoleInfo(HWND hwndDlg, - PCONSOLE_STATE_INFO pConInfo) +VOID +ApplyConsoleInfo(HWND hwndDlg) { - BOOL SetParams = FALSE; - BOOL SaveParams = FALSE; + static BOOL ConsoleInfoAlreadySaved = FALSE; + + /* + * We alread applied all the console properties (and saved if needed). + * Nothing more needs to be done. + */ + if (ConsoleInfoAlreadySaved) + goto Done; /* * If we are setting the default parameters, just save them, - * otherwise display the save-confirmation dialog. + * otherwise display the confirmation & apply dialog. */ - if (pConInfo->hWnd == NULL) + if (ConInfo->hWnd == NULL) { - SetParams = FALSE; - SaveParams = TRUE; // FIXME: What happens if one clicks on CANCEL?? + SetConsoleInfo = FALSE; + SaveConsoleInfo = TRUE; } else { INT_PTR res = DialogBoxW(hApplet, MAKEINTRESOURCEW(IDD_APPLYOPTIONS), hwndDlg, ApplyProc); - SetParams = (res != IDCANCEL); - SaveParams = (res == IDC_RADIO_APPLY_ALL); + SetConsoleInfo = (res != IDCANCEL); + SaveConsoleInfo = (res == IDC_RADIO_APPLY_ALL); - if (SetParams == FALSE) + if (SetConsoleInfo == FALSE) { - /* Don't destroy when user presses cancel */ + /* Don't destroy when the user presses cancel */ SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE); - // return TRUE; + return; } } - if (SetParams) - { - HANDLE hSection; - PCONSOLE_STATE_INFO pSharedInfo; + /* + * We applied all the console properties (and saved if needed). + * Set the flag so that if this function is called again, we won't + * need to redo everything again. + */ + ConsoleInfoAlreadySaved = TRUE; - /* - * Create a memory section to share with CONSRV, and map it. - */ - hSection = CreateFileMappingW(INVALID_HANDLE_VALUE, - NULL, - PAGE_READWRITE, - 0, - pConInfo->cbSize, - NULL); - if (!hSection) - { - DPRINT1("Error when creating file mapping, error = %d\n", GetLastError()); - return FALSE; - } - - pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0); - if (!pSharedInfo) - { - DPRINT1("Error when mapping view of file, error = %d\n", GetLastError()); - CloseHandle(hSection); - return FALSE; - } - - /* We are applying the chosen configuration */ - AppliedConfig = TRUE; - - /* Copy the console information into the section */ - RtlCopyMemory(pSharedInfo, pConInfo, pConInfo->cbSize); - - /* Unmap it */ - UnmapViewOfFile(pSharedInfo); - - /* Signal to CONSRV that it can apply the new configuration */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - SendMessage(pConInfo->hWnd, - WM_SETCONSOLEINFO, - (WPARAM)hSection, 0); - - /* Close the section and return */ - CloseHandle(hSection); - } - - if (SaveParams) - { - ConCfgWriteUserSettings(pConInfo); - } - - return TRUE; +Done: + /* Options have been applied */ + SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); + return; } /* First Applet */ @@ -286,7 +251,56 @@ InitApplet(HANDLE hSectionOrWnd) InitPropSheetPage(&psp[i++], IDD_PROPPAGECOLORS , ColorsProc ); Result = PropertySheetW(&psh); + + if (SetConsoleInfo) + { + HANDLE hSection; + /* + * Create a memory section to share with CONSRV, and map it. + */ + hSection = CreateFileMappingW(INVALID_HANDLE_VALUE, + NULL, + PAGE_READWRITE, + 0, + ConInfo->cbSize, + NULL); + if (!hSection) + { + DPRINT1("Error when creating file mapping, error = %d\n", GetLastError()); + goto Quit; + } + + pSharedInfo = MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, 0); + if (!pSharedInfo) + { + DPRINT1("Error when mapping view of file, error = %d\n", GetLastError()); + CloseHandle(hSection); + goto Quit; + } + + /* Copy the console information into the section */ + RtlCopyMemory(pSharedInfo, ConInfo, ConInfo->cbSize); + + /* Unmap it */ + UnmapViewOfFile(pSharedInfo); + + /* Signal to CONSRV that it can apply the new configuration */ + SendMessage(ConInfo->hWnd, + WM_SETCONSOLEINFO, + (WPARAM)hSection, 0); + + /* Close the section and return */ + CloseHandle(hSection); + } + + if (SaveConsoleInfo) + { + /* Default settings saved when ConInfo->hWnd == NULL */ + ConCfgWriteUserSettings(ConInfo, ConInfo->hWnd == NULL); + } + +Quit: /* Cleanup */ HeapFree(GetProcessHeap(), 0, ConInfo); ConInfo = NULL; diff --git a/reactos/dll/cpl/console/console.h b/reactos/dll/cpl/console/console.h index 4e68bf33b20..e3985a0dfed 100644 --- a/reactos/dll/cpl/console/console.h +++ b/reactos/dll/cpl/console/console.h @@ -29,10 +29,9 @@ typedef enum _TEXT_TYPE } TEXT_TYPE; /* Globals */ -extern BOOLEAN AppliedConfig; extern PCONSOLE_STATE_INFO ConInfo; -BOOL ApplyConsoleInfo(HWND hwndDlg, PCONSOLE_STATE_INFO pConInfo); +VOID ApplyConsoleInfo(HWND hwndDlg); VOID PaintConsole(LPDRAWITEMSTRUCT drawItem, PCONSOLE_STATE_INFO pConInfo); BOOL PaintText(LPDRAWITEMSTRUCT drawItem, PCONSOLE_STATE_INFO pConInfo, TEXT_TYPE TextMode); diff --git a/reactos/dll/cpl/console/font.c b/reactos/dll/cpl/console/font.c index 9a6413fa33e..16f9823c395 100644 --- a/reactos/dll/cpl/console/font.c +++ b/reactos/dll/cpl/console/font.c @@ -421,17 +421,8 @@ FontProc(HWND hwndDlg, { case PSN_APPLY: { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } - break; + ApplyConsoleInfo(hwndDlg); + return TRUE; } } diff --git a/reactos/dll/cpl/console/options.c b/reactos/dll/cpl/console/options.c index 58c869d00aa..a37c82fafbb 100644 --- a/reactos/dll/cpl/console/options.c +++ b/reactos/dll/cpl/console/options.c @@ -127,16 +127,8 @@ OptionsProc(HWND hwndDlg, } else if (lppsn->hdr.code == PSN_APPLY) { - if (!AppliedConfig) - { - return ApplyConsoleInfo(hwndDlg, ConInfo); - } - else - { - /* Options have already been applied */ - SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, PSNRET_NOERROR); - return TRUE; - } + ApplyConsoleInfo(hwndDlg); + return TRUE; } break; } diff --git a/reactos/win32ss/user/winsrv/concfg/settings.c b/reactos/win32ss/user/winsrv/concfg/settings.c index 9b95fd51e28..b361c76cc95 100644 --- a/reactos/win32ss/user/winsrv/concfg/settings.c +++ b/reactos/win32ss/user/winsrv/concfg/settings.c @@ -115,13 +115,13 @@ TranslateConsoleName(OUT LPWSTR DestString, while ((DestString = wcschr(DestString, PATH_SEPARATOR))) *DestString = L'_'; } -BOOL +BOOLEAN ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, PHKEY hSubKey, REGSAM samDesired, - BOOL bCreate) + BOOLEAN Create) { - BOOL bRet = TRUE; + BOOLEAN RetVal = TRUE; NTSTATUS Status; WCHAR szBuffer[MAX_PATH] = L"Console\\"; WCHAR szBuffer2[MAX_PATH] = L""; @@ -161,37 +161,38 @@ ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, wcsncat(szBuffer, szBuffer2, MAX_PATH - wcslen(szBuffer) - 1); /* Create or open the registry key */ - if (bCreate) + if (Create) { /* Create the key */ - bRet = (RegCreateKeyExW(hKey, - szBuffer, - 0, NULL, - REG_OPTION_NON_VOLATILE, - samDesired, - NULL, - hSubKey, - NULL) == ERROR_SUCCESS); + RetVal = (RegCreateKeyExW(hKey, + szBuffer, + 0, NULL, + REG_OPTION_NON_VOLATILE, + samDesired, + NULL, + hSubKey, + NULL) == ERROR_SUCCESS); } else { /* Open the key */ - bRet = (RegOpenKeyExW(hKey, - szBuffer, - 0, - samDesired, - hSubKey) == ERROR_SUCCESS); + RetVal = (RegOpenKeyExW(hKey, + szBuffer, + 0, + samDesired, + hSubKey) == ERROR_SUCCESS); } /* Close the parent key and return success or not */ NtClose(hKey); - return bRet; + return RetVal; } -BOOL -ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) +BOOLEAN +ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings) { - BOOL RetVal = FALSE; + BOOLEAN RetVal = FALSE; HKEY hKey; DWORD dwNumSubKeys = 0; DWORD dwIndex; @@ -203,9 +204,8 @@ ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) DWORD Value; DWORD dwValue; - if (!ConCfgOpenUserSettings(ConsoleInfo->ConsoleTitle, - &hKey, KEY_READ, - FALSE)) + if (!ConCfgOpenUserSettings(DefaultSettings ? L"" : ConsoleInfo->ConsoleTitle, + &hKey, KEY_READ, FALSE)) { DPRINT("ConCfgOpenUserSettings failed\n"); return FALSE; @@ -346,16 +346,16 @@ ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) return RetVal; } -BOOL -ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo) +BOOLEAN +ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings) { - BOOL GlobalSettings = (ConsoleInfo->ConsoleTitle[0] == L'\0'); // FIXME HKEY hKey; DWORD Storage = 0; #define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \ do { \ - if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \ + if (DefaultSettings || (!DefaultSettings && (*(Setting) != (DefaultValue)))) \ { \ RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \ } \ @@ -368,9 +368,8 @@ do { WCHAR szValueName[15]; UINT i; - if (!ConCfgOpenUserSettings(ConsoleInfo->ConsoleTitle, - &hKey, KEY_WRITE, - TRUE)) + if (!ConCfgOpenUserSettings(DefaultSettings ? L"" : ConsoleInfo->ConsoleTitle, + &hKey, KEY_WRITE, TRUE)) { return FALSE; } @@ -489,9 +488,6 @@ ConCfgInitDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) RtlCopyMemory(ConsoleInfo->ColorTable, s_Colors, sizeof(s_Colors)); ConsoleInfo->CodePage = 0; - - /* Default settings --> console title is NULL */ - ConsoleInfo->ConsoleTitle[0] = UNICODE_NULL; } VOID @@ -509,8 +505,8 @@ ConCfgGetDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo) * If the HKCU\Console key doesn't exist, create it * and store the default values inside. */ - if (!ConCfgReadUserSettings(ConsoleInfo)) - ConCfgWriteUserSettings(ConsoleInfo); + if (!ConCfgReadUserSettings(ConsoleInfo, TRUE)) + ConCfgWriteUserSettings(ConsoleInfo, TRUE); } /* EOF */ diff --git a/reactos/win32ss/user/winsrv/concfg/settings.h b/reactos/win32ss/user/winsrv/concfg/settings.h index e7d876b5097..bb60b7bd484 100644 --- a/reactos/win32ss/user/winsrv/concfg/settings.h +++ b/reactos/win32ss/user/winsrv/concfg/settings.h @@ -75,13 +75,18 @@ C_ASSERT(sizeof(CONSOLE_STATE_INFO) == 0xD0); /* FUNCTIONS ******************************************************************/ -BOOL ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, - PHKEY hSubKey, - REGSAM samDesired, - BOOL bCreate); +BOOLEAN +ConCfgOpenUserSettings(LPCWSTR ConsoleTitle, + PHKEY hSubKey, + REGSAM samDesired, + BOOLEAN Create); +BOOLEAN +ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings); +BOOLEAN +ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo, + IN BOOLEAN DefaultSettings); -BOOL ConCfgReadUserSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); -BOOL ConCfgWriteUserSettings(IN PCONSOLE_STATE_INFO ConsoleInfo); VOID ConCfgInitDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); VOID ConCfgGetDefaultSettings(IN OUT PCONSOLE_STATE_INFO ConsoleInfo); diff --git a/reactos/win32ss/user/winsrv/consrv/console.c b/reactos/win32ss/user/winsrv/consrv/console.c index b4257b0f47b..4fc9f7db006 100644 --- a/reactos/win32ss/user/winsrv/consrv/console.c +++ b/reactos/win32ss/user/winsrv/consrv/console.c @@ -535,24 +535,24 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, /* * Load the console settings */ - - /* Impersonate the caller in order to retrieve settings in its context */ - if (!CsrImpersonateClient(NULL)) - return STATUS_BAD_IMPERSONATION_LEVEL; - - /* 1. Load the default settings */ RtlZeroMemory(ConsoleInfo, sizeof(ConsoleInfoBuffer)); ConsoleInfo->cbSize = sizeof(ConsoleInfoBuffer); - ConCfgGetDefaultSettings(ConsoleInfo); - /* 2. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */ + /* 1. Get the title of the console (initialize ConsoleInfo->ConsoleTitle) */ Length = min(ConsoleInitInfo->TitleLength, (ConsoleInfo->cbSize - FIELD_OFFSET(CONSOLE_STATE_INFO, ConsoleTitle) - sizeof(UNICODE_NULL)) / sizeof(WCHAR)); wcsncpy(ConsoleInfo->ConsoleTitle, ConsoleInitInfo->ConsoleTitle, Length); ConsoleInfo->ConsoleTitle[Length] = UNICODE_NULL; // NULL-terminate it. + /* 2. Impersonate the caller in order to retrieve settings in its context */ + if (!CsrImpersonateClient(NULL)) + return STATUS_BAD_IMPERSONATION_LEVEL; + + /* 3. Load the default settings */ + ConCfgGetDefaultSettings(ConsoleInfo); + /* - * 3. Load per-application terminal settings. + * 4. Load per-application terminal settings. * * Check whether the process creating the console was launched via * a shell-link. ConsoleInfo->ConsoleTitle may be updated with the @@ -567,7 +567,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, } /* - * 4. Load the remaining console settings via the registry. + * 5. Load the remaining console settings via the registry. */ if ((ConsoleInitInfo->ConsoleStartInfo->dwStartupFlags & STARTF_TITLEISLINKNAME) == 0) { @@ -576,7 +576,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, * or we failed to load shell-link console properties. * Therefore, load the console infos for the application from the registry. */ - ConCfgReadUserSettings(ConsoleInfo); + ConCfgReadUserSettings(ConsoleInfo, FALSE); /* * Now, update them with the properties the user might gave to us @@ -617,7 +617,7 @@ ConSrvInitConsole(OUT PHANDLE NewConsoleHandle, #endif } - /* Revert impersonation */ + /* 6. Revert impersonation */ CsrRevertToSelf(); /* Set-up the code page */ @@ -1044,7 +1044,7 @@ CSR_API(SrvAttachConsole) PROCESS_BASIC_INFORMATION ProcessInfo; ULONG Length = sizeof(ProcessInfo); - /* Get the real parent's ID */ + /* Get the real parent's PID */ Status = NtQueryInformationProcess(TargetProcess->ProcessHandle, ProcessBasicInformation,