00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include "precomp.h"
00017
#pragma hdrstop
00018
00019
#include "ntuser.h"
00020
00021
#include <winsta.h>
00022
#include <wstmsg.h>
00023
00024
#include <icadd.h>
00025
00026 extern HANDLE
G_IcaVideoChannel;
00027 extern HANDLE
G_IcaCommandChannel;
00028 extern HANDLE
WinStationIcaApiPort;
00029
00030
00031
extern NTSTATUS BrokenConnection(BROKENCLASS, BROKENSOURCECLASS);
00032
extern NTSTATUS ShadowHotkey(VOID);
00033
00034
NTSTATUS
00035 Win32CommandChannelThread(
00036 IN PVOID ThreadParameter)
00037 {
00038 ICA_CHANNEL_COMMAND Command;
00039 PTEB Teb;
00040 ULONG ActualLength;
00041
NTSTATUS Status;
00042 ULONG
Error;
00043 OVERLAPPED Overlapped;
00044
00045
00046
00047
00048 Teb = NtCurrentTeb();
00049 Teb->GdiClientPID = 4;
00050 Teb->GdiClientTID = HandleToUlong(Teb->ClientId.UniqueThread);
00051
00052
for ( ; ; ) {
00053
00054 memset(&Overlapped, 0,
sizeof(Overlapped));
00055
00056
if (!ReadFile(
G_IcaCommandChannel,
00057 &Command,
00058
sizeof(Command),
00059 &ActualLength,
00060 &Overlapped)) {
00061
00062
Error = GetLastError();
00063
00064
if (
Error == ERROR_IO_PENDING) {
00065
00066
00067
00068
00069
if (!GetOverlappedResult(
G_IcaCommandChannel, &Overlapped,
00070 &ActualLength,
TRUE)) {
00071
00072
00073
DBGHYD((
"Command Channel: Error 0x%x from GetOverlappedResult\n",
00074 GetLastError()));
00075
break;
00076 }
00077 }
else {
00078
DBGHYD((
"Command Channel: Error 0x%x from ReadFile\n",
00079
Error));
00080
break;
00081 }
00082 }
00083
00084
if (ActualLength <
sizeof(ICA_COMMAND_HEADER)) {
00085
00086
DBGHYD((
"Command Channel Thread bad length 0x%x\n",
00087 ActualLength));
00088
continue;
00089 }
00090
00091
switch (Command.Header.Command) {
00092
00093
case ICA_COMMAND_BROKEN_CONNECTION:
00094
00095
00096
00097
Status =
BrokenConnection(
00098 Command.BrokenConnection.Reason,
00099 Command.BrokenConnection.Source);
00100
00101
if (!
NT_SUCCESS(
Status)) {
00102
DBGHYD((
"BrokenConnection failed with Status 0x%x\n",
00103
Status));
00104 }
00105
break;
00106
00107
case ICA_COMMAND_REDRAW_RECTANGLE:
00108
00109
00110
00111
if (ActualLength <
sizeof(ICA_COMMAND_HEADER) +
sizeof(ICA_REDRAW_RECTANGLE)) {
00112
00113
DBGHYD((
"Command Channel: redraw rect bad length %d\n",
00114 ActualLength));
00115
break;
00116 }
00117
Status =
NtUserRemoteRedrawRectangle(
00118 Command.RedrawRectangle.Rect.Left,
00119 Command.RedrawRectangle.Rect.Top,
00120 Command.RedrawRectangle.Rect.Right,
00121 Command.RedrawRectangle.Rect.Bottom);
00122
00123
if (!
NT_SUCCESS(
Status)) {
00124
DBGHYD((
"NtUserRemoteRedrawRectangle failed with Status 0x%x\n",
00125
Status));
00126 }
00127
break;
00128
00129
case ICA_COMMAND_REDRAW_SCREEN:
00130
00131
Status =
NtUserRemoteRedrawScreen();
00132
00133
if (!
NT_SUCCESS(
Status)) {
00134
DBGHYD((
"NtUserRemoteRedrawScreen failed with Status 0x%x\n",
00135
Status));
00136 }
00137
break;
00138
00139
case ICA_COMMAND_STOP_SCREEN_UPDATES:
00140
00141
Status =
NtUserRemoteStopScreenUpdates();
00142
00143
if (!
NT_SUCCESS(
Status)) {
00144
DBGHYD((
"NtUserRemoteStopScreenUpdates failed with Status 0x%x\n",
00145
Status));
00146 }
else {
00147 IO_STATUS_BLOCK IoStatus;
00148
00149
NtDeviceIoControlFile(
G_IcaVideoChannel,
00150
NULL,
00151
NULL,
00152
NULL,
00153 &IoStatus,
00154 IOCTL_VIDEO_ICA_STOP_OK,
00155
NULL,
00156 0,
00157
NULL,
00158 0);
00159 }
00160
break;
00161
00162
case ICA_COMMAND_SHADOW_HOTKEY:
00163
00164
Status =
ShadowHotkey();
00165
00166
if (!
NT_SUCCESS(
Status)) {
00167
DBGHYD((
"ShadowHotkey failed with Status 0x%x\n",
00168
Status));
00169 }
00170
break;
00171
00172
case ICA_COMMAND_DISPLAY_IOCTL:
00173
00174
Status =
NtUserCtxDisplayIOCtl(
00175 Command.DisplayIOCtl.DisplayIOCtlFlags,
00176 &Command.DisplayIOCtl.DisplayIOCtlData[0],
00177 Command.DisplayIOCtl.cbDisplayIOCtlData);
00178
00179
if (!
NT_SUCCESS(
Status)) {
00180
DBGHYD((
"NtUserCtxDisplayIOCtl failed with Status 0x%x\n",
00181
Status));
00182 }
00183
break;
00184
00185
default:
00186
00187
DBGHYD((
"Command Channel: Bad Command 0x%x\n",
00188 Command.Header.Command));
00189
break;
00190 }
00191
00192 }
00193
00194
00195
00196
00197
if (
WinStationIcaApiPort) {
00198
NtClose(
WinStationIcaApiPort);
00199
WinStationIcaApiPort =
NULL;
00200
00201 }
00202
00203
00204 ExitThread(0);
00205
00206
00207
00208
return STATUS_UNSUCCESSFUL;
00209 UNREFERENCED_PARAMETER(ThreadParameter);
00210 }