Windows2000/private/ntos/w32/ntuser/server/command.c
2020-09-30 17:12:32 +02:00

211 lines
5.7 KiB
C

/*
* command.c
* WinStation command channel handler
* Copyright (c) 1985 - 1999, Microsoft Corporation
* $Author:
*/
/*
* Includes
*/
#include "precomp.h"
#pragma hdrstop
#include "ntuser.h"
#include <winsta.h>
#include <wstmsg.h>
#include <icadd.h>
extern HANDLE G_IcaVideoChannel;
extern HANDLE G_IcaCommandChannel;
extern HANDLE WinStationIcaApiPort;
extern NTSTATUS BrokenConnection(BROKENCLASS, BROKENSOURCECLASS);
extern NTSTATUS ShadowHotkey(VOID);
NTSTATUS
Win32CommandChannelThread(
IN PVOID ThreadParameter)
{
ICA_CHANNEL_COMMAND Command;
PTEB Teb;
ULONG ActualLength;
NTSTATUS Status;
ULONG Error;
OVERLAPPED Overlapped;
/*
* Initialize GDI accelerators. Identify this thread as a server thread.
*/
Teb = NtCurrentTeb();
Teb->GdiClientPID = 4; // PID_SERVERLPC
Teb->GdiClientTID = HandleToUlong(Teb->ClientId.UniqueThread);
for ( ; ; ) {
memset(&Overlapped, 0, sizeof(Overlapped));
if (!ReadFile(G_IcaCommandChannel,
&Command,
sizeof(Command),
&ActualLength,
&Overlapped)) {
Error = GetLastError();
if (Error == ERROR_IO_PENDING) {
/*
* check on the results of the asynchronous read
*/
if (!GetOverlappedResult(G_IcaCommandChannel, &Overlapped,
&ActualLength, TRUE)) {
// wait for result
DBGHYD(("Command Channel: Error 0x%x from GetOverlappedResult\n",
GetLastError()));
break;
}
} else {
DBGHYD(("Command Channel: Error 0x%x from ReadFile\n",
Error));
break;
}
}
if (ActualLength < sizeof(ICA_COMMAND_HEADER)) {
DBGHYD(("Command Channel Thread bad length 0x%x\n",
ActualLength));
continue;
}
switch (Command.Header.Command) {
case ICA_COMMAND_BROKEN_CONNECTION:
/*
* broken procedure
*/
Status = BrokenConnection(
Command.BrokenConnection.Reason,
Command.BrokenConnection.Source);
if (!NT_SUCCESS(Status)) {
DBGHYD(("BrokenConnection failed with Status 0x%x\n",
Status));
}
break;
case ICA_COMMAND_REDRAW_RECTANGLE:
/*
* setfocus ???
*/
if (ActualLength < sizeof(ICA_COMMAND_HEADER) + sizeof(ICA_REDRAW_RECTANGLE)) {
DBGHYD(("Command Channel: redraw rect bad length %d\n",
ActualLength));
break;
}
Status = NtUserRemoteRedrawRectangle(
Command.RedrawRectangle.Rect.Left,
Command.RedrawRectangle.Rect.Top,
Command.RedrawRectangle.Rect.Right,
Command.RedrawRectangle.Rect.Bottom);
if (!NT_SUCCESS(Status)) {
DBGHYD(("NtUserRemoteRedrawRectangle failed with Status 0x%x\n",
Status));
}
break;
case ICA_COMMAND_REDRAW_SCREEN: // setfocus
Status = NtUserRemoteRedrawScreen();
if (!NT_SUCCESS(Status)) {
DBGHYD(("NtUserRemoteRedrawScreen failed with Status 0x%x\n",
Status));
}
break;
case ICA_COMMAND_STOP_SCREEN_UPDATES: // killfocus
Status = NtUserRemoteStopScreenUpdates();
if (!NT_SUCCESS(Status)) {
DBGHYD(("NtUserRemoteStopScreenUpdates failed with Status 0x%x\n",
Status));
} else {
IO_STATUS_BLOCK IoStatus;
NtDeviceIoControlFile( G_IcaVideoChannel,
NULL,
NULL,
NULL,
&IoStatus,
IOCTL_VIDEO_ICA_STOP_OK,
NULL,
0,
NULL,
0);
}
break;
case ICA_COMMAND_SHADOW_HOTKEY: // shadow hotkey
Status = ShadowHotkey();
if (!NT_SUCCESS(Status)) {
DBGHYD(("ShadowHotkey failed with Status 0x%x\n",
Status));
}
break;
case ICA_COMMAND_DISPLAY_IOCTL:
Status = NtUserCtxDisplayIOCtl(
Command.DisplayIOCtl.DisplayIOCtlFlags,
&Command.DisplayIOCtl.DisplayIOCtlData[0],
Command.DisplayIOCtl.cbDisplayIOCtlData);
if (!NT_SUCCESS(Status)) {
DBGHYD(("NtUserCtxDisplayIOCtl failed with Status 0x%x\n",
Status));
}
break;
default:
DBGHYD(("Command Channel: Bad Command 0x%x\n",
Command.Header.Command));
break;
}
}
/*
* Close command channel LPC port if there is one.
*/
if (WinStationIcaApiPort) {
NtClose(WinStationIcaApiPort);
WinStationIcaApiPort = NULL;
}
ExitThread(0);
/*
* Make the compiler happy
*/
return STATUS_UNSUCCESSFUL;
UNREFERENCED_PARAMETER(ThreadParameter);
}