2021-09-13 01:33:14 +00:00
|
|
|
/*
|
2015-03-11 01:21:29 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Win32k subsystem
|
|
|
|
* PURPOSE: Console support functions for CONSRV
|
2015-11-10 17:41:55 +00:00
|
|
|
* FILE: win32ss/user/ntuser/console.c
|
2015-03-11 01:21:29 +00:00
|
|
|
* PROGRAMMER: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <win32k.h>
|
|
|
|
DBG_DEFAULT_CHANNEL(UserMisc);
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
APIENTRY
|
|
|
|
NtUserConsoleControl(
|
|
|
|
IN CONSOLECONTROL ConsoleCtrl,
|
|
|
|
IN PVOID ConsoleCtrlInfo,
|
|
|
|
IN ULONG ConsoleCtrlInfoLength)
|
|
|
|
{
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
/* Allow only the Console Server to perform this operation (via CSRSS) */
|
|
|
|
if (PsGetCurrentProcess() != gpepCSRSS)
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
|
|
|
|
UserEnterExclusive();
|
|
|
|
|
|
|
|
switch (ConsoleCtrl)
|
|
|
|
{
|
|
|
|
case ConsoleCtrlDesktopConsoleThread:
|
|
|
|
{
|
|
|
|
DESKTOP_CONSOLE_THREAD DesktopConsoleThreadInfo;
|
|
|
|
PDESKTOP Desktop = NULL;
|
|
|
|
ULONG_PTR OldThreadId;
|
|
|
|
|
|
|
|
if (ConsoleCtrlInfoLength != sizeof(DesktopConsoleThreadInfo))
|
|
|
|
{
|
|
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForWrite(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
|
|
|
|
DesktopConsoleThreadInfo = *(PDESKTOP_CONSOLE_THREAD)ConsoleCtrlInfo;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
_SEH2_YIELD(break);
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
/* Reference the desktop */
|
|
|
|
Status = ObReferenceObjectByHandle(DesktopConsoleThreadInfo.DesktopHandle,
|
|
|
|
0,
|
|
|
|
ExDesktopObjectType,
|
|
|
|
UserMode,
|
|
|
|
(PVOID*)&Desktop,
|
|
|
|
NULL);
|
|
|
|
if (!NT_SUCCESS(Status)) break;
|
|
|
|
|
|
|
|
/* Save the old thread ID, it is always returned to the caller */
|
|
|
|
OldThreadId = Desktop->dwConsoleThreadId;
|
|
|
|
|
|
|
|
/* Set the new console input thread ID for this desktop if required */
|
|
|
|
if (DesktopConsoleThreadInfo.ThreadId != (ULONG_PTR)INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
Desktop->dwConsoleThreadId = DesktopConsoleThreadInfo.ThreadId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Always return the old thread ID */
|
|
|
|
DesktopConsoleThreadInfo.ThreadId = OldThreadId;
|
|
|
|
|
|
|
|
/* Dereference the desktop */
|
|
|
|
ObDereferenceObject(Desktop);
|
|
|
|
|
|
|
|
/* Return the information back to the caller */
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
*(PDESKTOP_CONSOLE_THREAD)ConsoleCtrlInfo = DesktopConsoleThreadInfo;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case GuiConsoleWndClassAtom:
|
|
|
|
{
|
|
|
|
if (ConsoleCtrlInfoLength != sizeof(ATOM))
|
|
|
|
{
|
|
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
|
|
|
|
gaGuiConsoleWndClass = *(ATOM*)ConsoleCtrlInfo;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ConsoleMakePalettePublic:
|
|
|
|
{
|
|
|
|
HPALETTE hPalette;
|
|
|
|
|
|
|
|
if (ConsoleCtrlInfoLength != sizeof(hPalette))
|
|
|
|
{
|
|
|
|
Status = STATUS_INFO_LENGTH_MISMATCH;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
_SEH2_TRY
|
|
|
|
{
|
|
|
|
ProbeForRead(ConsoleCtrlInfo, ConsoleCtrlInfoLength, sizeof(USHORT));
|
|
|
|
hPalette = *(HPALETTE*)ConsoleCtrlInfo;
|
|
|
|
}
|
|
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
|
|
{
|
|
|
|
Status = _SEH2_GetExceptionCode();
|
|
|
|
_SEH2_YIELD(break);
|
|
|
|
}
|
|
|
|
_SEH2_END;
|
|
|
|
|
|
|
|
/* Make the palette handle public */
|
|
|
|
GreSetObjectOwnerEx(hPalette,
|
|
|
|
GDI_OBJ_HMGR_PUBLIC,
|
|
|
|
GDIOBJFLAG_IGNOREPID);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
case ConsoleAcquireDisplayOwnership:
|
|
|
|
{
|
|
|
|
ERR("NtUserConsoleControl - ConsoleAcquireDisplayOwnership is UNIMPLEMENTED\n");
|
|
|
|
Status = STATUS_NOT_IMPLEMENTED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
default:
|
|
|
|
ERR("Calling invalid control %d in NtUserConsoleControl\n", ConsoleCtrl);
|
|
|
|
Status = STATUS_INVALID_INFO_CLASS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
UserLeave();
|
|
|
|
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* EOF */
|