[CONSRV]: Use string-safe functions to copy the font names into the fixed-size buffers.
[reactos.git] / reactos / win32ss / user / winsrv / consrv / frontends / gui / guisettings.c
index ebfd733..b61d84e 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
-VOID GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
-VOID SwitchFullScreen(PGUI_CONSOLE_DATA GuiData, BOOL FullScreen);
+#include "guiterm.h"
+#include "guisettings.h"
 
 /* FUNCTIONS ******************************************************************/
 
 BOOL
-GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
-                           IN LPCWSTR ConsoleTitle,
-                           IN DWORD ProcessId)
+GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo)
 {
-    /*****************************************************
-     * Adapted from ConSrvReadUserSettings in settings.c *
-     *****************************************************/
-
-    BOOL  RetVal = FALSE;
-    HKEY  hKey;
-    DWORD dwNumSubKeys = 0;
-    DWORD dwIndex;
-    DWORD dwType;
-    WCHAR szValueName[MAX_PATH];
-    DWORD dwValueName;
-    WCHAR szValue[LF_FACESIZE] = L"\0";
-    DWORD Value;
-    DWORD dwValue;
-
-    if (!ConSrvOpenUserSettings(ProcessId,
-                                ConsoleTitle,
-                                &hKey, KEY_READ,
-                                FALSE))
-    {
-        DPRINT("ConSrvOpenUserSettings failed\n");
-        return FALSE;
-    }
-
-    if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
-                        &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
-    {
-        DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
-        RegCloseKey(hKey);
-        return FALSE;
-    }
-
-    DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
-
-    for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
-    {
-        dwValue = sizeof(Value);
-        dwValueName = MAX_PATH; // sizeof(szValueName)/sizeof(szValueName[0])
-
-        if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
-        {
-            if (dwType == REG_SZ)
-            {
-                /*
-                 * Retry in case of string value
-                 */
-                dwValue = sizeof(szValue);
-                dwValueName = MAX_PATH; // sizeof(szValueName)/sizeof(szValueName[0])
-                if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
-                    break;
-            }
-            else
-            {
-                break;
-            }
-        }
-
-        if (!wcscmp(szValueName, L"FaceName"))
-        {
-            SIZE_T Length = min(wcslen(szValue) + 1, LF_FACESIZE); // wcsnlen
-            wcsncpy(TermInfo->FaceName, szValue, LF_FACESIZE);
-            TermInfo->FaceName[Length] = L'\0';
-            RetVal = TRUE;
-        }
-        else if (!wcscmp(szValueName, L"FontFamily"))
-        {
-            TermInfo->FontFamily = Value;
-            RetVal = TRUE;
-        }
-        else if (!wcscmp(szValueName, L"FontSize"))
-        {
-            TermInfo->FontSize = Value;
-            RetVal = TRUE;
-        }
-        else if (!wcscmp(szValueName, L"FontWeight"))
-        {
-            TermInfo->FontWeight = Value;
-            RetVal = TRUE;
-        }
-        else if (!wcscmp(szValueName, L"FullScreen"))
-        {
-            TermInfo->FullScreen = Value;
-            RetVal = TRUE;
-        }
-        else if (!wcscmp(szValueName, L"WindowPosition"))
-        {
-            TermInfo->AutoPosition = FALSE;
-            TermInfo->WindowOrigin.x = LOWORD(Value);
-            TermInfo->WindowOrigin.y = HIWORD(Value);
-            RetVal = TRUE;
-        }
-    }
-
-    RegCloseKey(hKey);
-    return RetVal;
+    /* Do nothing */
+    return TRUE;
 }
 
 BOOL
-GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
-                            IN LPCWSTR ConsoleTitle,
-                            IN DWORD ProcessId)
+GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo)
 {
-    /******************************************************
-     * Adapted from ConSrvWriteUserSettings in settings.c *
-     ******************************************************/
-
-    BOOL GlobalSettings = (ConsoleTitle[0] == L'\0');
-    HKEY hKey;
-    DWORD Storage = 0;
-
-#define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue)         \
-do {                                                                                            \
-    if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue))))                  \
-    {                                                                                           \
-        RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \
-    }                                                                                           \
-    else                                                                                        \
-    {                                                                                           \
-        RegDeleteValue(hKey, (SettingName));                                                    \
-    }                                                                                           \
-} while (0)
-
-    if (!ConSrvOpenUserSettings(ProcessId,
-                                ConsoleTitle,
-                                &hKey, KEY_WRITE,
-                                TRUE))
-    {
-        return FALSE;
-    }
-
-    SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen
-    SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
-    SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &TermInfo->FontSize, 0);
-    SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
-
-    Storage = TermInfo->FullScreen;
-    SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
-
-    if (TermInfo->AutoPosition == FALSE)
-    {
-        Storage = MAKELONG(TermInfo->WindowOrigin.x, TermInfo->WindowOrigin.y);
-        RegSetValueExW(hKey, L"WindowPosition", 0, REG_DWORD, (PBYTE)&Storage, sizeof(DWORD));
-    }
-    else
-    {
-        RegDeleteValue(hKey, L"WindowPosition");
-    }
-
-    RegCloseKey(hKey);
+    /* Do nothing */
     return TRUE;
 }
 
 VOID
-GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
-                             IN DWORD ProcessId)
+GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo)
 {
-    /*******************************************************
-     * Adapted from ConSrvGetDefaultSettings in settings.c *
-     *******************************************************/
-
-    if (TermInfo == NULL) return;
-
-    /*
-     * 1. Load the default values
-     */
-    // wcsncpy(TermInfo->FaceName, L"DejaVu Sans Mono", LF_FACESIZE);
-    // TermInfo->FontSize = MAKELONG(12, 8); // 0x0008000C; // font is 8x12
-    // TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16
-    // TermInfo->FontWeight = FW_NORMAL;
-
-    wcsncpy(TermInfo->FaceName, L"Fixedsys", LF_FACESIZE); // HACK: !!
-    // TermInfo->FaceName[0] = L'\0';
-    TermInfo->FontFamily = FF_DONTCARE;
-    TermInfo->FontSize   = 0;
-    TermInfo->FontWeight = FW_DONTCARE;
-    TermInfo->UseRasterFonts = TRUE;
-
-    TermInfo->FullScreen   = FALSE;
-    TermInfo->ShowWindow   = SW_SHOWNORMAL;
-    TermInfo->AutoPosition = TRUE;
-    TermInfo->WindowOrigin.x = 0;
-    TermInfo->WindowOrigin.y = 0;
-
-    /*
-     * 2. Overwrite them with the ones stored in HKCU\Console.
-     *    If the HKCU\Console key doesn't exist, create it
-     *    and store the default values inside.
-     */
-    if (!GuiConsoleReadUserSettings(TermInfo, L"", ProcessId))
-    {
-        GuiConsoleWriteUserSettings(TermInfo, L"", ProcessId);
-    }
+    /* Do nothing */
 }
 
 VOID
@@ -223,86 +44,108 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
                                 BOOL Defaults)
 {
     NTSTATUS Status;
-    PCONSOLE Console = GuiData->Console;
-    PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
+    PCONSRV_CONSOLE Console = GuiData->Console;
     PCONSOLE_PROCESS_DATA ProcessData;
     HANDLE hSection = NULL, hClientSection = NULL;
-    LARGE_INTEGER SectionSize;
-    ULONG ViewSize = 0;
-    SIZE_T Length = 0;
-    PCONSOLE_PROPS pSharedInfo = NULL;
-    PGUI_CONSOLE_INFO GuiInfo = NULL;
+    PVOID ThreadParameter = NULL; // Is either hClientSection or the console window handle,
+                                  // depending on whether we display the default settings or
+                                  // the settings of a particular console.
 
     DPRINT("GuiConsoleShowConsoleProperties entered\n");
 
-    /*
-     * Create a memory section to share with the applet, and map it.
-     */
-    /* Holds data for console.dll + console info + terminal-specific info */
-    SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO);
-    Status = NtCreateSection(&hSection,
-                             SECTION_ALL_ACCESS,
-                             NULL,
-                             &SectionSize,
-                             PAGE_READWRITE,
-                             SEC_COMMIT,
-                             NULL);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
-        return;
-    }
-
-    Status = NtMapViewOfSection(hSection,
-                                NtCurrentProcess(),
-                                (PVOID*)&pSharedInfo,
-                                0,
-                                0,
-                                NULL,
-                                &ViewSize,
-                                ViewUnmap,
-                                0,
-                                PAGE_READWRITE);
-    if (!NT_SUCCESS(Status))
-    {
-        DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
-        NtClose(hSection);
-        return;
-    }
+    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;
 
