test: command.c Source File

Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

# command.c

Go to the documentation of this file.

    00001
    00002 /*************************************************************************
    00003 *
    00004 * command.c
    00005 *
    00006 * WinStation command channel handler
    00007 *
    00008 * Copyright (c) 1985 - 1999, Microsoft Corporation
    00009 *
    00010 * $Author:
    00011 *************************************************************************/
    00012
    00013 /*
    00014  *  Includes
    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      * Initialize GDI accelerators.  Identify this thread as a server thread.
    00047      */
    00048     Teb = NtCurrentTeb();
    00049     Teb->GdiClientPID = 4; // PID_SERVERLPC
    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                  * check on the results of the asynchronous read
    00068                  */
    00069                 if (!GetOverlappedResult(G_IcaCommandChannel, &Overlapped,
    00070                                          &ActualLength, TRUE)) {
    00071                     // wait for result
    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              * broken procedure
    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              * setfocus ???
    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: // setfocus
    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: // killfocus
    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: // 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      * Close command channel LPC port if there is one.
    00196      */
    00197     if (WinStationIcaApiPort) {
    00198         NtClose(WinStationIcaApiPort);
    00199         WinStationIcaApiPort = NULL;
    00200
    00201     }
    00202
    00203
    00204     ExitThread(0);
    00205     /*
    00206      * Make the compiler happy
    00207      */
    00208     return STATUS_UNSUCCESSFUL;
    00209     UNREFERENCED_PARAMETER(ThreadParameter);
    00210 }