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.

523 lines
17 KiB

  1. //*************************************************************
  2. //
  3. // File name: TSrvCon.c
  4. //
  5. // Description: Contains routines to provide TShareSRV
  6. // connection support
  7. //
  8. // Microsoft Confidential
  9. // Copyright (c) Microsoft Corporation 1991-1997
  10. // All rights reserved
  11. //
  12. //*************************************************************
  13. #define DC_HICOLOR
  14. #include <TSrv.h>
  15. #include <TSrvInfo.h>
  16. #include <TSrvCom.h>
  17. #include <TSrvTerm.h>
  18. #include <TSrvCon.h>
  19. #include <_TSrvCon.h>
  20. #include <_TSrvInfo.h>
  21. #include <TSrvSec.h>
  22. #include <at128.h>
  23. #include <at120ex.h>
  24. #include <ndcgmcro.h>
  25. //*************************************************************
  26. //
  27. // TSrvDoConnectResponse()
  28. //
  29. // Purpose: Performs the conf connect process
  30. //
  31. // Parameters: IN [pTSrvInfo] - GCC CreateIndicationMessage
  32. //
  33. // Return: STATUS_SUCCESS - Success
  34. // other - Failure
  35. //
  36. // History: 07-17-97 BrianTa Created
  37. //
  38. //*************************************************************
  39. NTSTATUS
  40. TSrvDoConnectResponse(IN PTSRVINFO pTSrvInfo)
  41. {
  42. NTSTATUS ntStatus;
  43. TRACE((DEBUG_TSHRSRV_FLOW,
  44. "TShrSRV: TSrvDoConnectResponse entry\n"));
  45. // Invoke routine to perform actual response
  46. ntStatus = TSrvConfCreateResp(pTSrvInfo);
  47. if (NT_SUCCESS(ntStatus))
  48. {
  49. EnterCriticalSection(&pTSrvInfo->cs);
  50. // If this connection was not told to terminate during the
  51. // connection response, then mark the conference state as
  52. // TSRV_GCC_CONF_CONNECTED
  53. if (!pTSrvInfo->fDisconnect)
  54. pTSrvInfo->fuConfState = TSRV_CONF_CONNECTED;
  55. LeaveCriticalSection(&pTSrvInfo->cs);
  56. // If we were unable to mark the conf state as CONNECTED, then
  57. // the connection needs to be terminated
  58. if (pTSrvInfo->fuConfState != TSRV_CONF_CONNECTED)
  59. {
  60. TRACE((DEBUG_TSHRSRV_NORMAL,
  61. "TShrSRV: Connection aborted due to termination request\n"));
  62. ntStatus = STATUS_REQUEST_ABORTED;
  63. }
  64. }
  65. TRACE((DEBUG_TSHRSRV_FLOW,
  66. "TShrSRV: TSrvDoConnectResponse exit - 0x%x\n", ntStatus));
  67. return (ntStatus);
  68. }
  69. //*************************************************************
  70. //
  71. // TSrvDoConnect()
  72. //
  73. // Purpose: Initiates the conf connect process
  74. //
  75. // Parameters: IN [pTSrvInfo] - GCC CreateIndicationMessage
  76. //
  77. // Return: STATUS_SUCCESS - Success
  78. // other - Failure
  79. //
  80. // History: 07-17-97 BrianTa Created
  81. //
  82. //*************************************************************
  83. NTSTATUS
  84. TSrvDoConnect(IN PTSRVINFO pTSrvInfo)
  85. {
  86. DWORD dwStatus;
  87. NTSTATUS ntStatus;
  88. TRACE((DEBUG_TSHRSRV_FLOW,
  89. "TShrSRV: TSrvDoConnect entry\n"));
  90. ntStatus = STATUS_TRANSACTION_ABORTED;
  91. if (pTSrvInfo->fDisconnect == FALSE)
  92. {
  93. TSrvReferenceInfo(pTSrvInfo);
  94. // Wait to be told that a connection is being
  95. // requested via the client
  96. TRACE((DEBUG_TSHRSRV_NORMAL,
  97. "TShrSRV: Waiting for connection Ind signal for pTSrvInfo 0x%x\n",
  98. pTSrvInfo));
  99. dwStatus = WaitForSingleObject(pTSrvInfo->hWorkEvent, 60000);
  100. TRACE((DEBUG_TSHRSRV_NORMAL,
  101. "TShrSRV: Connection Ind signal received for pTSrvInfo %p - 0x%x\n",
  102. pTSrvInfo, dwStatus));
  103. // If a client connection request has been recieved, then proceed
  104. // with the acknowledgement process (CreateResponse)
  105. switch (dwStatus)
  106. {
  107. case WAIT_OBJECT_0:
  108. if (pTSrvInfo->fDisconnect == FALSE)
  109. ntStatus = TSrvDoConnectResponse(pTSrvInfo);
  110. else
  111. ntStatus = STATUS_TRANSACTION_ABORTED;
  112. break;
  113. case WAIT_TIMEOUT:
  114. ntStatus = STATUS_IO_TIMEOUT;
  115. break;
  116. }
  117. TSrvDereferenceInfo(pTSrvInfo);
  118. }
  119. TRACE((DEBUG_TSHRSRV_FLOW,
  120. "TShrSRV: TSrvDoConnect exit - 0x%x\n", ntStatus));
  121. return (ntStatus);
  122. }
  123. //*************************************************************
  124. //
  125. // TSrvStackConnect()
  126. //
  127. // Purpose: Stack initiated connect
  128. //
  129. // Parameters: IN [hIca] - Ica handle
  130. // IN [hStack] - Ica stack
  131. // OUT [ppTSrvInfo] - Ptr to TSRVINFO ptr
  132. //
  133. // Return: STATUS_SUCCESS - Success
  134. // other - Failure
  135. //
  136. // History: 07-17-97 BrianTa Created
  137. //
  138. //*************************************************************
  139. NTSTATUS
  140. TSrvStackConnect(IN HANDLE hIca,
  141. IN HANDLE hStack,
  142. OUT PTSRVINFO *ppTSrvInfo)
  143. {
  144. NTSTATUS ntStatus;
  145. TRACE((DEBUG_TSHRSRV_FLOW,
  146. "TShrSRV: TSrvStackConnect entry\n"));
  147. ntStatus = STATUS_UNSUCCESSFUL;
  148. if (TSrvIsReady(TRUE))
  149. {
  150. TS_ASSERT(hStack);
  151. // Allocate a TSrvInfo object which will be used to
  152. // track this connection instance
  153. ntStatus = TSrvAllocInfo(ppTSrvInfo, hIca, hStack);
  154. if (NT_SUCCESS(ntStatus))
  155. {
  156. TS_ASSERT(*ppTSrvInfo);
  157. ntStatus = TSrvDoConnect(*ppTSrvInfo);
  158. }
  159. }
  160. TRACE((DEBUG_TSHRSRV_FLOW,
  161. "TShrSRV: TSrvStackConnect exit - 0x%x\n", ntStatus));
  162. return (ntStatus);
  163. }
  164. //*************************************************************
  165. //
  166. // TSrvConsoleConnect()
  167. //
  168. // Purpose: Connest to console session
  169. //
  170. // Parameters: IN [hIca] - Ica handle
  171. // IN [hStack] - Ica stack
  172. // OUT [ppTSrvInfo] - Ptr to TSRVINFO ptr
  173. //
  174. // Return: STATUS_SUCCESS - Success
  175. // other - Failure
  176. //
  177. // History: 11-02-98 MartinRichards (DCL) Created
  178. //
  179. //*************************************************************
  180. NTSTATUS
  181. TSrvConsoleConnect(IN HANDLE hIca,
  182. IN HANDLE hStack,
  183. IN PVOID pBuffer,
  184. IN ULONG ulBufferLength,
  185. OUT PTSRVINFO *ppTSrvInfo)
  186. {
  187. NTSTATUS ntStatus;
  188. PTSRVINFO pTSrvInfo;
  189. int i;
  190. ULONG ulInBufferSize;
  191. ULONG ulBytesReturned;
  192. PRNS_UD_CS_CORE pCoreData;
  193. PTSHARE_MODULE_DATA pModuleData = (PTSHARE_MODULE_DATA) pBuffer;
  194. PTSHARE_MODULE_DATA_B3 pModuleDataB3 = (PTSHARE_MODULE_DATA_B3) pBuffer;
  195. HDC hdc;
  196. int screenBpp;
  197. TRACE((DEBUG_TSHRSRV_FLOW,
  198. "TShrSRV: TSrvConsoleConnect entry\n"));
  199. ntStatus = STATUS_UNSUCCESSFUL;
  200. if (TSrvIsReady(TRUE))
  201. {
  202. TS_ASSERT(hStack);
  203. // Allocate a TSrvInfo object which will be used to
  204. // track this connection instance
  205. ntStatus = STATUS_NO_MEMORY;
  206. // Try allocating a TSRVINFO object
  207. pTSrvInfo = TSrvAllocInfoNew();
  208. // If we managed to get a TSRVINFO object, perform
  209. // default base initialization
  210. if (pTSrvInfo)
  211. {
  212. pTSrvInfo->hDomain = NULL;
  213. pTSrvInfo->hIca = hIca;
  214. pTSrvInfo->hStack = hStack;
  215. pTSrvInfo->fDisconnect = FALSE;
  216. pTSrvInfo->fConsoleStack = TRUE;
  217. pTSrvInfo->fuConfState = TSRV_CONF_PENDING;
  218. pTSrvInfo->ulReason = 0;
  219. pTSrvInfo->ntStatus = STATUS_SUCCESS;
  220. pTSrvInfo->bSecurityEnabled = FALSE;
  221. pTSrvInfo->SecurityInfo.CertType = CERT_TYPE_INVALID;
  222. /****************************************************************/
  223. /* Build the User data portion (remember that there is not */
  224. /* actually a real client to connect; instead we need to pass */
  225. /* in the relevant information about the console session) */
  226. /****************************************************************/
  227. ulInBufferSize = sizeof(USERDATAINFO) + sizeof(RNS_UD_CS_CORE);
  228. pTSrvInfo->pUserDataInfo = TSHeapAlloc(0, ulInBufferSize,
  229. TS_HTAG_TSS_USERDATA_OUT);
  230. if (pTSrvInfo->pUserDataInfo == NULL)
  231. {
  232. TRACE((DEBUG_TSHRSRV_ERROR,
  233. "TShrSRV: Failed to get user data memory\n"));
  234. ntStatus = STATUS_NO_MEMORY;
  235. goto Cleanup;
  236. }
  237. pTSrvInfo->pUserDataInfo->cbSize = sizeof(USERDATAINFO)
  238. + sizeof(RNS_UD_CS_CORE);
  239. pTSrvInfo->pUserDataInfo->version = RNS_UD_VERSION;
  240. pTSrvInfo->pUserDataInfo->hDomain = NULL;
  241. pTSrvInfo->pUserDataInfo->ulUserDataMembers = 1;
  242. pCoreData = (PRNS_UD_CS_CORE)(pTSrvInfo->pUserDataInfo->rgUserData);
  243. pCoreData->header.type = RNS_UD_CS_CORE_ID;
  244. pCoreData->header.length = sizeof(RNS_UD_CS_CORE);
  245. pCoreData->version = RNS_UD_VERSION;
  246. pCoreData->desktopWidth =
  247. (TSUINT16)GetSystemMetrics(SM_CXVIRTUALSCREEN);
  248. pCoreData->desktopHeight =
  249. (TSUINT16)GetSystemMetrics(SM_CYVIRTUALSCREEN);
  250. //
  251. // The fields colorDepth and supportedColorDepths of pCoreData are
  252. // used as temporary variables. The correct values are set before
  253. // sending the Ioctl below.
  254. //
  255. pCoreData->colorDepth = 0;
  256. pCoreData->supportedColorDepths = 0;
  257. //
  258. // Get the color depth and capabilities from the remote client.
  259. //
  260. // B3 and B3_oops! servers used a fixed length user data structure
  261. if ( (ulBufferLength == sizeof(TSHARE_MODULE_DATA_B3)) ||
  262. (ulBufferLength == sizeof(TSHARE_MODULE_DATA_B3_OOPS)) ) {
  263. pCoreData->colorDepth = pModuleDataB3->clientCoreData.colorDepth;
  264. } else if ( (ulBufferLength >= sizeof(TSHARE_MODULE_DATA)) &&
  265. (ulBufferLength == (sizeof(TSHARE_MODULE_DATA) +
  266. pModuleData->userDataLen - sizeof(RNS_UD_HEADER))) ) {
  267. PRNS_UD_HEADER pHeader;
  268. PRNS_UD_HEADER pEnd;
  269. PRNS_UD_CS_CORE pClientCoreData;
  270. pHeader = (PRNS_UD_HEADER) &pModuleData->userData;
  271. pEnd = (PRNS_UD_HEADER)((PBYTE)pHeader + pModuleData->userDataLen);
  272. // Loop through user data, extracting each piece.
  273. do {
  274. if ( pHeader->type == RNS_UD_CS_CORE_ID ) {
  275. pClientCoreData = (PRNS_UD_CS_CORE)pHeader;
  276. pCoreData->colorDepth = pClientCoreData->colorDepth;
  277. if (pClientCoreData->header.length >=
  278. (FIELDOFFSET(RNS_UD_CS_CORE, supportedColorDepths) +
  279. FIELDSIZE(RNS_UD_CS_CORE, supportedColorDepths))) {
  280. pCoreData->supportedColorDepths = pClientCoreData->supportedColorDepths;
  281. }
  282. break;
  283. }
  284. // don't get stuck here for ever...
  285. if (pHeader->length == 0) {
  286. break;
  287. }
  288. // Move on to the next user data string.
  289. pHeader = (PRNS_UD_HEADER)((PBYTE)pHeader + pHeader->length);
  290. } while (pHeader < pEnd);
  291. }
  292. switch (pCoreData->colorDepth) {
  293. case RNS_UD_COLOR_24BPP:
  294. pCoreData->highColorDepth = 24;
  295. break;
  296. case RNS_UD_COLOR_16BPP_565:
  297. pCoreData->highColorDepth = 16;
  298. break;
  299. case RNS_UD_COLOR_16BPP_555:
  300. pCoreData->highColorDepth = 15;
  301. break;
  302. case RNS_UD_COLOR_8BPP:
  303. pCoreData->highColorDepth = 8;
  304. break;
  305. case RNS_UD_COLOR_4BPP:
  306. pCoreData->highColorDepth = 4;
  307. break;
  308. default:
  309. pCoreData->highColorDepth = 0;
  310. break;
  311. }
  312. #ifdef DC_HICOLOR
  313. /****************************************************************/
  314. /* setup color depth based on the screen capabilities */
  315. /****************************************************************/
  316. hdc = GetDC(NULL);
  317. if (hdc) {
  318. screenBpp = GetDeviceCaps(hdc, BITSPIXEL);
  319. ReleaseDC(NULL, hdc);
  320. // Avoid bad colors when device bitmaps is enabled and if the
  321. // client connects at 15bpp and the console is at 16bpp.
  322. if ((screenBpp == 16) &&
  323. (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_555) &&
  324. (pCoreData->supportedColorDepths & RNS_UD_16BPP_SUPPORT))
  325. {
  326. pCoreData->colorDepth = RNS_UD_COLOR_16BPP_565;
  327. pCoreData->highColorDepth = 16;
  328. } else
  329. // see if the ColorDepth is valid
  330. if( !((pCoreData->colorDepth == RNS_UD_COLOR_24BPP) ||
  331. (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_565) ||
  332. (pCoreData->colorDepth == RNS_UD_COLOR_16BPP_555) ||
  333. (pCoreData->colorDepth == RNS_UD_COLOR_8BPP) ||
  334. (pCoreData->colorDepth == RNS_UD_COLOR_4BPP)) )
  335. {
  336. pCoreData->highColorDepth = (TSUINT16)screenBpp;
  337. if (screenBpp >= 24)
  338. {
  339. pCoreData->colorDepth = RNS_UD_COLOR_24BPP;
  340. pCoreData->highColorDepth = 24;
  341. }
  342. else if (screenBpp == 16)
  343. {
  344. pCoreData->colorDepth = RNS_UD_COLOR_16BPP_565;
  345. }
  346. else if (screenBpp == 15)
  347. {
  348. pCoreData->colorDepth = RNS_UD_COLOR_16BPP_555;
  349. }
  350. else
  351. {
  352. pCoreData->colorDepth = RNS_UD_COLOR_8BPP;
  353. pCoreData->highColorDepth = 8;
  354. }
  355. }
  356. TRACE((DEBUG_TSHRSRV_NORMAL,
  357. "TShrSRV: TSrvConsoleConnect at %d bpp\n", screenBpp));
  358. }
  359. #endif
  360. // set new high color fields
  361. pCoreData->supportedColorDepths = (TSUINT16)( RNS_UD_24BPP_SUPPORT ||
  362. RNS_UD_16BPP_SUPPORT ||
  363. RNS_UD_15BPP_SUPPORT);
  364. // Pass the data to WDTShare
  365. ulBytesReturned = 0;
  366. ntStatus = IcaStackIoControl(pTSrvInfo->hStack,
  367. IOCTL_TSHARE_CONSOLE_CONNECT,
  368. pTSrvInfo->pUserDataInfo,
  369. ulInBufferSize,
  370. NULL,
  371. 0,
  372. &ulBytesReturned);
  373. Cleanup:
  374. TRACE((DEBUG_TSHRSRV_FLOW,
  375. "TShrSRV: TSrvConsoleConnect exit - 0x%x\n", ntStatus));
  376. pTSrvInfo->ntStatus = ntStatus;
  377. if (NT_SUCCESS(ntStatus))
  378. {
  379. EnterCriticalSection(&pTSrvInfo->cs);
  380. // If this connection was not told to terminate during the
  381. // connection response, then mark the conference state as
  382. // TSRV_GCC_CONF_CONNECTED
  383. if (!pTSrvInfo->fDisconnect)
  384. pTSrvInfo->fuConfState = TSRV_CONF_CONNECTED;
  385. LeaveCriticalSection(&pTSrvInfo->cs);
  386. // If we were unable to mark the conf state as CONNECTED, then
  387. // the connection needs to be terminated
  388. if (pTSrvInfo->fuConfState != TSRV_CONF_CONNECTED)
  389. {
  390. TRACE((DEBUG_TSHRSRV_NORMAL,
  391. "TShrSRV: Connection aborted due to term request\n"));
  392. ntStatus = STATUS_REQUEST_ABORTED;
  393. }
  394. }
  395. if (!NT_SUCCESS(ntStatus))
  396. {
  397. TSrvDereferenceInfo(pTSrvInfo);
  398. pTSrvInfo = NULL;
  399. }
  400. }
  401. }
  402. if (NT_SUCCESS(ntStatus))
  403. {
  404. *ppTSrvInfo = pTSrvInfo;
  405. }
  406. TRACE((DEBUG_TSHRSRV_FLOW,
  407. "TShrSRV: TSrvConsoleConnect exit - 0x%x\n", ntStatus));
  408. return (ntStatus);
  409. }