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 }