00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
#include "precomp.h"
00018
#pragma hdrstop
00019
00020
#include "ntuser.h"
00021
00022
#include <winsta.h>
00023
#include <wstmsg.h>
00024
#include <icadd.h>
00025
00026 HANDLE
WinStationIcaApiPort =
NULL;
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
NTSTATUS
00042 ConnectToTerminalServer(
00043 ULONG Access,
00044 PHANDLE pPortHandle)
00045 {
00046 UNICODE_STRING
PortName;
00047 SECURITY_QUALITY_OF_SERVICE
DynamicQos;
00048 WINSTATIONAPI_CONNECT_INFO info;
00049 ULONG ConnectInfoLength;
00050
NTSTATUS Status;
00051
00052
00053
00054
00055
RtlInitUnicodeString(&
PortName,
L"\\SmSsWinStationApiPort");
00056
00057
00058
00059
00060
00061
00062
DynamicQos.ImpersonationLevel = SecurityImpersonation;
00063
DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
00064
DynamicQos.EffectiveOnly =
TRUE;
00065
00066
00067
00068
00069 info.Version = CITRIX_WINSTATIONAPI_VERSION;
00070 info.RequestedAccess = Access;
00071 ConnectInfoLength =
sizeof(WINSTATIONAPI_CONNECT_INFO);
00072
00073
00074
Status =
NtConnectPort(pPortHandle,
00075 &
PortName,
00076 &
DynamicQos,
00077
NULL,
00078
NULL,
00079
NULL,
00080 (PVOID)&info,
00081 &ConnectInfoLength);
00082
if (!
NT_SUCCESS(
Status)) {
00083
00084 *pPortHandle =
NULL;
00085
#if DBG
00086
if (ConnectInfoLength ==
sizeof(WINSTATIONAPI_CONNECT_INFO)) {
00087
DbgPrint(
"WinstationConnectToICASrv: connect failed, Reason 0x%x\n", info.AcceptStatus);
00088 }
00089
DbgPrint(
"WinstationConnectToICASrv: Connect failed 0x%x\n",
Status);
00090
#endif
00091
return (
Status);
00092 }
00093
00094
return (STATUS_SUCCESS);
00095 }
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
NTSTATUS
00112 BrokenConnection(
00113 BROKENCLASS Reason,
00114 BROKENSOURCECLASS Source)
00115 {
00116 WINSTATION_APIMSG Msg;
00117
NTSTATUS Status;
00118
00119
00120
00121
00122
if (
WinStationIcaApiPort ==
NULL) {
00123
Status =
ConnectToTerminalServer(0, &
WinStationIcaApiPort);
00124
if (!
NT_SUCCESS(
Status)) {
00125
return (
Status);
00126 }
00127 }
00128
00129
00130 Msg.h.u1.s1.DataLength =
sizeof(Msg) -
sizeof(PORT_MESSAGE);
00131 Msg.h.u1.s1.TotalLength =
sizeof(Msg);
00132 Msg.h.u2.s2.Type = 0;
00133 Msg.h.u2.s2.DataInfoOffset = 0;
00134 Msg.WaitForReply =
TRUE;
00135 Msg.ApiNumber = SMWinStationBrokenConnection;
00136 Msg.ReturnedStatus = 0;
00137
00138 Msg.u.Broken.Reason = Reason;
00139 Msg.u.Broken.Source = Source;
00140
00141
Status =
NtRequestWaitReplyPort(
WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
00142
00143
00144
00145
00146
#if DBG
00147
if (!
NT_SUCCESS(
Status)) {
00148
DbgPrint(
"BrokenConnection: rc=0x%x\n",
Status);
00149 }
00150
#endif
00151
00152
return (
Status);
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
NTSTATUS
00168 ReplyMessageToTerminalServer(
00169
PCTXHARDERRORINFO pchi)
00170 {
00171 WINSTATION_APIMSG Msg;
00172
NTSTATUS Status;
00173 HANDLE
PortHandle;
00174
00175
00176
00177
00178
Status =
ConnectToTerminalServer(0, &
PortHandle);
00179
if (!
NT_SUCCESS(
Status)) {
00180
return (
Status);
00181 }
00182
00183
00184
00185
00186
00187 Msg.h.u1.s1.DataLength =
sizeof(Msg) -
sizeof(PORT_MESSAGE);
00188 Msg.h.u1.s1.TotalLength =
sizeof(Msg);
00189 Msg.h.u2.s2.Type = 0;
00190 Msg.h.u2.s2.DataInfoOffset = 0;
00191 Msg.WaitForReply =
TRUE;
00192 Msg.ApiNumber = SMWinStationIcaReplyMessage;
00193 Msg.ReturnedStatus = 0;
00194
00195 Msg.u.ReplyMessage.Response = pchi->
Response;
00196 Msg.u.ReplyMessage.pResponse = pchi->
pResponse;
00197 Msg.u.ReplyMessage.hEvent = pchi->
hEvent;
00198
00199
Status =
NtRequestWaitReplyPort(
PortHandle, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
00200
00201
00202
00203
00204
00205
#if DBG
00206
if (!
NT_SUCCESS(
Status)) {
00207
DbgPrint(
"ReplyMessageToTerminalServer: rc=0x%x\n",
Status);
00208 }
00209
#endif
00210
NtClose(
PortHandle);
00211
00212
return (
Status);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
NTSTATUS
00228 ShadowHotkey()
00229 {
00230 WINSTATION_APIMSG Msg;
00231
NTSTATUS Status;
00232
00233
00234
00235
00236
if (
WinStationIcaApiPort ==
NULL) {
00237
Status =
ConnectToTerminalServer(0, &
WinStationIcaApiPort);
00238
if (!
NT_SUCCESS(
Status)) {
00239
return (
Status);
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248 Msg.h.u1.s1.DataLength =
sizeof(Msg) -
sizeof(PORT_MESSAGE);
00249 Msg.h.u1.s1.TotalLength =
sizeof(Msg);
00250 Msg.h.u2.s2.Type = 0;
00251 Msg.h.u2.s2.DataInfoOffset = 0;
00252 Msg.WaitForReply =
TRUE;
00253 Msg.ApiNumber = SMWinStationIcaShadowHotkey;
00254 Msg.ReturnedStatus = 0;
00255
00256
Status =
NtRequestWaitReplyPort(
WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
00257
00258
00259
00260
#if DBG
00261
if (!
NT_SUCCESS(
Status)) {
00262
DbgPrint(
"ShadowHotkey: rc=0x%x\n",
Status);
00263 }
00264
#endif
00265
00266
return (
Status);
00267 }