mirror of
https://github.com/reactos/reactos.git
synced 2024-10-21 21:34:17 +00:00
542 lines
19 KiB
C
542 lines
19 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS Console Server DLL
|
|
* FILE: win32ss/user/winsrv/consrv_new/frontends/gui/guisettings.c
|
|
* PURPOSE: GUI Terminal Front-End Settings Management
|
|
* PROGRAMMERS: Johannes Anderwald
|
|
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "consrv.h"
|
|
#include "include/conio.h"
|
|
#include "include/settings.h"
|
|
#include "guisettings.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
|
|
VOID GuiConsoleMoveWindow(PGUI_CONSOLE_DATA GuiData);
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
BOOL
|
|
GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|
IN LPCWSTR ConsoleTitle,
|
|
IN DWORD ProcessId)
|
|
{
|
|
/*****************************************************
|
|
* 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;
|
|
}
|
|
|
|
BOOL
|
|
GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|
IN LPCWSTR ConsoleTitle,
|
|
IN DWORD ProcessId)
|
|
{
|
|
/******************************************************
|
|
* 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);
|
|
return TRUE;
|
|
}
|
|
|
|
VOID
|
|
GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
|
|
IN DWORD ProcessId)
|
|
{
|
|
/*******************************************************
|
|
* 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"VGA", 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);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
|
|
BOOL Defaults)
|
|
{
|
|
NTSTATUS Status;
|
|
PCONSOLE Console = GuiData->Console;
|
|
PCONSOLE_SCREEN_BUFFER ActiveBuffer = Console->ActiveBuffer;
|
|
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;
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
/*
|
|
* Setup the shared console properties structure.
|
|
*/
|
|
|
|
/* Header */
|
|
pSharedInfo->hConsoleWindow = GuiData->hWindow;
|
|
pSharedInfo->ShowDefaultParams = Defaults;
|
|
|
|
/*
|
|
* We fill-in the fields only if we display
|
|
* our properties, not the default ones.
|
|
*/
|
|
if (!Defaults)
|
|
{
|
|
/* 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;
|
|
if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
|
|
{
|
|
PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
|
|
|
|
pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
|
|
pSharedInfo->ci.PopupAttrib = Buffer->PopupDefaultAttrib;
|
|
}
|
|
else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
|
|
{
|
|
// PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
|
|
DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
|
|
|
|
// FIXME: Gather defaults from the registry ?
|
|
pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
|
|
pSharedInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB ;
|
|
}
|
|
pSharedInfo->ci.CodePage;
|
|
|
|
/* 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);
|
|
|
|
/* Palette */
|
|
memcpy(pSharedInfo->ci.Colors, 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.
|
|
}
|
|
|
|
/* Null-terminate the title */
|
|
pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
|
|
|
|
|
|
/* 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))
|
|
{
|
|
DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status);
|
|
goto Quit;
|
|
}
|
|
|
|
/* Start the properties dialog */
|
|
if (ProcessData->PropDispatcher)
|
|
{
|
|
_SEH2_TRY
|
|
{
|
|
HANDLE Thread = NULL;
|
|
|
|
_SEH2_TRY
|
|
{
|
|
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);
|
|
}
|
|
}
|
|
_SEH2_FINALLY
|
|
{
|
|
CloseHandle(Thread);
|
|
}
|
|
_SEH2_END;
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Status = _SEH2_GetExceptionCode();
|
|
DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = %08X\n", Status);
|
|
}
|
|
_SEH2_END;
|
|
}
|
|
|
|
Quit:
|
|
/* We have finished, close the section handle */
|
|
NtClose(hSection);
|
|
return;
|
|
}
|
|
|
|
NTSTATUS
|
|
GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
|
|
HANDLE hClientSection,
|
|
BOOL SaveSettings)
|
|
{
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
PCONSOLE 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;
|
|
|
|
/* Get the console leader process, our client */
|
|
ProcessData = CONTAINING_RECORD(Console->ProcessList.Blink,
|
|
CONSOLE_PROCESS_DATA,
|
|
ConsoleLink);
|
|
|
|
/* Duplicate the section handle for ourselves */
|
|
Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
|
|
hClientSection,
|
|
NtCurrentProcess(),
|
|
&hSection,
|
|
0, 0, DUPLICATE_SAME_ACCESS);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
|
|
return Status;
|
|
}
|
|
|
|
/* Get a view of the shared section */
|
|
Status = NtMapViewOfSection(hSection,
|
|
NtCurrentProcess(),
|
|
(PVOID*)&pConInfo,
|
|
0,
|
|
0,
|
|
NULL,
|
|
&ViewSize,
|
|
ViewUnmap,
|
|
0,
|
|
PAGE_READONLY);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
|
|
NtClose(hSection);
|
|
return Status;
|
|
}
|
|
|
|
_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) )
|
|
{
|
|
DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
|
|
Status = STATUS_INVALID_VIEW_SIZE;
|
|
_SEH2_YIELD(goto Quit);
|
|
}
|
|
|
|
// TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
|
|
|
|
/* Retrieve terminal informations */
|
|
ConInfo = &pConInfo->ci;
|
|
TermInfo = &pConInfo->TerminalInfo;
|
|
GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);
|
|
|
|
/*
|
|
* If we don't set the default parameters,
|
|
* apply them, otherwise just save them.
|
|
*/
|
|
if (pConInfo->ShowDefaultParams == FALSE)
|
|
{
|
|
/* Set the console informations */
|
|
ConSrvApplyUserSettings(Console, ConInfo);
|
|
|
|
/* Set the terminal informations */
|
|
|
|
// memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
|
|
|
|
/* Move the window to the user's values */
|
|
GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
|
|
GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
|
|
GuiConsoleMoveWindow(GuiData);
|
|
|
|
InvalidateRect(GuiData->hWindow, NULL, TRUE);
|
|
|
|
/*
|
|
* Apply full-screen mode.
|
|
*/
|
|
GuiData->GuiInfo.FullScreen = GuiInfo->FullScreen;
|
|
// TODO: Apply it really
|
|
}
|
|
|
|
/*
|
|
* Save settings if needed
|
|
*/
|
|
// FIXME: Do it in the console properties applet ??
|
|
if (SaveSettings)
|
|
{
|
|
DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
|
|
ConSrvWriteUserSettings(ConInfo, ProcessId);
|
|
GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
|
|
}
|
|
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
Status = _SEH2_GetExceptionCode();
|
|
DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
|
|
}
|
|
_SEH2_END;
|
|
|
|
Quit:
|
|
/* Finally, close the section and return */
|
|
NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
|
|
NtClose(hSection);
|
|
return Status;
|
|
}
|
|
|
|
/* EOF */
|