+    /* Get the console leader process, our client */
+    ProcessData = ConSrvGetConsoleLeaderProcess(Console);
 
     /*
-     * Setup the shared console properties structure.
+     * Be sure we effectively have a properties dialog routine (that launches
+     * the console control panel applet). It resides in kernel32.dll (client).
      */
-
-    /* Header */
-    pSharedInfo->hConsoleWindow = GuiData->hWindow;
-    pSharedInfo->ShowDefaultParams = Defaults;
+    if (ProcessData->PropRoutine == NULL) goto Quit;
 
     /*
-     * We fill-in the fields only if we display
-     * our properties, not the default ones.
+     * Create a memory section to be shared with the console control panel applet
+     * in the case we are displaying the settings of a particular console.
+     * In that case the ThreadParameter is the hClientSection handle.
+     * In the case we display the default console parameters, we don't need to
+     * create a memory section. We just need to open the applet, and in this case
+     * the ThreadParameter is the parent window handle of the applet's window,
+     * that is, the console window.
      */
     if (!Defaults)
     {
+        PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
+        LARGE_INTEGER SectionSize;
+        ULONG ViewSize = 0;
+        PCONSOLE_STATE_INFO pSharedInfo = NULL;
+
+        /*
+         * Create a memory section to share with the applet, and map it.
+         */
+        SectionSize.QuadPart  = sizeof(CONSOLE_STATE_INFO);    // Standard size
+        SectionSize.QuadPart += Console->OriginalTitle.Length; // Add the length in bytes of the console title string
+
+        Status = NtCreateSection(&hSection,
+                                 SECTION_ALL_ACCESS,
+                                 NULL,
+                                 &SectionSize,
+                                 PAGE_READWRITE,
+                                 SEC_COMMIT,
+                                 NULL);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status);
+            goto Quit;
+        }
+
+        Status = NtMapViewOfSection(hSection,
+                                    NtCurrentProcess(),
+                                    (PVOID*)&pSharedInfo,
+                                    0,
+                                    0,
+                                    NULL,
+                                    &ViewSize,
+                                    ViewUnmap,
+                                    0,
+                                    PAGE_READWRITE);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status);
+            goto Quit;
+        }
+
+
+        /*
+         * Setup the shared console properties structure.
+         */
+
+        /* Store the real size of the structure */
+        pSharedInfo->cbSize = SectionSize.QuadPart;
+
+        /*
+         * When we setup the settings of a particular console, the parent window
+         * of the applet's window is the console window, and it is given via the
+         * hWnd member of the shared console info structure.
+         */
+        pSharedInfo->hWnd = GuiData->hWindow;
+
         /* Console information */
