Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

310 lines
7.6 KiB

  1. /*************************************************************************
  2. *
  3. * icadis.c
  4. *
  5. * Send notice of ICA disconnect
  6. *
  7. * Copyright (c) 1985 - 1999, Microsoft Corporation
  8. *
  9. * $Author:
  10. *
  11. *************************************************************************/
  12. /*
  13. * Includes
  14. */
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "ntuser.h"
  18. #include <winsta.h>
  19. #include <wstmsg.h>
  20. #include <icadd.h>
  21. HANDLE WinStationIcaApiPort = NULL;
  22. /*******************************************************************************
  23. *
  24. * ConnectToTerminalServer
  25. *
  26. * ENTRY:
  27. * Access (input)
  28. * security access
  29. *
  30. * EXIT:
  31. * STATUS_SUCCESS - successful
  32. *
  33. ******************************************************************************/
  34. NTSTATUS
  35. ConnectToTerminalServer(
  36. ULONG Access,
  37. PHANDLE pPortHandle)
  38. {
  39. UNICODE_STRING PortName;
  40. SECURITY_QUALITY_OF_SERVICE DynamicQos;
  41. WINSTATIONAPI_CONNECT_INFO info;
  42. ULONG ConnectInfoLength;
  43. NTSTATUS Status;
  44. /*
  45. * Set up SM API port name
  46. */
  47. RtlInitUnicodeString(&PortName, L"\\SmSsWinStationApiPort");
  48. /*
  49. * Set up the security quality of service parameters to use over the
  50. * port. Use the most efficient (least overhead) - which is dynamic
  51. * rather than static tracking.
  52. */
  53. DynamicQos.ImpersonationLevel = SecurityImpersonation;
  54. DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  55. DynamicQos.EffectiveOnly = TRUE;
  56. /*
  57. * Fill in the ConnectInfo structure with our access request mask
  58. */
  59. info.Version = CITRIX_WINSTATIONAPI_VERSION;
  60. info.RequestedAccess = Access;
  61. ConnectInfoLength = sizeof(WINSTATIONAPI_CONNECT_INFO);
  62. // Attempt to connect to the Session Manager API port
  63. Status = NtConnectPort(pPortHandle,
  64. &PortName,
  65. &DynamicQos,
  66. NULL,
  67. NULL,
  68. NULL, // Max message length [select default]
  69. (PVOID)&info,
  70. &ConnectInfoLength);
  71. if (!NT_SUCCESS(Status)) {
  72. // Look at the returned INFO to see why if desired
  73. *pPortHandle = NULL;
  74. #if DBG
  75. if (ConnectInfoLength == sizeof(WINSTATIONAPI_CONNECT_INFO)) {
  76. DbgPrint("WinstationConnectToICASrv: connect failed, Reason 0x%x\n", info.AcceptStatus);
  77. }
  78. DbgPrint("WinstationConnectToICASrv: Connect failed 0x%x\n", Status);
  79. #endif
  80. return (Status);
  81. }
  82. return (STATUS_SUCCESS);
  83. }
  84. /*******************************************************************************
  85. *
  86. * BrokenConnection
  87. *
  88. * ENTRY:
  89. * Reason code
  90. *
  91. * EXIT:
  92. * STATUS_SUCCESS - successful
  93. *
  94. ******************************************************************************/
  95. NTSTATUS
  96. BrokenConnection(
  97. BROKENCLASS Reason,
  98. BROKENSOURCECLASS Source)
  99. {
  100. WINSTATION_APIMSG Msg;
  101. NTSTATUS Status;
  102. /*
  103. * Connect to Session Mgr
  104. */
  105. if (WinStationIcaApiPort == NULL) {
  106. Status = ConnectToTerminalServer(0, &WinStationIcaApiPort);
  107. if (!NT_SUCCESS(Status)) {
  108. return (Status);
  109. }
  110. }
  111. Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
  112. Msg.h.u1.s1.TotalLength = sizeof(Msg);
  113. Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
  114. Msg.h.u2.s2.DataInfoOffset = 0;
  115. Msg.WaitForReply = TRUE;
  116. Msg.ApiNumber = SMWinStationBrokenConnection;
  117. Msg.ReturnedStatus = 0;
  118. Msg.u.Broken.Reason = Reason;
  119. Msg.u.Broken.Source = Source;
  120. Status = NtRequestWaitReplyPort(WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
  121. #if DBG
  122. if (!NT_SUCCESS(Status)) {
  123. DbgPrint("BrokenConnection: rc=0x%x\n", Status);
  124. }
  125. #endif
  126. return (Status);
  127. }
  128. /*******************************************************************************
  129. *
  130. * ReplyMessageToTerminalServer
  131. *
  132. * ENTRY:
  133. *
  134. * EXIT:
  135. * STATUS_SUCCESS - successful
  136. *
  137. ******************************************************************************/
  138. NTSTATUS
  139. ReplyMessageToTerminalServer(
  140. NTSTATUS ReplyStatus,
  141. PNTSTATUS pStatus,
  142. ULONG Response,
  143. PULONG pResponse,
  144. HANDLE hEvent
  145. )
  146. {
  147. WINSTATION_APIMSG Msg;
  148. NTSTATUS Status;
  149. HANDLE PortHandle;
  150. /*
  151. * Connect to Session Mgr
  152. */
  153. Status = ConnectToTerminalServer(0, &PortHandle);
  154. if (!NT_SUCCESS(Status)) {
  155. return (Status);
  156. }
  157. Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
  158. Msg.h.u1.s1.TotalLength = sizeof(Msg);
  159. Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
  160. Msg.h.u2.s2.DataInfoOffset = 0;
  161. Msg.WaitForReply = TRUE;
  162. Msg.ApiNumber = SMWinStationIcaReplyMessage;
  163. Msg.ReturnedStatus = 0;
  164. Msg.u.ReplyMessage.Response = Response;
  165. Msg.u.ReplyMessage.pResponse = pResponse;
  166. Msg.u.ReplyMessage.hEvent = hEvent;
  167. Msg.u.ReplyMessage.Status = ReplyStatus;
  168. Msg.u.ReplyMessage.pStatus = pStatus;
  169. Status = NtRequestWaitReplyPort(PortHandle, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
  170. #if DBG
  171. if (!NT_SUCCESS(Status)) {
  172. DbgPrint("ReplyMessageToTerminalServer: rc=0x%x\n", Status);
  173. }
  174. #endif
  175. NtClose(PortHandle);
  176. return (Status);
  177. }
  178. NTSTATUS ReplyInvalidWindowToTerminalServer (HWND hWnd, ULONG ulSessionId)
  179. {
  180. WINSTATION_APIMSG Msg;
  181. NTSTATUS Status;
  182. HANDLE PortHandle;
  183. /*
  184. * Connect to Session Mgr
  185. */
  186. Status = ConnectToTerminalServer(0, &PortHandle);
  187. if (!NT_SUCCESS(Status)) {
  188. return (Status);
  189. }
  190. Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
  191. Msg.h.u1.s1.TotalLength = sizeof(Msg);
  192. Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
  193. Msg.h.u2.s2.DataInfoOffset = 0;
  194. Msg.WaitForReply = FALSE;
  195. Msg.ApiNumber = SMWinStationWindowInvalid;
  196. Msg.ReturnedStatus = 0;
  197. Msg.u.WindowInvalid.hWnd = HandleToULong(hWnd);
  198. Msg.u.WindowInvalid.SessionId = ulSessionId;
  199. Status = NtRequestPort(PortHandle, (PPORT_MESSAGE)&Msg);
  200. #if DBG
  201. if (!NT_SUCCESS(Status)) {
  202. DbgPrint("ReplyInvalidWindowToTerminalServer: rc=0x%x\n", Status);
  203. }
  204. #endif
  205. NtClose(PortHandle);
  206. return (Status);
  207. }
  208. /*******************************************************************************
  209. *
  210. * ShadowHotkey
  211. *
  212. * ENTRY:
  213. * none
  214. *
  215. * EXIT:
  216. * STATUS_SUCCESS - successful
  217. *
  218. ******************************************************************************/
  219. NTSTATUS
  220. ShadowHotkey()
  221. {
  222. WINSTATION_APIMSG Msg;
  223. NTSTATUS Status;
  224. /*
  225. * Connect to Session Mgr
  226. */
  227. if (WinStationIcaApiPort == NULL) {
  228. Status = ConnectToTerminalServer(0, &WinStationIcaApiPort);
  229. if (!NT_SUCCESS(Status)) {
  230. return (Status);
  231. }
  232. }
  233. Msg.h.u1.s1.DataLength = sizeof(Msg) - sizeof(PORT_MESSAGE);
  234. Msg.h.u1.s1.TotalLength = sizeof(Msg);
  235. Msg.h.u2.s2.Type = 0; // Kernel will fill in message type
  236. Msg.h.u2.s2.DataInfoOffset = 0;
  237. Msg.WaitForReply = TRUE;
  238. Msg.ApiNumber = SMWinStationIcaShadowHotkey;
  239. Msg.ReturnedStatus = 0;
  240. Status = NtRequestWaitReplyPort(WinStationIcaApiPort, (PPORT_MESSAGE)&Msg, (PPORT_MESSAGE)&Msg);
  241. #if DBG
  242. if (!NT_SUCCESS(Status)) {
  243. DbgPrint("ShadowHotkey: rc=0x%x\n", Status);
  244. }
  245. #endif
  246. return (Status);
  247. }