f7d67ef9cfc77e4e92bbfc9fbe85287d6fda8d1e
[reactos.git] / reactos / win32ss / user / winsrv / consrv / frontends / gui / guisettings.c
1 /*
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)
8 */
9
10 /* INCLUDES *******************************************************************/
11
12 #include <consrv.h>
13
14 #define NDEBUG
15 #include <debug.h>
16
17 #include "guiterm.h"
18 #include "guisettings.h"
19
20 /* FUNCTIONS ******************************************************************/
21
22 BOOL
23 GuiConsoleReadUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
24 IN LPCWSTR ConsoleTitle,
25 IN DWORD ProcessId)
26 {
27 /*****************************************************
28 * Adapted from ConSrvReadUserSettings in settings.c *
29 *****************************************************/
30
31 BOOL RetVal = FALSE;
32 HKEY hKey;
33 DWORD dwNumSubKeys = 0;
34 DWORD dwIndex;
35 DWORD dwType;
36 WCHAR szValueName[MAX_PATH];
37 DWORD dwValueName;
38 WCHAR szValue[LF_FACESIZE] = L"\0";
39 DWORD Value;
40 DWORD dwValue;
41
42 if (!ConSrvOpenUserSettings(ProcessId,
43 ConsoleTitle,
44 &hKey, KEY_READ,
45 FALSE))
46 {
47 DPRINT("ConSrvOpenUserSettings failed\n");
48 return FALSE;
49 }
50
51 if (RegQueryInfoKey(hKey, NULL, NULL, NULL, NULL, NULL, NULL,
52 &dwNumSubKeys, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
53 {
54 DPRINT("GuiConsoleReadUserSettings: RegQueryInfoKey failed\n");
55 RegCloseKey(hKey);
56 return FALSE;
57 }
58
59 DPRINT("GuiConsoleReadUserSettings entered dwNumSubKeys %d\n", dwNumSubKeys);
60
61 for (dwIndex = 0; dwIndex < dwNumSubKeys; dwIndex++)
62 {
63 dwValue = sizeof(Value);
64 dwValueName = MAX_PATH; // sizeof(szValueName)/sizeof(szValueName[0])
65
66 if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, &dwType, (BYTE*)&Value, &dwValue) != ERROR_SUCCESS)
67 {
68 if (dwType == REG_SZ)
69 {
70 /*
71 * Retry in case of string value
72 */
73 dwValue = sizeof(szValue);
74 dwValueName = MAX_PATH; // sizeof(szValueName)/sizeof(szValueName[0])
75 if (RegEnumValueW(hKey, dwIndex, szValueName, &dwValueName, NULL, NULL, (BYTE*)szValue, &dwValue) != ERROR_SUCCESS)
76 break;
77 }
78 else
79 {
80 break;
81 }
82 }
83
84 if (!wcscmp(szValueName, L"FaceName"))
85 {
86 SIZE_T Length = min(wcslen(szValue) + 1, LF_FACESIZE); // wcsnlen
87 wcsncpy(TermInfo->FaceName, szValue, LF_FACESIZE);
88 TermInfo->FaceName[Length] = L'\0';
89 RetVal = TRUE;
90 }
91 else if (!wcscmp(szValueName, L"FontFamily"))
92 {
93 TermInfo->FontFamily = Value;
94 RetVal = TRUE;
95 }
96 else if (!wcscmp(szValueName, L"FontSize"))
97 {
98 TermInfo->FontSize.X = LOWORD(Value); // Width
99 TermInfo->FontSize.Y = HIWORD(Value); // Height
100 RetVal = TRUE;
101 }
102 else if (!wcscmp(szValueName, L"FontWeight"))
103 {
104 TermInfo->FontWeight = Value;
105 RetVal = TRUE;
106 }
107 else if (!wcscmp(szValueName, L"FullScreen"))
108 {
109 TermInfo->FullScreen = Value;
110 RetVal = TRUE;
111 }
112 else if (!wcscmp(szValueName, L"WindowPosition"))
113 {
114 TermInfo->AutoPosition = FALSE;
115 TermInfo->WindowOrigin.x = LOWORD(Value);
116 TermInfo->WindowOrigin.y = HIWORD(Value);
117 RetVal = TRUE;
118 }
119 }
120
121 RegCloseKey(hKey);
122 return RetVal;
123 }
124
125 BOOL
126 GuiConsoleWriteUserSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
127 IN LPCWSTR ConsoleTitle,
128 IN DWORD ProcessId)
129 {
130 /******************************************************
131 * Adapted from ConSrvWriteUserSettings in settings.c *
132 ******************************************************/
133
134 BOOL GlobalSettings = (ConsoleTitle[0] == L'\0');
135 HKEY hKey;
136 DWORD Storage = 0;
137
138 #define SetConsoleSetting(SettingName, SettingType, SettingSize, Setting, DefaultValue) \
139 do { \
140 if (GlobalSettings || (!GlobalSettings && (*(Setting) != (DefaultValue)))) \
141 { \
142 RegSetValueExW(hKey, (SettingName), 0, (SettingType), (PBYTE)(Setting), (SettingSize)); \
143 } \
144 else \
145 { \
146 RegDeleteValue(hKey, (SettingName)); \
147 } \
148 } while (0)
149
150 if (!ConSrvOpenUserSettings(ProcessId,
151 ConsoleTitle,
152 &hKey, KEY_WRITE,
153 TRUE))
154 {
155 return FALSE;
156 }
157
158 SetConsoleSetting(L"FaceName", REG_SZ, (wcslen(TermInfo->FaceName) + 1) * sizeof(WCHAR), TermInfo->FaceName, L'\0'); // wcsnlen
159 SetConsoleSetting(L"FontFamily", REG_DWORD, sizeof(DWORD), &TermInfo->FontFamily, FF_DONTCARE);
160
161 Storage = MAKELONG(TermInfo->FontSize.X, TermInfo->FontSize.Y); // Width, Height
162 SetConsoleSetting(L"FontSize", REG_DWORD, sizeof(DWORD), &Storage, 0);
163
164 SetConsoleSetting(L"FontWeight", REG_DWORD, sizeof(DWORD), &TermInfo->FontWeight, FW_DONTCARE);
165
166 Storage = TermInfo->FullScreen;
167 SetConsoleSetting(L"FullScreen", REG_DWORD, sizeof(DWORD), &Storage, FALSE);
168
169 if (TermInfo->AutoPosition == FALSE)
170 {
171 Storage = MAKELONG(TermInfo->WindowOrigin.x, TermInfo->WindowOrigin.y);
172 RegSetValueExW(hKey, L"WindowPosition", 0, REG_DWORD, (PBYTE)&Storage, sizeof(DWORD));
173 }
174 else
175 {
176 RegDeleteValue(hKey, L"WindowPosition");
177 }
178
179 RegCloseKey(hKey);
180 return TRUE;
181 }
182
183 VOID
184 GuiConsoleGetDefaultSettings(IN OUT PGUI_CONSOLE_INFO TermInfo,
185 IN DWORD ProcessId)
186 {
187 /*******************************************************
188 * Adapted from ConSrvGetDefaultSettings in settings.c *
189 *******************************************************/
190
191 if (TermInfo == NULL) return;
192
193 /*
194 * 1. Load the default values
195 */
196 // wcsncpy(TermInfo->FaceName, L"DejaVu Sans Mono", LF_FACESIZE);
197 // TermInfo->FontSize = MAKELONG(8, 12); // 0x000C0008; // font is 8x12
198 // TermInfo->FontSize = MAKELONG(16, 16); // font is 16x16
199
200 wcsncpy(TermInfo->FaceName, L"VGA", LF_FACESIZE); // HACK: !!
201 // TermInfo->FaceName[0] = L'\0';
202 TermInfo->FontFamily = FF_DONTCARE;
203 TermInfo->FontSize.X = 0;
204 TermInfo->FontSize.Y = 0;
205 TermInfo->FontWeight = FW_NORMAL; // HACK: !!
206 // TermInfo->FontWeight = FW_DONTCARE;
207
208 TermInfo->FullScreen = FALSE;
209 TermInfo->ShowWindow = SW_SHOWNORMAL;
210 TermInfo->AutoPosition = TRUE;
211 TermInfo->WindowOrigin.x = 0;
212 TermInfo->WindowOrigin.y = 0;
213
214 /*
215 * 2. Overwrite them with the ones stored in HKCU\Console.
216 * If the HKCU\Console key doesn't exist, create it
217 * and store the default values inside.
218 */
219 if (!GuiConsoleReadUserSettings(TermInfo, L"", ProcessId))
220 {
221 GuiConsoleWriteUserSettings(TermInfo, L"", ProcessId);
222 }
223 }
224
225 VOID
226 GuiConsoleShowConsoleProperties(PGUI_CONSOLE_DATA GuiData,
227 BOOL Defaults)
228 {
229 NTSTATUS Status;
230 PCONSRV_CONSOLE Console = GuiData->Console;
231 PCONSOLE_SCREEN_BUFFER ActiveBuffer = GuiData->ActiveBuffer;
232 PCONSOLE_PROCESS_DATA ProcessData;
233 HANDLE hSection = NULL, hClientSection = NULL;
234 LARGE_INTEGER SectionSize;
235 ULONG ViewSize = 0;
236 SIZE_T Length = 0;
237 PCONSOLE_PROPS pSharedInfo = NULL;
238 PGUI_CONSOLE_INFO GuiInfo = NULL;
239
240 DPRINT("GuiConsoleShowConsoleProperties entered\n");
241
242 if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
243
244 /*
245 * Create a memory section to share with the applet, and map it.
246 */
247 /* Holds data for console.dll + console info + terminal-specific info */
248 SectionSize.QuadPart = sizeof(CONSOLE_PROPS) + sizeof(GUI_CONSOLE_INFO);
249 Status = NtCreateSection(&hSection,
250 SECTION_ALL_ACCESS,
251 NULL,
252 &SectionSize,
253 PAGE_READWRITE,
254 SEC_COMMIT,
255 NULL);
256 if (!NT_SUCCESS(Status))
257 {
258 DPRINT1("Error: Impossible to create a shared section ; Status = %lu\n", Status);
259 goto Quit;
260 }
261
262 Status = NtMapViewOfSection(hSection,
263 NtCurrentProcess(),
264 (PVOID*)&pSharedInfo,
265 0,
266 0,
267 NULL,
268 &ViewSize,
269 ViewUnmap,
270 0,
271 PAGE_READWRITE);
272 if (!NT_SUCCESS(Status))
273 {
274 DPRINT1("Error: Impossible to map the shared section ; Status = %lu\n", Status);
275 goto Quit;
276 }
277
278
279 /*
280 * Setup the shared console properties structure.
281 */
282
283 /* Header */
284 pSharedInfo->hConsoleWindow = GuiData->hWindow;
285 pSharedInfo->ShowDefaultParams = Defaults;
286
287 /*
288 * We fill-in the fields only if we display
289 * our properties, not the default ones.
290 */
291 if (!Defaults)
292 {
293 /* Console information */
294 pSharedInfo->ci.HistoryBufferSize = Console->HistoryBufferSize;
295 pSharedInfo->ci.NumberOfHistoryBuffers = Console->NumberOfHistoryBuffers;
296 pSharedInfo->ci.HistoryNoDup = Console->HistoryNoDup;
297 pSharedInfo->ci.QuickEdit = Console->QuickEdit;
298 pSharedInfo->ci.InsertMode = Console->InsertMode;
299 /////////////pSharedInfo->ci.InputBufferSize = 0;
300 pSharedInfo->ci.ScreenBufferSize = ActiveBuffer->ScreenBufferSize;
301 pSharedInfo->ci.ConsoleSize = ActiveBuffer->ViewSize;
302 pSharedInfo->ci.CursorBlinkOn;
303 pSharedInfo->ci.ForceCursorOff;
304 pSharedInfo->ci.CursorSize = ActiveBuffer->CursorInfo.dwSize;
305 if (GetType(ActiveBuffer) == TEXTMODE_BUFFER)
306 {
307 PTEXTMODE_SCREEN_BUFFER Buffer = (PTEXTMODE_SCREEN_BUFFER)ActiveBuffer;
308
309 pSharedInfo->ci.ScreenAttrib = Buffer->ScreenDefaultAttrib;
310 pSharedInfo->ci.PopupAttrib = Buffer->PopupDefaultAttrib;
311 }
312 else // if (GetType(ActiveBuffer) == GRAPHICS_BUFFER)
313 {
314 // PGRAPHICS_SCREEN_BUFFER Buffer = (PGRAPHICS_SCREEN_BUFFER)ActiveBuffer;
315 DPRINT1("GuiConsoleShowConsoleProperties - Graphics buffer\n");
316
317 // FIXME: Gather defaults from the registry ?
318 pSharedInfo->ci.ScreenAttrib = DEFAULT_SCREEN_ATTRIB;
319 pSharedInfo->ci.PopupAttrib = DEFAULT_POPUP_ATTRIB ;
320 }
321 pSharedInfo->ci.CodePage;
322
323 /* GUI Information */
324 pSharedInfo->TerminalInfo.Size = sizeof(GUI_CONSOLE_INFO);
325 GuiInfo = pSharedInfo->TerminalInfo.TermInfo = (PGUI_CONSOLE_INFO)(pSharedInfo + 1);
326 Length = min(wcslen(GuiData->GuiInfo.FaceName) + 1, LF_FACESIZE); // wcsnlen
327 wcsncpy(GuiInfo->FaceName, GuiData->GuiInfo.FaceName, LF_FACESIZE);
328 GuiInfo->FaceName[Length] = L'\0';
329 GuiInfo->FontFamily = GuiData->GuiInfo.FontFamily;
330 GuiInfo->FontSize = GuiData->GuiInfo.FontSize;
331 GuiInfo->FontWeight = GuiData->GuiInfo.FontWeight;
332 GuiInfo->FullScreen = GuiData->GuiInfo.FullScreen;
333 GuiInfo->AutoPosition = GuiData->GuiInfo.AutoPosition;
334 GuiInfo->WindowOrigin = GuiData->GuiInfo.WindowOrigin;
335 /* Offsetize */
336 pSharedInfo->TerminalInfo.TermInfo = (PVOID)((ULONG_PTR)GuiInfo - (ULONG_PTR)pSharedInfo);
337
338 /* Palette */
339 memcpy(pSharedInfo->ci.Colors, Console->Colors, sizeof(Console->Colors));
340
341 /* Title of the console, original one corresponding to the one set by the console leader */
342 Length = min(sizeof(pSharedInfo->ci.ConsoleTitle) / sizeof(pSharedInfo->ci.ConsoleTitle[0]) - 1,
343 Console->OriginalTitle.Length / sizeof(WCHAR));
344 wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
345 }
346 else
347 {
348 Length = 0;
349 // FIXME: Load the default parameters from the registry.
350 }
351
352 /* Null-terminate the title */
353 pSharedInfo->ci.ConsoleTitle[Length] = L'\0';
354
355
356 /* Unmap the view */
357 NtUnmapViewOfSection(NtCurrentProcess(), pSharedInfo);
358
359 /* Get the console leader process, our client */
360 ProcessData = ConSrvGetConsoleLeaderProcess(Console);
361
362 /* Duplicate the section handle for the client */
363 Status = NtDuplicateObject(NtCurrentProcess(),
364 hSection,
365 ProcessData->Process->ProcessHandle,
366 &hClientSection,
367 0, 0, DUPLICATE_SAME_ACCESS);
368 if (!NT_SUCCESS(Status))
369 {
370 DPRINT1("Error: Impossible to duplicate section handle for client ; Status = %lu\n", Status);
371 goto Quit;
372 }
373
374 /* Start the properties dialog */
375 if (ProcessData->PropRoutine)
376 {
377 _SEH2_TRY
378 {
379 HANDLE Thread = NULL;
380
381 _SEH2_TRY
382 {
383 Thread = CreateRemoteThread(ProcessData->Process->ProcessHandle, NULL, 0,
384 ProcessData->PropRoutine,
385 (PVOID)hClientSection, 0, NULL);
386 if (NULL == Thread)
387 {
388 DPRINT1("Failed thread creation (Error: 0x%x)\n", GetLastError());
389 }
390 else
391 {
392 DPRINT("ProcessData->PropRoutine remote thread creation succeeded, ProcessId = %x, Process = 0x%p\n",
393 ProcessData->Process->ClientId.UniqueProcess, ProcessData->Process);
394 /// WaitForSingleObject(Thread, INFINITE);
395 }
396 }
397 _SEH2_FINALLY
398 {
399 CloseHandle(Thread);
400 }
401 _SEH2_END;
402 }
403 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
404 {
405 Status = _SEH2_GetExceptionCode();
406 DPRINT1("GuiConsoleShowConsoleProperties - Caught an exception, Status = %08X\n", Status);
407 }
408 _SEH2_END;
409 }
410
411 Quit:
412 /* We have finished, close the section handle */
413 if (hSection) NtClose(hSection);
414
415 LeaveCriticalSection(&Console->Lock);
416 return;
417 }
418
419 VOID
420 GuiApplyUserSettings(PGUI_CONSOLE_DATA GuiData,
421 HANDLE hClientSection,
422 BOOL SaveSettings)
423 {
424 NTSTATUS Status = STATUS_SUCCESS;
425 PCONSRV_CONSOLE Console = GuiData->Console;
426 PCONSOLE_PROCESS_DATA ProcessData;
427 HANDLE hSection = NULL;
428 ULONG ViewSize = 0;
429 PCONSOLE_PROPS pConInfo = NULL;
430 PCONSOLE_INFO ConInfo = NULL;
431 PTERMINAL_INFO TermInfo = NULL;
432 PGUI_CONSOLE_INFO GuiInfo = NULL;
433
434 if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
435
436 /* Get the console leader process, our client */
437 ProcessData = ConSrvGetConsoleLeaderProcess(Console);
438
439 /* Duplicate the section handle for ourselves */
440 Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
441 hClientSection,
442 NtCurrentProcess(),
443 &hSection,
444 0, 0, DUPLICATE_SAME_ACCESS);
445 if (!NT_SUCCESS(Status))
446 {
447 DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
448 goto Quit;
449 }
450
451 /* Get a view of the shared section */
452 Status = NtMapViewOfSection(hSection,
453 NtCurrentProcess(),
454 (PVOID*)&pConInfo,
455 0,
456 0,
457 NULL,
458 &ViewSize,
459 ViewUnmap,
460 0,
461 PAGE_READWRITE);
462 if (!NT_SUCCESS(Status))
463 {
464 DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
465 goto Quit;
466 }
467
468 _SEH2_TRY
469 {
470 /* Check that the section is well-sized */
471 if ( (ViewSize < sizeof(CONSOLE_PROPS)) ||
472 (pConInfo->TerminalInfo.Size != sizeof(GUI_CONSOLE_INFO)) ||
473 (ViewSize < sizeof(CONSOLE_PROPS) + pConInfo->TerminalInfo.Size) )
474 {
475 DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_PROPS) + sizeof(Terminal_specific_info)\n");
476 Status = STATUS_INVALID_VIEW_SIZE;
477 _SEH2_YIELD(goto Quit);
478 }
479
480 // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
481
482 /* Retrieve terminal informations */
483 ConInfo = &pConInfo->ci;
484 TermInfo = &pConInfo->TerminalInfo;
485 GuiInfo = TermInfo->TermInfo = (PVOID)((ULONG_PTR)pConInfo + (ULONG_PTR)TermInfo->TermInfo);
486
487 /*
488 * If we don't set the default parameters,
489 * apply them, otherwise just save them.
490 */
491 if (pConInfo->ShowDefaultParams == FALSE)
492 {
493 /* Set the console informations */
494 ConSrvApplyUserSettings(Console, ConInfo);
495
496 /* Set the terminal informations */
497
498 // memcpy(&GuiData->GuiInfo, GuiInfo, sizeof(GUI_CONSOLE_INFO));
499
500 /* Change the font */
501 InitFonts(GuiData,
502 GuiInfo->FaceName,
503 GuiInfo->FontFamily,
504 GuiInfo->FontSize,
505 GuiInfo->FontWeight);
506 // HACK, needed because changing font may change the size of the window
507 /**/TermResizeTerminal(Console);/**/
508
509 /* Move the window to the user's values */
510 GuiData->GuiInfo.AutoPosition = GuiInfo->AutoPosition;
511 GuiData->GuiInfo.WindowOrigin = GuiInfo->WindowOrigin;
512 GuiConsoleMoveWindow(GuiData);
513
514 InvalidateRect(GuiData->hWindow, NULL, TRUE);
515
516 /*
517 * Apply full-screen mode.
518 */
519 if (GuiInfo->FullScreen != GuiData->GuiInfo.FullScreen)
520 {
521 SwitchFullScreen(GuiData, GuiInfo->FullScreen);
522 }
523 }
524
525 /*
526 * Save settings if needed
527 */
528 // FIXME: Do it in the console properties applet ??
529 if (SaveSettings)
530 {
531 DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
532 ConSrvWriteUserSettings(ConInfo, ProcessId);
533 GuiConsoleWriteUserSettings(GuiInfo, ConInfo->ConsoleTitle, ProcessId);
534 }
535
536 Status = STATUS_SUCCESS;
537 }
538 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
539 {
540 Status = _SEH2_GetExceptionCode();
541 DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
542 }
543 _SEH2_END;
544
545 Quit:
546 /* Finally, close the section and return */
547 if (hSection)
548 {
549 NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
550 NtClose(hSection);
551 }
552
553 LeaveCriticalSection(&Console->Lock);
554 return;
555 }
556
557 /*
558 * Function for dealing with the undocumented message and structure used by
559 * Windows' console.dll for setting console info.
560 * See http://www.catch22.net/sites/default/source/files/setconsoleinfo.c
561 * and http://www.scn.rain.com/~neighorn/PDF/MSBugPaper.pdf
562 * for more information.
563 */
564 VOID
565 GuiApplyWindowsConsoleSettings(PGUI_CONSOLE_DATA GuiData,
566 HANDLE hClientSection)
567 {
568 NTSTATUS Status = STATUS_SUCCESS;
569 PCONSRV_CONSOLE Console = GuiData->Console;
570 PCONSOLE_PROCESS_DATA ProcessData;
571 HANDLE hSection = NULL;
572 ULONG ViewSize = 0;
573 PCONSOLE_STATE_INFO pConInfo = NULL;
574 CONSOLE_INFO ConInfo;
575 GUI_CONSOLE_INFO GuiInfo;
576 SIZE_T Length;
577
578 if (!ConDrvValidateConsoleUnsafe(Console, CONSOLE_RUNNING, TRUE)) return;
579
580 /* Get the console leader process, our client */
581 ProcessData = ConSrvGetConsoleLeaderProcess(Console);
582
583 /* Duplicate the section handle for ourselves */
584 Status = NtDuplicateObject(ProcessData->Process->ProcessHandle,
585 hClientSection,
586 NtCurrentProcess(),
587 &hSection,
588 0, 0, DUPLICATE_SAME_ACCESS);
589 if (!NT_SUCCESS(Status))
590 {
591 DPRINT1("Error when mapping client handle, Status = %lu\n", Status);
592 goto Quit;
593 }
594
595 /* Get a view of the shared section */
596 Status = NtMapViewOfSection(hSection,
597 NtCurrentProcess(),
598 (PVOID*)&pConInfo,
599 0,
600 0,
601 NULL,
602 &ViewSize,
603 ViewUnmap,
604 0,
605 PAGE_READWRITE);
606 if (!NT_SUCCESS(Status))
607 {
608 DPRINT1("Error when mapping view of file, Status = %lu\n", Status);
609 goto Quit;
610 }
611
612 _SEH2_TRY
613 {
614 /* Check that the section is well-sized */
615 if ( (ViewSize < sizeof(CONSOLE_STATE_INFO)) ||
616 (pConInfo->cbSize != sizeof(CONSOLE_STATE_INFO)) )
617 {
618 DPRINT1("Error: section bad-sized: sizeof(Section) < sizeof(CONSOLE_STATE_INFO)\n");
619 Status = STATUS_INVALID_VIEW_SIZE;
620 _SEH2_YIELD(goto Quit);
621 }
622
623 // TODO: Check that GuiData->hWindow == pConInfo->hConsoleWindow
624
625 /* Retrieve terminal informations */
626
627 // Console information
628 ConInfo.HistoryBufferSize = pConInfo->HistoryBufferSize;
629 ConInfo.NumberOfHistoryBuffers = pConInfo->NumberOfHistoryBuffers;
630 ConInfo.HistoryNoDup = !!pConInfo->HistoryNoDup;
631 ConInfo.QuickEdit = !!pConInfo->QuickEdit;
632 ConInfo.InsertMode = !!pConInfo->InsertMode;
633 ConInfo.ScreenBufferSize = pConInfo->ScreenBufferSize;
634 ConInfo.ConsoleSize = pConInfo->WindowSize;
635 ConInfo.CursorSize = pConInfo->CursorSize;
636 ConInfo.ScreenAttrib = pConInfo->ScreenColors;
637 ConInfo.PopupAttrib = pConInfo->PopupColors;
638 memcpy(&ConInfo.Colors, pConInfo->ColorTable, sizeof(ConInfo.Colors));
639 ConInfo.CodePage = pConInfo->CodePage;
640 /**ConInfo.ConsoleTitle[MAX_PATH + 1] = pConInfo->ConsoleTitle; // FIXME: memcpy**/
641 #if 0
642 /* Title of the console, original one corresponding to the one set by the console leader */
643 Length = min(sizeof(pConInfo->ConsoleTitle) / sizeof(pConInfo->ConsoleTitle[0]) - 1,
644 Console->OriginalTitle.Length / sizeof(WCHAR));
645 wcsncpy(pSharedInfo->ci.ConsoleTitle, Console->OriginalTitle.Buffer, Length);
646 #endif
647 // BOOLEAN ConInfo.CursorBlinkOn = pConInfo->
648 // BOOLEAN ConInfo.ForceCursorOff = pConInfo->
649
650
651 // Terminal information
652 Length = min(wcslen(pConInfo->FaceName) + 1, LF_FACESIZE); // wcsnlen
653 wcsncpy(GuiInfo.FaceName, pConInfo->FaceName, LF_FACESIZE);
654 GuiInfo.FaceName[Length] = L'\0';
655
656 GuiInfo.FontFamily = pConInfo->FontFamily;
657 GuiInfo.FontSize = pConInfo->FontSize;
658 GuiInfo.FontWeight = pConInfo->FontWeight;
659 GuiInfo.FullScreen = !!pConInfo->FullScreen;
660 GuiInfo.AutoPosition = !!pConInfo->AutoPosition;
661 GuiInfo.WindowOrigin = pConInfo->WindowPosition;
662 // WORD GuiInfo.ShowWindow = pConInfo->
663
664
665
666 /*
667 * If we don't set the default parameters,
668 * apply them, otherwise just save them.
669 */
670 #if 0
671 if (pConInfo->ShowDefaultParams == FALSE)
672 #endif
673 {
674 /* Set the console informations */
675 ConSrvApplyUserSettings(Console, &ConInfo);
676
677 /* Set the terminal informations */
678
679 // memcpy(&GuiData->GuiInfo, &GuiInfo, sizeof(GUI_CONSOLE_INFO));
680
681 /* Change the font */
682 InitFonts(GuiData,
683 GuiInfo.FaceName,
684 GuiInfo.FontFamily,
685 GuiInfo.FontSize,
686 GuiInfo.FontWeight);
687 // HACK, needed because changing font may change the size of the window
688 /**/TermResizeTerminal(Console);/**/
689
690 /* Move the window to the user's values */
691 GuiData->GuiInfo.AutoPosition = GuiInfo.AutoPosition;
692 GuiData->GuiInfo.WindowOrigin = GuiInfo.WindowOrigin;
693 GuiConsoleMoveWindow(GuiData);
694
695 InvalidateRect(GuiData->hWindow, NULL, TRUE);
696
697 /*
698 * Apply full-screen mode.
699 */
700 if (GuiInfo.FullScreen != GuiData->GuiInfo.FullScreen)
701 {
702 SwitchFullScreen(GuiData, GuiInfo.FullScreen);
703 }
704 }
705
706 #if 0
707 /*
708 * Save settings if needed
709 */
710 // FIXME: Do it in the console properties applet ??
711 if (SaveSettings)
712 {
713 DWORD ProcessId = HandleToUlong(ProcessData->Process->ClientId.UniqueProcess);
714 ConSrvWriteUserSettings(&ConInfo, ProcessId);
715 GuiConsoleWriteUserSettings(&GuiInfo, ConInfo.ConsoleTitle, ProcessId);
716 }
717 #endif
718
719 Status = STATUS_SUCCESS;
720 }
721 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
722 {
723 Status = _SEH2_GetExceptionCode();
724 DPRINT1("GuiApplyUserSettings - Caught an exception, Status = %08X\n", Status);
725 }
726 _SEH2_END;
727
728 Quit:
729 /* Finally, close the section and return */
730 if (hSection)
731 {
732 NtUnmapViewOfSection(NtCurrentProcess(), pConInfo);
733 NtClose(hSection);
734 }
735
736 LeaveCriticalSection(&Console->Lock);
737 return;
738 }
739
740 /* EOF */