-        pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
-        pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
-        pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
-        pSharedInfo->ci.QuickEdit = Console->QuickEdit;
-        pSharedInfo->ci.InsertMode = Console->InsertMode;
-        pSharedInfo->ci.InputBufferSize = 0;
-        pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
-        pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
-        pSharedInfo->ci.CursorBlinkOn;
-        pSharedInfo->ci.ForceCursorOff;
-        pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
+        pSharedInfo->HistoryBufferSize = Console->HistoryBufferSize;
+        pSharedInfo->NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
+        pSharedInfo->HistoryNoDup = Console->HistoryNoDup;
+        pSharedInfo->QuickEdit = Console->QuickEdit;
+        pSharedInfo->InsertMode = Console->InsertMode;
+        /// pSharedInfo->InputBufferSize = 0;
+        pSharedInfo->ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
+        pSharedInfo->WindowSize = ActiveBuffer->ViewSize;
+        pSharedInfo->CursorSize = ActiveBuffer->CursorInfo.dwSize;
         if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
         {
             PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
 
-            pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
-            pSharedInfo->ci.PopupAttrib  = Buffer->PopupDefaultAttrib;
+            pSharedInfo->ScreenAttributes = Buffer->ScreenDefaultAttrib;
+            pSharedInfo->PopupAttributes  = Buffer->PopupDefaultAttrib;
         }
         else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
         {
@@ -310,127 +153,122 @@ GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
             DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
 
             // FIXME: Gather defaults from the registry ?
-            pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
-            pSharedInfo->ci.PopupAttrib  = DEFAULT_POPUP_ATTRIB ;
+            pSharedInfo->ScreenAttributes = DEFAULT_SCREEN_ATTRIB;
+            pSharedInfo->PopupAttributes  = DEFAULT_POPUP_ATTRIB ;
         }
-        pSharedInfo->ci.CodePage;
+
+        /* We display the output code page only */
+        pSharedInfo->CodePage = Console->OutputCodePage;
 
         /* GUI Information */
-        pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
-        GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
-        Length = min(wcslen(GuiData->GuiInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
-        wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
-        GuiInfo->FaceName[Length] = L'\0';
-        GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
-        GuiInfo->FontSize   = GuiData->GuiInfo.FontSize;
-        GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
-        GuiInfo->UseRasterFonts = GuiData->GuiInfo.UseRasterFonts;
-        GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
-        /// GuiInfo->WindowPosition = GuiData->GuiInfo.WindowPosition;
-        GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
-        GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
-        /* Offsetize */
-        pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo);
+        StringCchCopyNW(pSharedInfo->FaceName, ARRAYSIZE(pSharedInfo->FaceName),
+                        GuiData->GuiInfo.FaceName, ARRAYSIZE(GuiData->GuiInfo.FaceName));
+        pSharedInfo->FontFamily = GuiData->GuiInfo.FontFamily;
+        pSharedInfo->FontSize   = GuiData->GuiInfo.FontSize;
+        pSharedInfo->FontWeight = GuiData->GuiInfo.FontWeight;
+        pSharedInfo->FullScreen = GuiData->GuiInfo.FullScreen;
+        pSharedInfo->AutoPosition   = GuiData->GuiInfo.AutoPosition;
+        pSharedInfo->WindowPosition = GuiData->GuiInfo.WindowOrigin;
 
         /* Palette */
-        memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));
+        RtlCopyMemory(pSharedInfo->ColorTable,
+                      Console->Colors, sizeof(Console->Colors));
 
-        /* Title of the console, original one corresponding to the one set by the console leader */
-        Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
-                     Console->OriginalTitle.Length / sizeof(WCHAR));
-        wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
-    }
-    else
-    {
-        Length = 0;
-        // FIXME: Load the default parameters from the registry.
-    }
+        /* Copy the original title of the console and null-terminate it */
+        RtlCopyMemory(pSharedInfo->ConsoleTitle,
+                      Console->OriginalTitle.Buffer,
+                      Console->OriginalTitle.Length);
 
-    /* Null-terminate the title */
-    pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
+        pSharedInfo->ConsoleTitle[Console->OriginalTitle.Length / sizeof(WCHAR)] = UNICODE_NULL;
 
 
-    /* Unmap the view */
-    NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
+        /* Unmap the view */
+        NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
 
