2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Console Server DLL
4 * FILE: win32ss/user/winsrv/consrv/frontends/gui/guisettings.c
5 * PURPOSE: GUI Terminal Front-End Settings Management
6 * PROGRAMMERS: Johannes Anderwald
7 * Hermes Belusca-Maito (hermes.belusca@sfr.fr)
10 /* INCLUDES *******************************************************************/
18 #include "guisettings.h"
20 /* FUNCTIONS ******************************************************************/
23 GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
30 GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
37 GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo
)
43 GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData
,
47 PCONSRV_CONSOLE Console
= GuiData
->Console
;
48 PCONSOLE_PROCESS_DATA ProcessData
;
49 HANDLE hSection
= NULL
, hClientSection
= NULL
;
50 PVOID ThreadParameter
= NULL
; // Is either hClientSection or the console window handle,
51 // depending on whether we display the default settings or
52 // the settings of a particular console.
54 DPRINT("GuiConsoleShowConsoleProperties entered\n");
56 if (!ConDrvValidateConsoleUnsafe((PCONSOLE
)Console
, CONSOLE_RUNNING
, TRUE
)) return;
58 /* Get the console leader process, our client */
59 ProcessData
= ConSrvGetConsoleLeaderProcess(Console
);
62 * Be sure we effectively have a properties dialog routine (that launches
63 * the console control panel applet). It resides in kernel32.dll (client).
65 if (ProcessData
->PropRoutine
== NULL
) goto Quit
;
68 * Create a memory section to be shared with the console control panel applet
69 * in the case we are displaying the settings of a particular console.
70 * In that case the ThreadParameter is the hClientSection handle.
71 * In the case we display the default console parameters, we don't need to
72 * create a memory section. We just need to open the applet, and in this case
73 * the ThreadParameter is the parent window handle of the applet's window,
74 * that is, the console window.
78 PCONSOLE_SCREEN_BUFFER ActiveBuffer
= GuiData
->ActiveBuffer
;
79 LARGE_INTEGER SectionSize
;
81 PCONSOLE_STATE_INFO pSharedInfo
= NULL
;
84 * Create a memory section to share with the applet, and map it.
86 SectionSize
.QuadPart
= sizeof(CONSOLE_STATE_INFO
); // Standard size
87 SectionSize
.QuadPart
+= Console
->OriginalTitle
.Length
; // Add the length in bytes of the console title string
89 Status
= NtCreateSection(&hSection
,
96 if (!NT_SUCCESS(Status
))
98 DPRINT1("Error: Impossible to create a shared section, Status = 0x%08lx\n", Status
);
102 Status
= NtMapViewOfSection(hSection
,
104 (PVOID
*)&pSharedInfo
,
112 if (!NT_SUCCESS(Status
))
114 DPRINT1("Error: Impossible to map the shared section, Status = 0x%08lx\n", Status
);
120 * Setup the shared console properties structure.
123 /* Store the real size of the structure */
124 pSharedInfo
->cbSize
= SectionSize
.QuadPart
;
127 * When we setup the settings of a particular console, the parent window
128 * of the applet's window is the console window, and it is given via the
129 * hWnd member of the shared console info structure.
131 pSharedInfo
->hWnd
= GuiData
->hWindow
;
133 /* Console information */
134 pSharedInfo
->HistoryBufferSize
= Console
->HistoryBufferSize
;
135 pSharedInfo
->NumberOfHistoryBuffers
= Console
->NumberOfHistoryBuffers
;
136 pSharedInfo
->HistoryNoDup
= Console
->HistoryNoDup
;
137 pSharedInfo
->QuickEdit
= Console
->QuickEdit
;
138 pSharedInfo
->InsertMode
= Console
->InsertMode
;
139 /// pSharedInfo->InputBufferSize = 0;
140 pSharedInfo
->ScreenBufferSize
= ActiveBuffer
->ScreenBufferSize
;
141 pSharedInfo
->WindowSize
= ActiveBuffer
->ViewSize
;
142 pSharedInfo
->CursorSize
= ActiveBuffer
->CursorInfo
.dwSize
;
143 if (GetType(ActiveBuffer
) == TEXTMODE_BUFFER
)
145 PTEXTMODE_SCREEN_BUFFER Buffer
= (PTEXTMODE_SCREEN_BUFFER
)ActiveBuffer
;
147 pSharedInfo
->ScreenAttributes
= Buffer
->ScreenDefaultAttrib
;
148 pSharedInfo
->PopupAttributes
= Buffer
->PopupDefaultAttrib
;
150 else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
152 // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
153 DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
155 // FIXME: Gather defaults from the registry ?
156 pSharedInfo
->ScreenAttributes
= DEFAULT_SCREEN_ATTRIB
;
157 pSharedInfo
->PopupAttributes
= DEFAULT_POPUP_ATTRIB
;
160 /* We display the output code page only */
161 pSharedInfo
->CodePage
= Console
->OutputCodePage
;
163 /* GUI Information */
164 StringCchCopyNW(pSharedInfo
->FaceName
, ARRAYSIZE(pSharedInfo
->FaceName
),
165 GuiData
->GuiInfo
.FaceName
, ARRAYSIZE(GuiData
->GuiInfo
.FaceName
));
166 pSharedInfo
->FontFamily
= GuiData
->GuiInfo
.FontFamily
;
167 pSharedInfo
->FontSize
= GuiData
->GuiInfo
.FontSize
;
168 pSharedInfo
->FontWeight
= GuiData
->GuiInfo
.FontWeight
;
169 pSharedInfo
->FullScreen
= GuiData
->GuiInfo
.FullScreen
;
170 pSharedInfo
->AutoPosition
= GuiData
->GuiInfo
.AutoPosition
;
171 pSharedInfo
->WindowPosition
= GuiData
->GuiInfo
.WindowOrigin
;
174 RtlCopyMemory(pSharedInfo
->ColorTable
,
175 Console
->Colors
, sizeof(Console
->Colors
));
177 /* Copy the original title of the console and null-terminate it */
178 RtlCopyMemory(pSharedInfo
->ConsoleTitle
,
179 Console
->OriginalTitle
.Buffer
,
180 Console
->OriginalTitle
.Length
);
182 pSharedInfo
->ConsoleTitle
[Console
->OriginalTitle
.Length
/ sizeof(WCHAR
)] = UNICODE_NULL
;
186 NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo
);
188 /* Duplicate the section handle for the client */
189 Status
= NtDuplicateObject(NtCurrentProcess(),
191 ProcessData
->Process
->ProcessHandle
,
193 0, 0, DUPLICATE_SAME_ACCESS
);
194 if (!NT_SUCCESS(Status
))
196 DPRINT1("Error: Impossible to duplicate section handle for client, Status = 0x%08lx\n", Status
);
200 /* For the settings of a particular console, use the shared client section handle as the thread parameter */
201 ThreadParameter
= (PVOID
)hClientSection
;
205 /* For the default settings, use the console window handle as the thread parameter */
206 ThreadParameter
= (PVOID
)GuiData
->hWindow
;
209 /* Start the console control panel applet */
212 HANDLE Thread
= NULL
;
216 Thread
= CreateRemoteThread(ProcessData
->Process
->ProcessHandle
, NULL
, 0,
217 ProcessData
->PropRoutine
,
218 ThreadParameter
, 0, NULL
);
221 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
225 DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
226 ProcessData
->Process
->ClientId
.UniqueProcess
, ProcessData
->Process
);
235 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
237 Status
= _SEH2_GetExceptionCode();
238 DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = 0x%08lx\n", Status
);
243 /* We have finished, close the section handle if any */
244 if (hSection
) NtClose(hSection
);
246 LeaveCriticalSection(&Console
->Lock
);
251 * Function for dealing with the undocumented message and structure used by
252 * Windows' console.dll for setting console info.
253 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
254 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
255 * for more information.
258 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData
,
259 HANDLE hClientSection
)
261 NTSTATUS Status
= STATUS_SUCCESS
;
262 PCONSRV_CONSOLE Console
= GuiData
->Console
;
263 PCONSOLE_PROCESS_DATA ProcessData
;
264 HANDLE hSection
= NULL
;
266 PCONSOLE_STATE_INFO pConInfo
= NULL
;
268 if (!ConDrvValidateConsoleUnsafe((PCONSOLE
)Console
, CONSOLE_RUNNING
, TRUE
)) return;
270 /* Get the console leader process, our client */
271 ProcessData
= ConSrvGetConsoleLeaderProcess(Console
);
273 /* Duplicate the section handle for ourselves */
274 Status
= NtDuplicateObject(ProcessData
->Process
->ProcessHandle
,
278 0, 0, DUPLICATE_SAME_ACCESS
);
279 if (!NT_SUCCESS(Status
))
281 DPRINT1("Error when mapping client handle, Status = 0x%08lx\n", Status
);
285 /* Get a view of the shared section */
286 Status
= NtMapViewOfSection(hSection
,
296 if (!NT_SUCCESS(Status
))
298 DPRINT1("Error when mapping view of file, Status = 0x%08lx\n", Status
);
304 /* Check that the section is well-sized */
305 if ( (ViewSize
< sizeof(CONSOLE_STATE_INFO
)) ||
306 (pConInfo
->cbSize
< sizeof(CONSOLE_STATE_INFO
)) )
308 DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
309 Status
= STATUS_INVALID_VIEW_SIZE
;
310 _SEH2_YIELD(goto Quit
);
313 // TODO: Check that GuiData->hWindow == pConInfo->hWnd
315 /* Retrieve terminal informations */
317 /* Console information */
318 #if 0 // FIXME: Things not set
319 ConInfo
.HistoryBufferSize
= pConInfo
->HistoryBufferSize
;
320 ConInfo
.NumberOfHistoryBuffers
= pConInfo
->NumberOfHistoryBuffers
;
321 ConInfo
.HistoryNoDup
= !!pConInfo
->HistoryNoDup
;
322 ConInfo
.CodePage
= pConInfo
->CodePage
; // Done in ConSrvApplyUserSettings
329 /* Set the console informations */
330 ConSrvApplyUserSettings(Console
, pConInfo
);
332 /* Set the terminal informations */
334 /* Change the font */
337 pConInfo
->FontFamily
,
339 pConInfo
->FontWeight
);
340 // HACK, needed because changing font may change the size of the window
341 /**/TermResizeTerminal(Console
);/**/
343 /* Move the window to the user's values */
344 GuiData
->GuiInfo
.AutoPosition
= !!pConInfo
->AutoPosition
;
345 GuiData
->GuiInfo
.WindowOrigin
= pConInfo
->WindowPosition
;
346 GuiConsoleMoveWindow(GuiData
);
348 InvalidateRect(GuiData
->hWindow
, NULL
, TRUE
);
351 * Apply full-screen mode.
353 if (!!pConInfo
->FullScreen
!= GuiData
->GuiInfo
.FullScreen
)
355 SwitchFullScreen(GuiData
, !!pConInfo
->FullScreen
);
359 * The settings are saved in the registry by console.dll itself, if needed.
363 // GuiConsoleWriteUserSettings(GuiInfo);
366 Status
= STATUS_SUCCESS
;
368 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
370 Status
= _SEH2_GetExceptionCode();
371 DPRINT1("GuiApplyUserSettings - Caught an exception, Status = 0x%08lx\n", Status
);
376 /* Finally, close the section and return */
379 NtUnmapViewOfSection(NtCurrentProcess(), pConInfo
);
383 LeaveCriticalSection(&Console
->Lock
);