xref: /reactos/win32ss/user/ntuser/console.c (revision 8a978a17)
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS Win32k subsystem
4  * PURPOSE:          Console support functions for CONSRV
5  * FILE:             win32ss/user/ntuser/console.c
6  * PROGRAMMER:       Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7  */
8 
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(UserMisc);
11 
12 NTSTATUS
13 APIENTRY
14 NtUserConsoleControl(
15     IN CONSOLECONTROL ConsoleCtrl,
16     IN PVOID ConsoleCtrlInfo,
17     IN ULONG ConsoleCtrlInfoLength)
18 {
19     NTSTATUS Status = STATUS_SUCCESS;
20 
21     /* Allow only the Console Server to perform this operation (via CSRSS) */
22     if (PsGetCurrentProcess() != gpepCSRSS)
23         return STATUS_ACCESS_DENIED;
24 
25     UserEnterExclusive();
26 
27     switch (ConsoleCtrl)
28     {
29         case ConsoleCtrlDesktopConsoleThread:
30         {
31             DESKTOP_CONSOLE_THREAD DesktopConsoleThreadInfo;
32             PDESKTOP Desktop = NULL;
33             ULONG_PTR OldThreadId;
34 
35             if (ConsoleCtrlInfoLength != sizeof(DesktopConsoleThreadInfo))
36             {
37                 Status = STATUS_INFO_LENGTH_MISMATCH;
38                 break;
39             }
40 
41             _SEH2_TRY
42             {
43                 ProbeForWrite(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
44                 DesktopConsoleThreadInfo = *(PDESKTOP_CONSOLE_THREAD)ConsoleCtrlInfo;
45             }
46             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
47             {
48                 Status = _SEH2_GetExceptionCode();
49                 _SEH2_YIELD(break);
50             }
51             _SEH2_END;
52 
53             /* Reference the desktop */
54             Status = ObReferenceObjectByHandle(DesktopConsoleThreadInfo.DesktopHandle,
55                                                0,
56                                                ExDesktopObjectType,
57                                                UserMode,
58                                                (PVOID*)&Desktop,
59                                                NULL);
60             if (!NT_SUCCESS(Status)) break;
61 
62             /* Save the old thread ID, it is always returned to the caller */
63             OldThreadId = Desktop->dwConsoleThreadId;
64 
65             /* Set the new console input thread ID for this desktop if required */
66             if (DesktopConsoleThreadInfo.ThreadId != (ULONG_PTR)INVALID_HANDLE_VALUE)
67             {
68                 Desktop->dwConsoleThreadId = DesktopConsoleThreadInfo.ThreadId;
69             }
70 
71             /* Always return the old thread ID */
72             DesktopConsoleThreadInfo.ThreadId = OldThreadId;
73 
74             /* Dereference the desktop */
75             ObDereferenceObject(Desktop);
76 
77             /* Return the information back to the caller */
78             _SEH2_TRY
79             {
80                 *(PDESKTOP_CONSOLE_THREAD)ConsoleCtrlInfo = DesktopConsoleThreadInfo;
81             }
82             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
83             {
84                 Status = _SEH2_GetExceptionCode();
85             }
86             _SEH2_END;
87 
88             break;
89         }
90 
91         case GuiConsoleWndClassAtom:
92         {
93             if (ConsoleCtrlInfoLength != sizeof(ATOM))
94             {
95                 Status = STATUS_INFO_LENGTH_MISMATCH;
96                 break;
97             }
98 
99             _SEH2_TRY
100             {
101                 ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
102                 gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo;
103             }
104             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
105             {
106                 Status = _SEH2_GetExceptionCode();
107             }
108             _SEH2_END;
109 
110             break;
111         }
112 
113         case ConsoleMakePalettePublic:
114         {
115             HPALETTE hPalette;
116 
117             if (ConsoleCtrlInfoLength != sizeof(hPalette))
118             {
119                 Status = STATUS_INFO_LENGTH_MISMATCH;
120                 break;
121             }
122 
123             _SEH2_TRY
124             {
125                 ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
126                 hPalette = *(HPALETTE*)ConsoleCtrlInfo;
127             }
128             _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
129             {
130                 Status = _SEH2_GetExceptionCode();
131                 _SEH2_YIELD(break);
132             }
133             _SEH2_END;
134 
135             /* Make the palette handle public */
136             GreSetObjectOwnerEx(hPalette,
137                                 GDI_OBJ_HMGR_PUBLIC,
138                                 GDIOBJFLAG_IGNOREPID);
139             break;
140         }
141 
142         case ConsoleAcquireDisplayOwnership:
143         {
144             ERR("NtUserConsoleControl - ConsoleAcquireDisplayOwnership is UNIMPLEMENTED\n");
145             Status = STATUS_NOT_IMPLEMENTED;
146             break;
147         }
148 
149         default:
150             ERR("Calling invalid control %d in NtUserConsoleControl\n", ConsoleCtrl);
151             Status = STATUS_INVALID_INFO_CLASS;
152             break;
153     }
154 
155     UserLeave();
156 
157     return Status;
158 }
159 
160 /* EOF */
161