-    /* Get the console leader process, our client */
-    ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
-                                    CONSOLE_PROCESS_DATA,
-                                    ConsoleLink);
-
-    /* Duplicate the section handle for the client */
-    Status = NtDuplicateObject(NtCurrentProcess(),
-                               hSection,
-                               ProcessData->Process->ProcessHandle,
-                               &hClientSection,
-                               0, 0, DUPLICATE_SAME_ACCESS);
-    if (!NT_SUCCESS(Status))
+        /* Duplicate the section handle for the client */
+        Status = NtDuplicateObject(NtCurrentProcess(),
+                                   hSection,
+                                   ProcessData->Process->ProcessHandle,
+                                   &hClientSection,
+                                   0, 0, DUPLICATE_SAME_ACCESS);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status);
+            goto Quit;
+        }
+
+        /* For the settings of a particular console, use the shared client section handle as the thread parameter */
+        ThreadParameter = (PVOID)hClientSection;
+    }
+    else
     {
-        DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status);
-        goto Quit;
+        /* For the default settings, use the console window handle as the thread parameter */
+        ThreadParameter = (PVOID)GuiData->hWindow;
     }
 
-    /* Start the properties dialog */
-    if (ProcessData->PropDispatcher)
+    /* Start the console control panel applet */
+    _SEH2_TRY
     {
+        HANDLE Thread = NULL;
+
         _SEH2_TRY
         {
-            HANDLE Thread = NULL;
-
-            _SEH2_TRY
+            Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
+                                        ProcessData->PropRoutine,
+                                        ThreadParameter, 0, NULL);
+            if (NULL == Thread)
             {
-                Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
-                                            ProcessData->PropDispatcher,
-                                            (PVOID)hClientSection, 0, NULL);
-                if (NULL == Thread)
-                {
-                    DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
-                }
-                else
-                {
-                    DPRINT("ProcessData->PropDispatcher remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n", ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
-                    /// WaitForSingleObject(Thread, INFINITE);
-                }
+                DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
             }
-            _SEH2_FINALLY
+            else
             {
-                CloseHandle(Thread);
+                DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
+                       ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
             }
-            _SEH2_END;
         }
-        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        _SEH2_FINALLY
         {
-            Status = _SEH2_GetExceptionCode();
-            DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = %08X\n", Status);
+            CloseHandle(Thread);
         }
         _SEH2_END;
     }
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+    {
+        Status = _SEH2_GetExceptionCode();
+        DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status);
+    }
+    _SEH2_END;
 
 Quit:
-    /* We have finished, close the section handle */
-    NtClose(hSection);
+    /* We have finished, close the section handle if any */
+    if (hSection) NtClose(hSection);
+
+    LeaveCriticalSection(&Console->Lock);
     return;
 }
 
-NTSTATUS
+/*
+ * Function for dealing with the undocumented message and structure used by
+ * Windows' console.dll for setting console info.
+ * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
+ * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
+ * for more information.
+ */
+VOID
 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
-                     HANDLE hClientSection,
-                     BOOL SaveSettings)
+                     HANDLE hClientSection)
 {
     NTSTATUS Status = STATUS_SUCCESS;
-    PCONSOLE Console = GuiData->Console;
+    PCONSRV_CONSOLE Console = GuiData->Console;
     PCONSOLE_PROCESS_DATA ProcessData;
     HANDLE hSection = NULL;
     ULONG ViewSize = 0;
-    PCONSOLE_PROPS pConInfo = NULL;
-    PCONSOLE_INFO  ConInfo  = NULL;
-    PTERMINAL_INFO TermInfo = NULL;
-    PGUI_CONSOLE_INFO GuiInfo = NULL;
+    PCONSOLE_STATE_INFO pConInfo = NULL;
+
+    if (!ConDrvValidateConsoleUnsafe((PCONSOLE)Console, CONSOLE_RUNNING, TRUE)) return;
 
     /* Get the console leader process, our client */
-    ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
-                                    CONSOLE_PROCESS_DATA,
-                                    ConsoleLink);
+    ProcessData = ConSrvGetConsoleLeaderProcess(Console);
 
     /* Duplicate the section handle for ourselves */
     Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
@@ -440,8 +278,8 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                                0, 0, DUPLICATE_SAME_ACCESS);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
-        return Status;
+        DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status);
+        goto Quit;
     }
 
     /* Get a view of the shared section */
@@ -454,87 +292,96 @@ GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
                                 &ViewSize,
                                 ViewUnmap,
                                 0,
-                                PAGE_READONLY);
+                                PAGE_READWRITE);
     if (!NT_SUCCESS(Status))
     {
-        DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
-        NtClose(hSection);
-        return Status;
+        DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status);
+        goto Quit;
     }
 
     _SEH2_TRY
     {
         /* Check that the section is well-sized */
-        if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
-             (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
-             (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
+        if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
+             (pConInfo->cbSize < sizeof(CONSOLE_STATE_INFO)) )
         {
-            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
+            DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
             Status = STATUS_INVALID_VIEW_SIZE;
             _SEH2_YIELD(goto Quit);
         }
 
-        // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
+        // TODO: Check that GuiData->hWindow == pConInfo->hWnd
 
         /* Retrieve terminal informations */
-        ConInfo  = &pConInfo->ci;
-        TermInfo = &pConInfo->TerminalInfo;
-        GuiInfo  = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);
+
+        /* Console information */
+#if 0 // FIXME: Things not set
+        ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
+        ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
+        ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
+        ConInfo.CodePage = pConInfo->CodePage; // Done in ConSrvApplyUserSettings
+#endif
 
         /*
-         * If we don't set the default parameters,
-         * apply them, otherwise just save them.
+         * Apply the settings
          */
-        if (pConInfo->ShowDefaultParams == FALSE)
-        {
-            /* Set the console informations */
-            ConSrvApplyUserSettings(Console, ConInfo);
 
-            /* Set the terminal informations */
+        /* Set the console informations */
+        ConSrvApplyUserSettings(Console, pConInfo);
 
-            // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
+        /* Set the terminal informations */
 
-            /* Move the window to the user's values */
-            GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
-            GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
-            GuiConsoleMoveWindow(GuiData);
+        /* Change the font */
+        InitFonts(GuiData,
+                  pConInfo->FaceName,
+                  pConInfo->FontFamily,
+                  pConInfo->FontSize,
+                  pConInfo->FontWeight);
+       // HACK, needed because changing font may change the size of the window
+       /**/TermResizeTerminal(Console);/**/
 
-            InvalidateRect(GuiData->hWindow, NULL, TRUE);
+        /* Move the window to the user's values */
+        GuiData->GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
+        GuiData->GuiInfo.WindowOrigin = pConInfo->WindowPosition;
+        GuiConsoleMoveWindow(GuiData);
 
-            /*
-             * Apply full-screen mode.
-             */
-            if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen)
-            {
-                SwitchFullScreen(GuiData, GuiInfo->FullScreen);
-            }
-        }
+        InvalidateRect(GuiData->hWindow, NULL, TRUE);
 
         /*
-         * Save settings if needed
+         * Apply full-screen mode.
          */
-        // FIXME: Do it in the console properties applet ??
-        if (SaveSettings)
+        if (!!pConInfo->FullScreen != GuiData->GuiInfo.FullScreen)
         {
-            DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
-            ConSrvWriteUserSettings(ConInfo, ProcessId);
-            GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
+            SwitchFullScreen(GuiData, !!pConInfo->FullScreen);
         }
 
+        /*
+         * The settings are saved in the registry by console.dll itself, if needed.
+         */
+        // if (SaveSettings)
+        // {
+            // GuiConsoleWriteUserSettings(GuiInfo);
+        // }
+
         Status = STATUS_SUCCESS;
     }
     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
         Status = _SEH2_GetExceptionCode();
-        DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
+        DPRINT1("GuiApplyUserSettings - Caught an exception, Status = 0x%08lx\n", Status);
     }
     _SEH2_END;
 
 Quit:
     /* Finally, close the section and return */
-    NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
-    NtClose(hSection);
-    return Status;
+    if (hSection)
+    {
+        NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
+        NtClose(hSection);
+    }
+
+    LeaveCriticalSection(&Console->Lock);
+    return;
 }
 
 /* EOF */