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.

1540 lines
66 KiB

  1. /****************************************************************************/
  2. // ccfsm.cpp
  3. //
  4. // Call controller finite state machine code.
  5. //
  6. // Copyright (C) 1997-2000 Microsoft Corporation
  7. /****************************************************************************/
  8. #include <adcg.h>
  9. extern "C" {
  10. #define TRC_GROUP TRC_GROUP_CORE
  11. #define TRC_FILE "accfsm"
  12. #include <atrcapi.h>
  13. #include <aver.h>
  14. #include <winsock.h>
  15. }
  16. #include "cd.h"
  17. #include "cc.h"
  18. #include "aco.h"
  19. #include "fs.h"
  20. #include "ih.h"
  21. #include "sl.h"
  22. #include "wui.h"
  23. #include "autil.h"
  24. #include "or.h"
  25. #include "uh.h"
  26. #define REG_WINDOWS_KEY TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion")
  27. /****************************************************************************/
  28. // CCEnableShareRecvCmpnts
  29. //
  30. // Called after sending ConfirmActivePDU to server to activate receive-thread
  31. // components.
  32. /****************************************************************************/
  33. inline void DCINTERNAL CCC::CCEnableShareRecvCmpnts(void)
  34. {
  35. DC_BEGIN_FN("CCEnableShareRecvCmpnts");
  36. // The following components expect to be called in the receiver thread
  37. // context - but we are in the sender thread context. Thus we need to
  38. // decouple the calls to these functions.
  39. // Note that we have to wait for completion of UH_Enable since it will
  40. // prepare the bitmap cache capabilities for the ConfirmActivePDU.
  41. TRC_NRM((TB, _T("Decoupling calls to CM/UH_Enable")));
  42. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pCm,
  43. CD_NOTIFICATION_FUNC(CCM,CM_Enable), 0);
  44. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pUh,
  45. CD_NOTIFICATION_FUNC(CUH,UH_Enable), 0);
  46. DC_END_FN();
  47. } /* CCEnableShareRecvCmpnts */
  48. /****************************************************************************/
  49. // CCDisableShareRecvCmpnts
  50. //
  51. // Disables the recv-side share components. Called on receipt of a
  52. // DisableAllPDU from the server. Note that although this is the end of a
  53. // share, it may not be the end of the session, since if the server is
  54. // reconnecting a DemandActivePDU will be sent soon after this.
  55. /****************************************************************************/
  56. inline void DCINTERNAL CCC::CCDisableShareRecvCmpnts(void)
  57. {
  58. DC_BEGIN_FN("CCDisableShareRecvCmpnts");
  59. /************************************************************************/
  60. /* The following components expect to be called in the receiver thread */
  61. /* context - but we are in the sender thread context. Thus we need */
  62. /* to decouple the calls to these functions. */
  63. /************************************************************************/
  64. TRC_NRM((TB, _T("Decoupling calls to CM/UH_Disable")));
  65. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pCm,
  66. CD_NOTIFICATION_FUNC(CCM,CM_Disable), 0);
  67. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pUh,
  68. CD_NOTIFICATION_FUNC(CUH,UH_Disable), 0);
  69. DC_END_FN();
  70. } /* CCDisableShareRecvCmpnts */
  71. /****************************************************************************/
  72. // CCDisconnectShareRecvCmpnts
  73. //
  74. // Disconnects the recv-side share components. Called on session end,
  75. // indicates cleanup should occur.
  76. /****************************************************************************/
  77. inline void DCINTERNAL CCC::CCDisconnectShareRecvCmpnts(void)
  78. {
  79. DC_BEGIN_FN("CCDisableShareRecvCmpnts");
  80. /************************************************************************/
  81. /* The following components expect to be called in the receiver thread */
  82. /* context - but we are in the sender thread context. Thus we need */
  83. /* to decouple the calls to these functions. */
  84. /************************************************************************/
  85. TRC_NRM((TB, _T("Decoupling calls to CM/UH_Disable")));
  86. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pCm,
  87. CD_NOTIFICATION_FUNC(CCM,CM_Disable), 0);
  88. _pCd->CD_DecoupleSyncNotification(CD_RCV_COMPONENT, _pUh,
  89. CD_NOTIFICATION_FUNC(CUH,UH_Disconnect), 0);
  90. DC_END_FN();
  91. } /* CCDisconnectShareRecvCmpnts */
  92. /****************************************************************************/
  93. // CCEnableShareSendCmpnts
  94. //
  95. // Enables the send-side share components. Called after sending
  96. // ConfirmActivePDU (containing client capabilities) to the server.
  97. /****************************************************************************/
  98. inline void DCINTERNAL CCC::CCEnableShareSendCmpnts(void)
  99. {
  100. DC_BEGIN_FN("CCEnableShareSendCmpnts");
  101. // The following components expect to be called in the sender thread
  102. // context - which is the context we're currently in. So we can just
  103. // call the functions directly.
  104. TRC_NRM((TB, _T("Calling IH/FS/FC/OR_Enable")));
  105. _pIh->IH_Enable();
  106. // Enable fonts. This becomes an empty function now because we only
  107. // send a zero font PDU from UH.
  108. _pFs->FS_Enable();
  109. // UH_Enable() is called when the DemandActivePDU is received, but the
  110. // persistent bitmap cache keys need to be sent after the sync and control
  111. // PDUs at this time. Call within the send thread context because that is
  112. // where this code expects to be called.
  113. // The PersistentKey PDUs have to be sent out before Font PDUs in the protocol.
  114. // So font list is sent out from UH code after persistent keys.
  115. _pUh->UH_SendPersistentKeysAndFontList();
  116. _pOr->OR_Enable();
  117. DC_END_FN();
  118. } /* CCEnableShareSendCmpnts */
  119. /****************************************************************************/
  120. /* Name: CCDisableShareSendCmpnts */
  121. /* */
  122. /* Purpose: Disables the send-side share components. */
  123. /****************************************************************************/
  124. inline void DCINTERNAL CCC::CCDisableShareSendCmpnts(void)
  125. {
  126. DC_BEGIN_FN("CCDisableShareSendCmpnts");
  127. // The following components expect to be called in the sender thread
  128. // context - which is what we are in - so we can just call these
  129. // functions directly.
  130. TRC_NRM((TB, _T("Calling OR/IH/FC/FS_Disable")));
  131. _pOr->OR_Disable();
  132. _pIh->IH_Disable();
  133. _pFs->FS_Disable();
  134. DC_END_FN();
  135. } /* CCDisableShareSendCmpnts */
  136. /****************************************************************************/
  137. /* CC FSM */
  138. /* */
  139. /* EVENTS STATES */
  140. /* 0 CC_EVT_STARTCONNECT 0 CC_DISCONNECTED */
  141. /* 1 CC_EVT_ONCONNECTOK 1 CC_CONNECTPENDING */
  142. /* 2 CC_EVT_ONDEMANDACTIVE 2 CC_WAITINGFORDMNDACT */
  143. /* 3 CC_EVT_SENTOK 3 CC_SENDINGCONFIRMACTIVEPDU1 */
  144. /* 4 CC_EVT_ONBUFFERAVAILABLE 4 CC_SENDINGSYNCPDU1 */
  145. /* 5 CC_EVT_ONDEACTIVATEALL 5 CC_SENDINGCOOPCONTROL */
  146. /* 6 CC_EVT_DISCONNECT 6 CC_SENDINGGRANTCONTROL */
  147. /* 7 CC_EVT_ONDISCONNECTED 7 CC_CONNECTED */
  148. /* 8 CC_EVT_SHUTDOWN 8 CC_SENDING_SHUTDOWNPDU */
  149. /* 9 CC_EVT_ONSHUTDOWNDENIED 9 CC_SENT_SHUTDOWNPDU */
  150. /*10 CC_EVT_DISCONNECT_AND_EXIT 10 CC_PENDING_SHUTDOWN */
  151. /* */
  152. /* Stt | 0 1 2 3 4 5 6 7 8 9 10 */
  153. /* ========================================================= */
  154. /* Evt | */
  155. /* 0 | 1A / / / / / / / / / / */
  156. /* | */
  157. /* 1 | - 2- / / / / / / / / - */
  158. /* | */
  159. /* 2 | - / 3B / / / / / / / - */
  160. /* | */
  161. /* 3 | / / / 4D 5G 6J 7K / 9- / / */
  162. /* | */
  163. /* 4 | - - - -C -F -I -J - -Z - - */
  164. /* | */
  165. /* 5 | - / / / / / / 2M 10P 10P - */
  166. /* | */
  167. /* 6 | - -P -P -P -P -P -P -P -P -P - */
  168. /* | */
  169. /* 7 | / 0Y 0Y 0Y 0Y 0Y 0Y 0Y 0T 0T 0T */
  170. /* | */
  171. /* 8 | -V 10P 10P 10P 10P 10P 10P 8Z - - - */
  172. /* | */
  173. /* 9 | - / / / / / / / / 7W - */
  174. /* | */
  175. /* 10 | -V 10P 10P 10P 10P 10P 10P 10P 10P 10P - */
  176. /* */
  177. /* '/' = illegal event/state combination */
  178. /* '-' = no action */
  179. /****************************************************************************/
  180. const FSM_ENTRY ccFSM[CC_FSM_INPUTS][CC_FSM_STATES] =
  181. {
  182. /* CC_EVT_STARTCONNECT */
  183. {{CC_CONNECTPENDING, ACT_A},
  184. {STATE_INVALID, ACT_NO},
  185. {STATE_INVALID, ACT_NO},
  186. {STATE_INVALID, ACT_NO},
  187. {STATE_INVALID, ACT_NO},
  188. {STATE_INVALID, ACT_NO},
  189. {STATE_INVALID, ACT_NO},
  190. {STATE_INVALID, ACT_NO},
  191. {STATE_INVALID, ACT_NO},
  192. {STATE_INVALID, ACT_NO},
  193. {STATE_INVALID, ACT_NO}},
  194. /* CC_EVT_CONNECTOK */
  195. {{CC_DISCONNECTED, ACT_NO},
  196. {CC_WAITINGFORDEMANDACTIVE, ACT_NO},
  197. {STATE_INVALID, ACT_NO},
  198. {STATE_INVALID, ACT_NO},
  199. {STATE_INVALID, ACT_NO},
  200. {STATE_INVALID, ACT_NO},
  201. {STATE_INVALID, ACT_NO},
  202. {STATE_INVALID, ACT_NO},
  203. {STATE_INVALID, ACT_NO},
  204. {STATE_INVALID, ACT_NO},
  205. {CC_PENDING_SHUTDOWN, ACT_NO}},
  206. /* CC_EVENT_DEMAND_ACTIVE */
  207. {{CC_DISCONNECTED, ACT_NO},
  208. {STATE_INVALID, ACT_NO},
  209. {CC_SENDINGCONFIRMACTIVE1, ACT_B},
  210. {STATE_INVALID, ACT_NO},
  211. {STATE_INVALID, ACT_NO},
  212. {STATE_INVALID, ACT_NO},
  213. {STATE_INVALID, ACT_NO},
  214. {STATE_INVALID, ACT_NO},
  215. {STATE_INVALID, ACT_NO},
  216. {STATE_INVALID, ACT_NO},
  217. {CC_PENDING_SHUTDOWN, ACT_NO}},
  218. /* CC_EVENT_SEND_OK */
  219. {{STATE_INVALID, ACT_NO},
  220. {STATE_INVALID, ACT_NO},
  221. {STATE_INVALID, ACT_NO},
  222. {CC_SENDINGSYNC1, ACT_F},
  223. {CC_SENDINGCOOPCONTROL, ACT_I},
  224. {CC_SENDINGGRANTCONTROL, ACT_J},
  225. {CC_CONNECTED, ACT_K},
  226. {STATE_INVALID, ACT_NO},
  227. {CC_SENT_SHUTDOWNPDU, ACT_NO},
  228. {STATE_INVALID, ACT_NO},
  229. {STATE_INVALID, ACT_NO}},
  230. /* CC_EVENT_BUFFER_AVAILABLE */
  231. {{CC_DISCONNECTED, ACT_NO},
  232. {CC_CONNECTPENDING, ACT_NO},
  233. {CC_WAITINGFORDEMANDACTIVE, ACT_NO},
  234. {CC_SENDINGCONFIRMACTIVE1, ACT_C},
  235. {CC_SENDINGSYNC1, ACT_F},
  236. {CC_SENDINGCOOPCONTROL, ACT_I},
  237. {CC_SENDINGGRANTCONTROL, ACT_J},
  238. {CC_CONNECTED, ACT_NO},
  239. {CC_SENDING_SHUTDOWNPDU, ACT_Z},
  240. {CC_SENT_SHUTDOWNPDU, ACT_NO},
  241. {CC_PENDING_SHUTDOWN, ACT_NO}},
  242. /* CC_EVENT_DEACTIVATEALL */
  243. {{CC_DISCONNECTED, ACT_NO},
  244. {STATE_INVALID, ACT_NO},
  245. {STATE_INVALID, ACT_NO},
  246. {STATE_INVALID, ACT_NO},
  247. {STATE_INVALID, ACT_NO},
  248. {STATE_INVALID, ACT_NO},
  249. {STATE_INVALID, ACT_NO},
  250. {CC_WAITINGFORDEMANDACTIVE, ACT_M},
  251. {CC_PENDING_SHUTDOWN, ACT_P},
  252. {CC_PENDING_SHUTDOWN, ACT_P},
  253. {CC_PENDING_SHUTDOWN, ACT_NO}},
  254. /* CC_EVENT_DISCONNECT */
  255. {{CC_DISCONNECTED, ACT_NO},
  256. {CC_CONNECTPENDING, ACT_P},
  257. {CC_WAITINGFORDEMANDACTIVE, ACT_P},
  258. {CC_SENDINGCONFIRMACTIVE1, ACT_P},
  259. {CC_SENDINGSYNC1, ACT_P},
  260. {CC_SENDINGCOOPCONTROL, ACT_P},
  261. {CC_SENDINGGRANTCONTROL, ACT_P},
  262. {CC_CONNECTED, ACT_P},
  263. {CC_SENDING_SHUTDOWNPDU, ACT_P},
  264. {CC_SENT_SHUTDOWNPDU, ACT_P},
  265. {CC_PENDING_SHUTDOWN, ACT_NO}},
  266. /* CC_EVENT_ONDISCONNECTED */
  267. {{STATE_INVALID, ACT_NO},
  268. {CC_DISCONNECTED, ACT_Y},
  269. {CC_DISCONNECTED, ACT_Y},
  270. {CC_DISCONNECTED, ACT_Y},
  271. {CC_DISCONNECTED, ACT_Y},
  272. {CC_DISCONNECTED, ACT_Y},
  273. {CC_DISCONNECTED, ACT_Y},
  274. {CC_DISCONNECTED, ACT_Y},
  275. {CC_DISCONNECTED, ACT_T},
  276. {CC_DISCONNECTED, ACT_T},
  277. {CC_DISCONNECTED, ACT_T}},
  278. /* CC_EVENT_SHUTDOWN */
  279. {{CC_DISCONNECTED, ACT_V},
  280. {CC_PENDING_SHUTDOWN, ACT_P},
  281. {CC_PENDING_SHUTDOWN, ACT_P},
  282. {CC_PENDING_SHUTDOWN, ACT_P},
  283. {CC_PENDING_SHUTDOWN, ACT_P},
  284. {CC_PENDING_SHUTDOWN, ACT_P},
  285. {CC_PENDING_SHUTDOWN, ACT_P},
  286. {CC_SENDING_SHUTDOWNPDU, ACT_Z},
  287. {CC_SENDING_SHUTDOWNPDU, ACT_NO},
  288. {CC_SENT_SHUTDOWNPDU, ACT_NO},
  289. {CC_PENDING_SHUTDOWN, ACT_NO}},
  290. /* CC_EVENT_ON_SHUTDOWN_DENIED */
  291. {{CC_DISCONNECTED, ACT_NO},
  292. {STATE_INVALID, ACT_NO},
  293. {STATE_INVALID, ACT_NO},
  294. {STATE_INVALID, ACT_NO},
  295. {STATE_INVALID, ACT_NO},
  296. {STATE_INVALID, ACT_NO},
  297. {STATE_INVALID, ACT_NO},
  298. {STATE_INVALID, ACT_NO},
  299. {STATE_INVALID, ACT_NO},
  300. {CC_CONNECTED, ACT_W},
  301. {CC_PENDING_SHUTDOWN, ACT_NO}},
  302. /* CC_EVENT_DISCONNECT_AND_EXIT */
  303. {{CC_DISCONNECTED, ACT_V},
  304. {CC_PENDING_SHUTDOWN, ACT_P},
  305. {CC_PENDING_SHUTDOWN, ACT_P},
  306. {CC_PENDING_SHUTDOWN, ACT_P},
  307. {CC_PENDING_SHUTDOWN, ACT_P},
  308. {CC_PENDING_SHUTDOWN, ACT_P},
  309. {CC_PENDING_SHUTDOWN, ACT_P},
  310. {CC_PENDING_SHUTDOWN, ACT_P},
  311. {CC_PENDING_SHUTDOWN, ACT_P},
  312. {CC_PENDING_SHUTDOWN, ACT_P},
  313. {CC_PENDING_SHUTDOWN, ACT_NO}}
  314. };
  315. /****************************************************************************/
  316. // CCFSMProc
  317. //
  318. // Runs the CC finite state machine based on event inputs.
  319. /****************************************************************************/
  320. void DCINTERNAL CCC::CCFSMProc(unsigned event, ULONG_PTR data, DCUINT dataLen)
  321. {
  322. BOOL sendRc = TRUE;
  323. unsigned action = 0;
  324. PCONNECTSTRUCT pConnect;
  325. DCSIZE desktopSize;
  326. HRESULT hr;
  327. DC_BEGIN_FN("CCFSMProc");
  328. TRC_ASSERT(((0==data && 0==dataLen) ||
  329. (0!=data && 0!=dataLen)),
  330. (TB, _T("data and dataLen should both be set or NULL")));
  331. // Run the FSM.
  332. EXECUTE_FSM(ccFSM, event, _CC.fsmState, action, eventString, stateString);
  333. switch (action) {
  334. case ACT_A:
  335. {
  336. BYTE UserData[sizeof(RNS_UD_CS_CORE) + sizeof(TS_UD_CS_CLUSTER)];
  337. RNS_UD_CS_CORE *pCoreData;
  338. TS_UD_CS_CLUSTER *pClusterData;
  339. TCHAR CompName[sizeof(pCoreData->clientName) / sizeof(UINT16)];
  340. TRC_NRM((TB, _T("ACT_A: begin connection process")));
  341. //
  342. // Flag that safe checksum settings have not been set yet
  343. // allowing them to be set on the first capabilities negotiation
  344. // we don't allow them to be reconfigured as it's a per-link
  345. // setting rather than something that needs to be reconfigured
  346. // when shadowing.
  347. //
  348. _CC.fSafeChecksumSettingsSet = FALSE;
  349. // We create here two different GCC user data sub-blocks (core
  350. // and cluster). Memset the entire space and create sub-pointers
  351. // for the individual parts.
  352. memset(UserData, 0, sizeof(UserData));
  353. pCoreData = (RNS_UD_CS_CORE *)UserData;
  354. pClusterData = (TS_UD_CS_CLUSTER *)
  355. (UserData + sizeof(RNS_UD_CS_CORE));
  356. // Incomplete Connect - need to break out address.
  357. pConnect = (PCONNECTSTRUCT)data;
  358. TRC_ASSERT((pConnect != NULL), (TB, _T("No connection data")));
  359. // Start creating the core data.
  360. pCoreData->header.type = RNS_UD_CS_CORE_ID;
  361. pCoreData->header.length = sizeof(RNS_UD_CS_CORE);
  362. pCoreData->version = RNS_UD_VERSION;
  363. pCoreData->desktopWidth = pConnect->desktopWidth;
  364. pCoreData->desktopHeight = pConnect->desktopHeight;
  365. //Indicate early support for error info PDU
  366. //We can't do this during caps negotiation because
  367. //that happens after licensing which could make use
  368. //of this PDU.
  369. //
  370. pCoreData->earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU;
  371. // Add desktop size to combined caps structure.
  372. _ccCombinedCapabilities.bitmapCapabilitySet.desktopWidth =
  373. pConnect->desktopWidth;
  374. _ccCombinedCapabilities.bitmapCapabilitySet.desktopHeight =
  375. pConnect->desktopHeight;
  376. // Pass the desktop size to UT.
  377. desktopSize.width = pConnect->desktopWidth;
  378. desktopSize.height = pConnect->desktopHeight;
  379. _pUi->UI_SetDesktopSize(&desktopSize);
  380. // Call UH_SetConnectOptions with the connect flags. This call
  381. // must happen after the desktop size has been sent to UT.
  382. // Make sure that we haven't set any flags in the high word, as
  383. // these will get dropped if DCUINT is 16 bits.
  384. TRC_ASSERT((0 == HIWORD(pConnect->connectFlags)),
  385. (TB, _T("Set flags in high word")));
  386. _pCd->CD_DecoupleSimpleNotification(CD_RCV_COMPONENT,
  387. _pUh,
  388. CD_NOTIFICATION_FUNC(CUH,UH_SetConnectOptions),
  389. (ULONG_PTR)pConnect->connectFlags);
  390. #ifdef DC_HICOLOR
  391. pCoreData->colorDepth = RNS_UD_COLOR_8BPP;
  392. // Set up the full hicolor support. We advertise support for
  393. // all the depths we can manage; if we don't then get the depth
  394. // the UI actually asked for, well, it can end the connection
  395. // if it so chooses.
  396. // Note that Win16 can only support 15bpp if running in a
  397. // suitable screen mode.
  398. pCoreData->supportedColorDepths = RNS_UD_15BPP_SUPPORT |
  399. RNS_UD_16BPP_SUPPORT |
  400. RNS_UD_24BPP_SUPPORT;
  401. #endif
  402. switch (pConnect->colorDepthID) {
  403. // The Server supports both 4bpp & 8bpp Clients. However,
  404. // a beta2 Server supported only 8bpp, and rejected Clients
  405. // specifying 4bpp.
  406. //
  407. // Therefore, always set colorDepth (the beta2 field) to
  408. // 8bpp, and set postBeta2ColorDepth (the new field) to the
  409. // real value.
  410. #ifndef DC_HICOLOR
  411. // Always set preferredBitsPerPixel to 8, as that is the
  412. // protocol color depth that we expect, irrespective of the
  413. // display color depth.
  414. #endif
  415. case CO_BITSPERPEL4:
  416. #ifndef DC_HICOLOR
  417. pCoreData->colorDepth = RNS_UD_COLOR_8BPP;
  418. #endif
  419. pCoreData->postBeta2ColorDepth = RNS_UD_COLOR_4BPP;
  420. #ifdef DC_HICOLOR
  421. pCoreData->highColorDepth = 4;
  422. #endif
  423. _ccCombinedCapabilities.bitmapCapabilitySet
  424. .preferredBitsPerPixel = 8;
  425. _pUi->UI_SetColorDepth(4);
  426. break;
  427. case CO_BITSPERPEL8:
  428. #ifndef DC_HICOLOR
  429. pCoreData->colorDepth = RNS_UD_COLOR_8BPP;
  430. #endif
  431. pCoreData->postBeta2ColorDepth = RNS_UD_COLOR_8BPP;
  432. #ifdef DC_HICOLOR
  433. pCoreData->highColorDepth = 8;
  434. #endif
  435. _ccCombinedCapabilities.bitmapCapabilitySet
  436. .preferredBitsPerPixel = 8;
  437. _pUi->UI_SetColorDepth(8);
  438. break;
  439. #ifdef DC_HICOLOR
  440. case CO_BITSPERPEL24:
  441. pCoreData->postBeta2ColorDepth = RNS_UD_COLOR_8BPP;
  442. pCoreData->highColorDepth = 24;
  443. _ccCombinedCapabilities.bitmapCapabilitySet.
  444. preferredBitsPerPixel = 24;
  445. _pUi->UI_SetColorDepth(24);
  446. break;
  447. case CO_BITSPERPEL15:
  448. pCoreData->postBeta2ColorDepth = RNS_UD_COLOR_8BPP;
  449. pCoreData->highColorDepth = 15;
  450. _ccCombinedCapabilities.bitmapCapabilitySet.
  451. preferredBitsPerPixel = 15;
  452. _pUi->UI_SetColorDepth(15);
  453. break;
  454. case CO_BITSPERPEL16:
  455. pCoreData->postBeta2ColorDepth = RNS_UD_COLOR_8BPP;
  456. pCoreData->highColorDepth = 16;
  457. _ccCombinedCapabilities.bitmapCapabilitySet.
  458. preferredBitsPerPixel = 16;
  459. _pUi->UI_SetColorDepth(16);
  460. break;
  461. #endif
  462. default:
  463. TRC_ABORT((TB, _T("Unsupported color depth %d"),
  464. pConnect->colorDepthID));
  465. break;
  466. }
  467. // SAS sequence.
  468. pCoreData->SASSequence = pConnect->sasSequence;
  469. // The keyboard information is passed to the Server in both the
  470. // userdata and the T.128 capabilites.
  471. pCoreData->keyboardLayout = pConnect->keyboardLayout;
  472. TRC_NRM((TB, _T("Set Caps kbdtype %#lx"), pCoreData->keyboardLayout));
  473. _ccCombinedCapabilities.inputCapabilitySet.keyboardLayout =
  474. pCoreData->keyboardLayout;
  475. // The keyboard sub type information is passed to the Server in
  476. // both the userdata and the T.128 capabilites.
  477. pCoreData->keyboardType = pConnect->keyboardType;
  478. pCoreData->keyboardSubType = pConnect->keyboardSubType;
  479. pCoreData->keyboardFunctionKey = pConnect->keyboardFunctionKey;
  480. TRC_NRM((TB, _T("Set Caps kbd type %#lx sub type %#lx func key %#lx"),
  481. pCoreData->keyboardType,
  482. pCoreData->keyboardSubType,
  483. pCoreData->keyboardFunctionKey));
  484. _ccCombinedCapabilities.inputCapabilitySet.keyboardType =
  485. pCoreData->keyboardType;
  486. _ccCombinedCapabilities.inputCapabilitySet.keyboardSubType =
  487. pCoreData->keyboardSubType;
  488. _ccCombinedCapabilities.inputCapabilitySet.keyboardFunctionKey =
  489. pCoreData->keyboardFunctionKey;
  490. // The IME file name information is passed to the Server in
  491. // both the userdata and the T.128 capabilites.
  492. #ifdef UNICODE
  493. hr = StringCchCopy(pCoreData->imeFileName,
  494. SIZE_TCHARS(pCoreData->imeFileName),
  495. pConnect->imeFileName);
  496. if (SUCCEEDED(hr)) {
  497. hr = StringCchCopy(
  498. _ccCombinedCapabilities.inputCapabilitySet.imeFileName,
  499. SIZE_TCHARS(_ccCombinedCapabilities.inputCapabilitySet.imeFileName),
  500. pCoreData->imeFileName);
  501. }
  502. //
  503. // Failure is not fatal just zero out the IME filenames
  504. //
  505. if (FAILED(hr)) {
  506. ZeroMemory(pCoreData->imeFileName, sizeof(pCoreData->imeFileName));
  507. ZeroMemory(
  508. _ccCombinedCapabilities.inputCapabilitySet.imeFileName,
  509. sizeof(_ccCombinedCapabilities.inputCapabilitySet.imeFileName));
  510. }
  511. #else
  512. // Manually translate the character array into the Unicode buffer.
  513. // ASCII only.
  514. {
  515. int i = 0;
  516. while (pConnect->imeFileName[i] && i < TS_MAX_IMEFILENAME) {
  517. pCoreData->imeFileName[i] =
  518. _ccCombinedCapabilities.inputCapabilitySet.
  519. imeFileName[i] =
  520. (UINT16)pConnect->imeFileName[i];
  521. i++;
  522. }
  523. pCoreData->imeFileName[i] = 0;
  524. _ccCombinedCapabilities.inputCapabilitySet.imeFileName[i] = 0;
  525. }
  526. #endif
  527. // Client build #.
  528. pCoreData->clientBuild = DCVER_BUILD_NUMBER;
  529. // Client computer name. gethostname() returns a full domain-
  530. // type name which we need to parse to take only the machine
  531. // name up to the first dot.
  532. pCoreData->clientName[0] = 0;
  533. //new core field added for beta3 Whistler
  534. pCoreData->clientDigProductId[0] = 0;
  535. {
  536. //get the digital product id from the registry
  537. HKEY hKey = NULL;
  538. if( RegOpenKeyEx( HKEY_LOCAL_MACHINE, REG_WINDOWS_KEY, 0, KEY_READ, &hKey) == ERROR_SUCCESS )
  539. {
  540. //failure not fatal; we can use the computername in the worst case.
  541. DWORD dwType = REG_SZ;
  542. DWORD dwSize = sizeof( pCoreData->clientDigProductId );
  543. RegQueryValueEx( hKey,
  544. _T("ProductId"), NULL, &dwType,
  545. (LPBYTE)pCoreData->clientDigProductId,
  546. &dwSize
  547. );
  548. if (hKey)
  549. RegCloseKey( hKey );
  550. hKey = NULL;
  551. }
  552. if (_pUt->UT_GetComputerName(CompName,
  553. sizeof(CompName) / sizeof(TCHAR))) {
  554. #ifdef UNICODE
  555. TRC_NRM((TB, _T("Sending unicode client computername")));
  556. hr = StringCchCopy(pCoreData->clientName,
  557. SIZE_TCHARS(pCoreData->clientName),
  558. CompName);
  559. if (FAILED(hr)) {
  560. TRC_ERR((TB,_T("Compname string copy failed: 0x%x"), hr));
  561. }
  562. #else // UNICODE
  563. #ifdef OS_WIN32
  564. {
  565. ULONG ulRetVal;
  566. TRC_NRM((TB, _T("Translating and sending unicode client ")
  567. "computername"));
  568. ulRetVal = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,
  569. CompName, -1, pCoreData->clientName,
  570. sizeof(pCoreData->clientName) /
  571. sizeof(pCoreData->clientName[0]));
  572. pCoreData->clientName[ulRetVal] = 0;
  573. }
  574. #else // !OS_WIN32
  575. // Manually translate the character array into the
  576. // Unicode buffer.
  577. // This will only work for code page 1252, so
  578. // non-latin Win3.11 clients that use non-Latin
  579. // computer names will come as a random jumble of high
  580. // ANSI characters. Fix this next time.
  581. int i = 0;
  582. while (CompName[i]) {
  583. pCoreData->clientName[i] = (DCUINT16)CompName[i];
  584. i++;
  585. }
  586. pCoreData->clientName[i] = 0;
  587. #endif // OS_WIN32
  588. #endif // UNICODE
  589. }
  590. }
  591. // New core data fields added post Win2000 beta 3
  592. pCoreData->clientProductId = 1;
  593. pCoreData->serialNumber = 0;
  594. // Now set up the clustering data. We indicate that the client
  595. // supports redirection (TS_SERVER_REDIRECT_PDU). If we are in the
  596. // midst of a redirection, we set up the session ID fields.
  597. pClusterData->header.type = TS_UD_CS_CLUSTER_ID;
  598. pClusterData->header.length = sizeof(TS_UD_CS_CLUSTER);
  599. pClusterData->Flags = TS_CLUSTER_REDIRECTION_SUPPORTED;
  600. pClusterData->Flags &= ~TS_CLUSTER_REDIRECTION_VERSION;
  601. pClusterData->Flags |= TS_CLUSTER_REDIRECTION_VERSION4 << 2;
  602. if(_pUi->UI_GetConnectToServerConsole()) {
  603. pClusterData->Flags |=
  604. TS_CLUSTER_REDIRECTED_SESSIONID_FIELD_VALID;
  605. //Console is session ID 0
  606. pClusterData->RedirectedSessionID = 0;
  607. }
  608. else if (_pUi->UI_GetDoRedirection()) {
  609. // redirection for purposes other than connecting to console
  610. // e.g load balancing
  611. pClusterData->Flags |=
  612. TS_CLUSTER_REDIRECTED_SESSIONID_FIELD_VALID;
  613. pClusterData->RedirectedSessionID =
  614. _pUi->UI_GetRedirectionSessionID();
  615. _pUi->UI_ClearDoRedirection();
  616. }
  617. if (_pUi->UI_GetUseSmartcardLogon()) {
  618. pClusterData->Flags |= TS_CLUSTER_REDIRECTED_SMARTCARD;
  619. }
  620. _pSl->SL_Connect(pConnect->bInitiateConnect, pConnect->RNSAddress,
  621. pConnect->transportType, SL_PROTOCOL_T128, UserData,
  622. sizeof(RNS_UD_CS_CORE) + sizeof(TS_UD_CS_CLUSTER));
  623. }
  624. break;
  625. case ACT_B:
  626. {
  627. TRC_NRM((TB, _T("ACT_B: DemandActive - send ConfirmActive")));
  628. /****************************************************************/
  629. /* The server is requesting that we start a share. The last */
  630. /* thing we do in this action is reply to the server with a */
  631. /* confirm active and once the server receives it */
  632. /* we are in a share as far as the server is concerned so now */
  633. /* is the time to store connection information. Call */
  634. /* CCShareStart to do this. */
  635. /****************************************************************/
  636. TRC_ASSERT((data != 0), (TB, _T("No data!")));
  637. BOOL fUseSafeChecksum = FALSE;
  638. if (SUCCEEDED(CCShareStart((PTS_DEMAND_ACTIVE_PDU)data, dataLen,
  639. &fUseSafeChecksum)))
  640. {
  641. /****************************************************************/
  642. // We also need to enable the share recv-side components at
  643. // this time. This neds to be done on the receiver thread. Note
  644. // that we don't enable the send-side components until we've sent
  645. // all the sync/control PDUs to the server - this keeps things
  646. // cleaner.
  647. /****************************************************************/
  648. CCEnableShareRecvCmpnts();
  649. /****************************************************************/
  650. /* Build and send Confirm active on low prioity */
  651. /****************************************************************/
  652. CCBuildShareHeaders();
  653. TRC_NRM((TB,_T("Sending ConfirmActivePDU")));
  654. if (!_CC.fSafeChecksumSettingsSet) {
  655. _pSl->SL_SetEncSafeChecksumSC(fUseSafeChecksum);
  656. }
  657. CCSendPDU(CC_TYPE_CONFIRMACTIVE,
  658. CC_SEND_FLAGS_CONFIRM,
  659. TS_CA_NON_DATA_SIZE + TS_MAX_SOURCEDESCRIPTOR +
  660. sizeof(CC_COMBINED_CAPABILITIES),
  661. TS_LOWPRIORITY);
  662. if (!_CC.fSafeChecksumSettingsSet) {
  663. //
  664. // Notify SL, separate calls for send and recv thread to prevent
  665. // races
  666. //
  667. _pCd->CD_DecoupleSimpleNotification(
  668. CD_SND_COMPONENT,
  669. _pSl,
  670. CD_NOTIFICATION_FUNC(CSL,SL_SetEncSafeChecksumCS),
  671. fUseSafeChecksum
  672. );
  673. }
  674. //
  675. // Flag that checksum settings are set and don't allow
  676. // them to be reset until the next connection
  677. //
  678. _CC.fSafeChecksumSettingsSet = TRUE;
  679. /****************************************************************/
  680. /* Inform the UI that we received DemandActivePDU. */
  681. /****************************************************************/
  682. _pCd->CD_DecoupleSyncNotification(
  683. CD_UI_COMPONENT,
  684. _pUi,
  685. CD_NOTIFICATION_FUNC(CUI,UI_OnDemandActivePDU),
  686. 0
  687. );
  688. }
  689. }
  690. break;
  691. case ACT_C:
  692. {
  693. TRC_ALT((TB, _T("ACT_C: retry send of lowPri ConfirmActive")));
  694. /****************************************************************/
  695. /* Build and send Confirm active on low prioity */
  696. /****************************************************************/
  697. CCBuildShareHeaders();
  698. CCSendPDU(CC_TYPE_CONFIRMACTIVE,
  699. CC_SEND_FLAGS_CONFIRM,
  700. TS_CA_NON_DATA_SIZE + TS_MAX_SOURCEDESCRIPTOR +
  701. sizeof(CC_COMBINED_CAPABILITIES),
  702. TS_LOWPRIORITY);
  703. }
  704. break;
  705. case ACT_F:
  706. {
  707. TRC_NRM((TB, _T("ACT_F: Send synchronize PDU (1)")));
  708. CCSendPDU(CC_TYPE_SYNCHRONIZE,
  709. CC_SEND_FLAGS_OTHER,
  710. TS_SYNC_PDU_SIZE,
  711. TS_LOWPRIORITY);
  712. }
  713. break;
  714. case ACT_I:
  715. {
  716. TRC_NRM((TB, _T("ACT_I: Send co-operate control PDU")));
  717. CCSendPDU(CC_TYPE_COOPCONTROL,
  718. CC_SEND_FLAGS_DATA,
  719. TS_CONTROL_PDU_SIZE,
  720. TS_MEDPRIORITY);
  721. }
  722. break;
  723. case ACT_J:
  724. {
  725. TRC_NRM((TB, _T("ACT_J: Send request control PDU")));
  726. CCSendPDU(CC_TYPE_REQUESTCONTROL,
  727. CC_SEND_FLAGS_DATA,
  728. TS_CONTROL_PDU_SIZE,
  729. TS_MEDPRIORITY);
  730. }
  731. break;
  732. case ACT_K:
  733. {
  734. TRC_NRM((TB, _T("ACT_K: Share has been created - connection OK")));
  735. /****************************************************************/
  736. /* Enable the share send components. */
  737. /****************************************************************/
  738. CCEnableShareSendCmpnts();
  739. /****************************************************************/
  740. /* Inform the UI that the connection is now complete. */
  741. /****************************************************************/
  742. _pCd->CD_DecoupleSimpleNotification(CD_UI_COMPONENT,
  743. _pUi,
  744. CD_NOTIFICATION_FUNC(CUI,UI_OnConnected),
  745. (ULONG_PTR) 0);
  746. }
  747. break;
  748. case ACT_M:
  749. {
  750. TRC_NRM((TB, _T("ACT_M: clearing up after share termination")));
  751. /****************************************************************/
  752. // The share has been terminated by the server so disable all
  753. // the share components. Note that if the session is reconnected
  754. // on the server we are not actually disconnecting since we could
  755. // receive a DemandActivePDU and start the share again.
  756. /****************************************************************/
  757. CCDisableShareSendCmpnts();
  758. CCDisableShareRecvCmpnts();
  759. CCShareEnd();
  760. /****************************************************************/
  761. /* Inform the UI that we received DeactivateAllPDU. Do it */
  762. /* synchronously so it's processed before any disconnection. */
  763. /****************************************************************/
  764. _pCd->CD_DecoupleSyncNotification(CD_UI_COMPONENT,
  765. _pUi,
  766. CD_NOTIFICATION_FUNC(CUI,UI_OnDeactivateAllPDU),
  767. 0);
  768. }
  769. break;
  770. case ACT_P:
  771. {
  772. /****************************************************************/
  773. /* Disconnect */
  774. /****************************************************************/
  775. TRC_NRM((TB, _T("ACT_P: disconnect")));
  776. _pSl->SL_Disconnect();
  777. }
  778. break;
  779. case ACT_T:
  780. {
  781. TRC_NRM((TB, _T("ACT_T: disable components and inform UI")));
  782. /****************************************************************/
  783. /* We need to disable all the share components. */
  784. /****************************************************************/
  785. CCDisableShareSendCmpnts();
  786. CCDisconnectShareRecvCmpnts();
  787. CCShareEnd();
  788. /****************************************************************/
  789. /* Reset the client MCS ID and the channel ID. */
  790. /****************************************************************/
  791. _pUi->UI_SetClientMCSID(0);
  792. _pUi->UI_SetChannelID(0);
  793. /****************************************************************/
  794. /* Inform UI that shutdown is OK */
  795. /****************************************************************/
  796. TRC_DBG((TB, _T("ACT_T: calling UI_OnShutDown(SUCCESS)")));
  797. _pCd->CD_DecoupleSimpleNotification(CD_UI_COMPONENT,
  798. _pUi,
  799. CD_NOTIFICATION_FUNC(CUI,UI_OnShutDown),
  800. (ULONG_PTR) UI_SHUTDOWN_SUCCESS);
  801. }
  802. break;
  803. case ACT_V:
  804. {
  805. TRC_NRM((TB, _T("ACT_V: calling UI_OnShutDown(success)")));
  806. /****************************************************************/
  807. /* Inform UI that shutdown is OK */
  808. /****************************************************************/
  809. _pCd->CD_DecoupleSimpleNotification(CD_UI_COMPONENT,
  810. _pUi,
  811. CD_NOTIFICATION_FUNC(CUI,UI_OnShutDown),
  812. (ULONG_PTR) UI_SHUTDOWN_SUCCESS);
  813. }
  814. break;
  815. case ACT_W:
  816. {
  817. TRC_NRM((TB, _T("ACT_W: calling UI_OnShutDown(failure)")));
  818. /****************************************************************/
  819. /* Inform UI that shutdown has been denied */
  820. /****************************************************************/
  821. _pCd->CD_DecoupleSimpleNotification(CD_UI_COMPONENT,
  822. _pUi,
  823. CD_NOTIFICATION_FUNC(CUI,UI_OnShutDown),
  824. (ULONG_PTR) UI_SHUTDOWN_FAILURE);
  825. }
  826. break;
  827. case ACT_Y:
  828. {
  829. TRC_NRM((TB, _T("ACT_Y: disconnection")));
  830. /****************************************************************/
  831. /* We need to disable all the share components. */
  832. /****************************************************************/
  833. CCDisableShareSendCmpnts();
  834. CCDisconnectShareRecvCmpnts();
  835. CCShareEnd();
  836. /****************************************************************/
  837. /* Connection has been lost, so we can safely reset the */
  838. /* client MCS ID and the channel ID. */
  839. /****************************************************************/
  840. _pUi->UI_SetClientMCSID(0);
  841. _pUi->UI_SetChannelID(0);
  842. /****************************************************************/
  843. /* Pass the UI the disconnect reason code. This reason code */
  844. /* should not occupy more than 16 bits. */
  845. /****************************************************************/
  846. TRC_ASSERT((HIWORD(data) == 0),
  847. (TB, _T("Disconnect reason code bigger then 16 bits %#x"),
  848. HIWORD(data)));
  849. _pCd->CD_DecoupleSimpleNotification(CD_UI_COMPONENT,
  850. _pUi,
  851. CD_NOTIFICATION_FUNC(CUI,UI_OnDisconnected),
  852. data);
  853. }
  854. break;
  855. case ACT_Z:
  856. {
  857. TRC_DBG((TB, _T("ACT_Z: sending ShutDownPDU")));
  858. /****************************************************************/
  859. /* Send Shutdown PDU */
  860. /****************************************************************/
  861. CCSendPDU(CC_TYPE_SHUTDOWNREQ,
  862. CC_SEND_FLAGS_DATA,
  863. TS_SHUTDOWN_REQ_PDU_SIZE,
  864. TS_HIGHPRIORITY);
  865. }
  866. break;
  867. case ACT_NO:
  868. {
  869. TRC_NRM((TB, _T("ACT_NO: Doing nothing")));
  870. }
  871. break;
  872. default:
  873. {
  874. TRC_ABORT((TB, _T("Invalid action %u"), action));
  875. }
  876. break;
  877. }
  878. DC_END_FN();
  879. } /* CC_FSMProc */
  880. /****************************************************************************/
  881. /* Name: CCBuildConfirmActive */
  882. /* */
  883. /* Purpose: Fills _CC.pBuffer and _CC.packetLen with a ConfirmActivePDU */
  884. /* and its length */
  885. /****************************************************************************/
  886. void DCINTERNAL CCC::CCBuildConfirmActivePDU()
  887. {
  888. PTS_CONFIRM_ACTIVE_PDU pConfirmActivePDU;
  889. PBYTE pCombinedCapabilities;
  890. DC_BEGIN_FN("CCBuildConfirmActivePDU");
  891. pConfirmActivePDU = (PTS_CONFIRM_ACTIVE_PDU)_CC.pBuffer;
  892. pConfirmActivePDU->shareControlHeader = _CC.shareControlHeader;
  893. pConfirmActivePDU->shareControlHeader.pduType =
  894. TS_PDUTYPE_CONFIRMACTIVEPDU | TS_PROTOCOL_VERSION;
  895. pConfirmActivePDU->shareID = _pUi->UI_GetShareID();
  896. pConfirmActivePDU->originatorID = _pUi->UI_GetServerMCSID();
  897. /************************************************************************/
  898. /* Note: source descriptor is a NULL-terminated string. */
  899. /************************************************************************/
  900. pConfirmActivePDU->lengthSourceDescriptor = (DCUINT16)
  901. DC_ASTRBYTELEN(CC_DUCATI_NAME);
  902. pConfirmActivePDU->lengthCombinedCapabilities =
  903. sizeof(CC_COMBINED_CAPABILITIES);
  904. TS_CTRLPKT_LEN(pConfirmActivePDU) =
  905. (DCUINT16)(pConfirmActivePDU->lengthSourceDescriptor +
  906. pConfirmActivePDU->lengthCombinedCapabilities +
  907. TS_CA_NON_DATA_SIZE);
  908. _CC.packetLen = TS_CTRLPKT_LEN(pConfirmActivePDU);
  909. TRC_ASSERT((CC_BUFSIZE >= _CC.packetLen),
  910. (TB,_T("CC Buffer not large enough")));
  911. StringCbCopyA((PCHAR)pConfirmActivePDU->data,
  912. sizeof(pConfirmActivePDU->data),
  913. CC_DUCATI_NAME);
  914. /************************************************************************/
  915. /* Copy the Combined Caps. */
  916. /************************************************************************/
  917. pCombinedCapabilities = pConfirmActivePDU->data +
  918. DC_ASTRBYTELEN(CC_DUCATI_NAME);
  919. DC_MEMCPY(pCombinedCapabilities,
  920. &_ccCombinedCapabilities,
  921. sizeof( CC_COMBINED_CAPABILITIES));
  922. DC_END_FN();
  923. } /* CCBuildConfirmActive */
  924. /****************************************************************************/
  925. /* Name: CCBuildSyncPDU */
  926. /* */
  927. /* Purpose: Fills _CC.pBuffer and _CC.packetLen with a SynchronizePDU */
  928. /* and its length */
  929. /****************************************************************************/
  930. void DCINTERNAL CCC::CCBuildSyncPDU()
  931. {
  932. PTS_SYNCHRONIZE_PDU pSyncPDU;
  933. DC_BEGIN_FN("CCBuildSyncPDU");
  934. pSyncPDU = (PTS_SYNCHRONIZE_PDU) _CC.pBuffer;
  935. pSyncPDU->shareDataHeader = _CC.shareDataHeader;
  936. _CC.packetLen = TS_SYNC_PDU_SIZE;
  937. TRC_ASSERT((CC_BUFSIZE >= _CC.packetLen),
  938. (TB,_T("CC Buffer not large enough")));
  939. TS_DATAPKT_LEN(pSyncPDU) = TS_SYNC_PDU_SIZE;
  940. pSyncPDU->shareDataHeader.shareControlHeader.pduType
  941. = TS_PDUTYPE_DATAPDU | TS_PROTOCOL_VERSION;
  942. TS_UNCOMP_LEN(pSyncPDU) = TS_SYNC_UNCOMP_LEN;
  943. pSyncPDU->shareDataHeader.pduType2 = TS_PDUTYPE2_SYNCHRONIZE;
  944. pSyncPDU->messageType = TS_SYNCMSGTYPE_SYNC;
  945. pSyncPDU->targetUser = _pUi->UI_GetServerMCSID();
  946. DC_END_FN();
  947. } /* CCBuildSync */
  948. /****************************************************************************/
  949. /* Name: CCBuildShutdownReqPDU */
  950. /* */
  951. /* Purpose: Fills _CC.pBuffer and _CC.packetLen with a ShutdownReqPDU */
  952. /* and its length */
  953. /****************************************************************************/
  954. void DCINTERNAL CCC::CCBuildShutdownReqPDU()
  955. {
  956. PTS_SHUTDOWN_REQ_PDU pShutdownPDU;
  957. DC_BEGIN_FN("CCBuildShutdownReqPDU");
  958. pShutdownPDU = (PTS_SHUTDOWN_REQ_PDU) _CC.pBuffer;
  959. pShutdownPDU->shareDataHeader = _CC.shareDataHeader;
  960. _CC.packetLen = TS_SHUTDOWN_REQ_PDU_SIZE;
  961. TRC_ASSERT((CC_BUFSIZE >= _CC.packetLen),
  962. (TB,_T("CC Buffer not large enough")));
  963. TS_DATAPKT_LEN(pShutdownPDU) = TS_SHUTDOWN_REQ_PDU_SIZE;
  964. pShutdownPDU->shareDataHeader.shareControlHeader.pduType
  965. = TS_PDUTYPE_DATAPDU | TS_PROTOCOL_VERSION;
  966. TS_UNCOMP_LEN(pShutdownPDU) = TS_SHUTDOWN_REQ_UNCOMP_LEN;
  967. pShutdownPDU->shareDataHeader.pduType2 = TS_PDUTYPE2_SHUTDOWN_REQUEST;
  968. DC_END_FN();
  969. } /* CCBuildShutdownReqPDU */
  970. /****************************************************************************/
  971. /* Name: CCBuildCoopControlPDU */
  972. /* */
  973. /* Purpose: Fills _CC.pBuffer and _CC.packetLen with a CoopControlPDU */
  974. /* and its length */
  975. /****************************************************************************/
  976. void DCINTERNAL CCC::CCBuildCoopControlPDU()
  977. {
  978. PTS_CONTROL_PDU pControlPDU;
  979. DC_BEGIN_FN("CCBuildCoopControlPDU");
  980. pControlPDU = (TS_CONTROL_PDU*) _CC.pBuffer;
  981. pControlPDU->shareDataHeader = _CC.shareDataHeader;
  982. _CC.packetLen = TS_CONTROL_PDU_SIZE;
  983. TRC_ASSERT((CC_BUFSIZE >= _CC.packetLen),\
  984. (TB,_T("CC Buffer not large enough")));
  985. TS_DATAPKT_LEN(pControlPDU) = TS_CONTROL_PDU_SIZE;
  986. pControlPDU->shareDataHeader.shareControlHeader.pduType
  987. = TS_PDUTYPE_DATAPDU | TS_PROTOCOL_VERSION;
  988. TS_UNCOMP_LEN(pControlPDU) = TS_CONTROL_UNCOMP_LEN;
  989. pControlPDU->shareDataHeader.pduType2 = TS_PDUTYPE2_CONTROL;
  990. pControlPDU->action = TS_CTRLACTION_COOPERATE;
  991. pControlPDU->grantId = 0;
  992. pControlPDU->controlId = 0;
  993. DC_END_FN();
  994. } /* CCBuildCoopControl */
  995. /****************************************************************************/
  996. /* Name: CCSendPDU */
  997. /* */
  998. /* Purpose: Fills and sends a specified PDU on agiven priority */
  999. /****************************************************************************/
  1000. void DCINTERNAL CCC::CCSendPDU(
  1001. unsigned pduTypeToSend,
  1002. unsigned flags,
  1003. unsigned size,
  1004. unsigned priority)
  1005. {
  1006. SL_BUFHND bufHandle;
  1007. DC_BEGIN_FN("CCSendPDU");
  1008. if (!_pSl->SL_GetBuffer(size, &_CC.pBuffer, &bufHandle)) {
  1009. // Buffer not available so can't send, try later.
  1010. TRC_ALT((TB, _T("Fail to get buffer for type %u"), pduTypeToSend));
  1011. DC_QUIT;
  1012. }
  1013. switch (pduTypeToSend) {
  1014. case CC_TYPE_CONFIRMACTIVE:
  1015. {
  1016. TRC_DBG((TB, _T("CCSendPDU handling Confirm Active PDU")));
  1017. CCBuildConfirmActivePDU();
  1018. }
  1019. break;
  1020. case CC_TYPE_SYNCHRONIZE:
  1021. {
  1022. CCBuildSyncPDU();
  1023. }
  1024. break;
  1025. case CC_TYPE_COOPCONTROL:
  1026. {
  1027. CCBuildCoopControlPDU();
  1028. }
  1029. break;
  1030. case CC_TYPE_REQUESTCONTROL:
  1031. {
  1032. CCBuildRequestControlPDU();
  1033. }
  1034. break;
  1035. case CC_TYPE_SHUTDOWNREQ:
  1036. {
  1037. CCBuildShutdownReqPDU();
  1038. }
  1039. break;
  1040. default:
  1041. {
  1042. TRC_ABORT((TB,_T("Bad PDU type")));
  1043. }
  1044. break;
  1045. }
  1046. _pSl->SL_SendPacket(_CC.pBuffer,
  1047. _CC.packetLen,
  1048. flags,
  1049. bufHandle,
  1050. _pUi->UI_GetClientMCSID(),
  1051. _pUi->UI_GetChannelID(),
  1052. priority);
  1053. _CC.pBuffer = NULL;
  1054. CCFSMProc(CC_EVT_SENTOK, 0, 0);
  1055. DC_EXIT_POINT:
  1056. DC_END_FN();
  1057. } /* CCSendPDU */
  1058. /****************************************************************************/
  1059. /* Name: CCBuildRequestControlPDU */
  1060. /* */
  1061. /* Purpose: Fills _CC.pBuffer and _CC.packetLen with a RequestControlPDU */
  1062. /* and its length */
  1063. /****************************************************************************/
  1064. void DCINTERNAL CCC::CCBuildRequestControlPDU()
  1065. {
  1066. TS_CONTROL_PDU * pControlPDU;
  1067. DC_BEGIN_FN("CCBuildRequestControlPDU");
  1068. pControlPDU = (PTS_CONTROL_PDU) _CC.pBuffer;
  1069. pControlPDU->shareDataHeader = _CC.shareDataHeader;
  1070. _CC.packetLen = TS_CONTROL_PDU_SIZE;
  1071. TRC_ASSERT((CC_BUFSIZE >= _CC.packetLen),\
  1072. (TB,_T("CC Buffer not large enough")));
  1073. pControlPDU->shareDataHeader.shareControlHeader.pduType
  1074. = TS_PDUTYPE_DATAPDU | TS_PROTOCOL_VERSION;
  1075. TS_DATAPKT_LEN(pControlPDU) = TS_CONTROL_PDU_SIZE;
  1076. TS_UNCOMP_LEN(pControlPDU) = TS_CONTROL_UNCOMP_LEN;
  1077. pControlPDU->shareDataHeader.pduType2 = TS_PDUTYPE2_CONTROL;
  1078. pControlPDU->action = TS_CTRLACTION_REQUEST_CONTROL;
  1079. pControlPDU->grantId = 0;
  1080. pControlPDU->controlId = 0;
  1081. DC_END_FN();
  1082. } /* CCBuildRequestControl */
  1083. /****************************************************************************/
  1084. /* Name: CCBuildShareHeaders */
  1085. /* */
  1086. /* Purpose: Fills in Core ShareControl and ShareData headers */
  1087. /****************************************************************************/
  1088. void DCINTERNAL CCC::CCBuildShareHeaders()
  1089. {
  1090. DC_BEGIN_FN("CCBuildShareHeaders");
  1091. _CC.shareControlHeader.totalLength = 0; /* sender sets this */
  1092. _CC.shareControlHeader.pduType = 0; /* sender sets this */
  1093. _CC.shareControlHeader.pduSource = _pUi->UI_GetClientMCSID();
  1094. _CC.shareDataHeader.shareControlHeader = _CC.shareControlHeader;
  1095. _CC.shareDataHeader.shareID = _pUi->UI_GetShareID();
  1096. _CC.shareDataHeader.pad1 = 0;
  1097. _CC.shareDataHeader.streamID = TS_STREAM_LOW;
  1098. _CC.shareDataHeader.uncompressedLength = 0; /* sender sets this */
  1099. _CC.shareDataHeader.pduType2 = 0; /* sender sets this */
  1100. _CC.shareDataHeader.generalCompressedType = 0;
  1101. _CC.shareDataHeader.generalCompressedLength= 0;
  1102. DC_END_FN();
  1103. } /* CCBuildShareHeaders */
  1104. /****************************************************************************/
  1105. /* Name: CCShareStart */
  1106. /* */
  1107. /* Purpose: Called when a share is established. */
  1108. /****************************************************************************/
  1109. HRESULT DCINTERNAL CCC::CCShareStart(PTS_DEMAND_ACTIVE_PDU pPDU, DCUINT dataLen,
  1110. PBOOL pfSecureChecksum)
  1111. {
  1112. HRESULT hrc = S_OK;
  1113. UINT32 sessionId;
  1114. PTS_INPUT_CAPABILITYSET pInputCaps;
  1115. PTS_ORDER_CAPABILITYSET pOrderCaps;
  1116. DCSIZE desktopSize;
  1117. PTS_BITMAP_CAPABILITYSET pBitmapCaps;
  1118. PTS_VIRTUALCHANNEL_CAPABILITYSET pVCCaps = NULL;
  1119. PTS_DRAW_GDIPLUS_CAPABILITYSET pDrawGdipCaps = NULL;
  1120. DC_BEGIN_FN("CCShareStart");
  1121. TRC_ASSERT((pPDU != NULL), (TB, _T("Null demand active PDU")));
  1122. /************************************************************************/
  1123. /* SECURITY: We verified that this PDU has at least enough data for the */
  1124. /* TS_DEMAND_ACTIVE_PDU struct in aco.cpp!CO_OnPacketReceived. */
  1125. /************************************************************************/
  1126. /************************************************************************/
  1127. /* Keep a copy of the server's share ID. */
  1128. /************************************************************************/
  1129. TRC_NRM((TB, _T("Save shareID %#x"), pPDU->shareID));
  1130. _pUi->UI_SetShareID(pPDU->shareID);
  1131. /************************************************************************/
  1132. /* Let UT know about the server's MCS user ID. */
  1133. /************************************************************************/
  1134. _pUi->UI_SetServerMCSID(pPDU->shareControlHeader.pduSource);
  1135. /************************************************************************/
  1136. /* Verify that the capabilities offset is within the PDU, and the cap */
  1137. /* length fits within the PDU. Throughout this function, UT_GetCapsSet */
  1138. /* is called with pointers to the caps and the caps length. */
  1139. /* */
  1140. /* Also, note that the last 4 bytes of this PDU can be the sessionId, */
  1141. /* but if someone's going to send the cap length as garbage, there's no */
  1142. /* reason to force the cap length to end 4 bytes before the packet end. */
  1143. /************************************************************************/
  1144. if (!IsContainedMemory(pPDU, dataLen, pPDU->data + pPDU->lengthSourceDescriptor, pPDU->lengthCombinedCapabilities))
  1145. {
  1146. TRC_ABORT((TB, _T("Capabilities (%u) is larger than packet size"), pPDU->lengthCombinedCapabilities));
  1147. _pSl->SLSetReasonAndDisconnect(SL_ERR_INVALIDPACKETFORMAT);
  1148. hrc = E_ABORT;
  1149. DC_QUIT;
  1150. }
  1151. PTS_GENERAL_CAPABILITYSET pGeneralCaps;
  1152. pGeneralCaps = (PTS_GENERAL_CAPABILITYSET) _pUt->UT_GetCapsSet(
  1153. pPDU->lengthCombinedCapabilities,
  1154. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1155. pPDU->lengthSourceDescriptor),
  1156. TS_CAPSETTYPE_GENERAL);
  1157. TRC_ASSERT((pGeneralCaps != NULL),(TB,_T("General capabilities not found")));
  1158. //
  1159. // A word about the safe checksum fix:
  1160. // The feature is a fix to salt the checksum with a running counter
  1161. // The problem is that checksumming plaintext leaves us vulnerable
  1162. // to frequency analysis of the checksums (since input packets for the same
  1163. // scancode will return the same checksum).
  1164. //
  1165. // To negotiate caps for this encryption setting
  1166. // a handshake must occur where one side requests the feature and the other side
  1167. // ackownledges it before you can start encrypting in the new way. The packets
  1168. // also have a bit set in the security header identifying which type of checksum
  1169. // is in effect.
  1170. //
  1171. // If the server advertises support for receiving C->S newly checksummed data
  1172. // then acknowlege it here, this completes the handshake any further data
  1173. // transfers to the server will now checksum the encrypted bytes.
  1174. //
  1175. // Also the server can now start sending us data in the checksummed encrypted format
  1176. //
  1177. if (pGeneralCaps &&
  1178. pGeneralCaps->extraFlags & TS_ENC_SECURE_CHECKSUM) {
  1179. _ccCombinedCapabilities.generalCapabilitySet.extraFlags |=
  1180. TS_ENC_SECURE_CHECKSUM;
  1181. *pfSecureChecksum = TRUE;
  1182. }
  1183. else {
  1184. _ccCombinedCapabilities.generalCapabilitySet.extraFlags &=
  1185. ~TS_ENC_SECURE_CHECKSUM;
  1186. *pfSecureChecksum = FALSE;
  1187. }
  1188. /************************************************************************/
  1189. /* If the call supports shadowing of sessions bigger than our current */
  1190. /* desktop size, then we'd better take note of the returned size */
  1191. /************************************************************************/
  1192. pBitmapCaps = (PTS_BITMAP_CAPABILITYSET) _pUt->UT_GetCapsSet(
  1193. pPDU->lengthCombinedCapabilities,
  1194. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1195. pPDU->lengthSourceDescriptor),
  1196. TS_CAPSETTYPE_BITMAP);
  1197. TRC_ASSERT((pBitmapCaps != NULL),(TB,_T("Bitmap capabilities not found")));
  1198. if (pBitmapCaps && pBitmapCaps->desktopResizeFlag == TS_CAPSFLAG_SUPPORTED)
  1199. {
  1200. TRC_ALT((TB, _T("New desktop size %u x %u"),
  1201. pBitmapCaps->desktopWidth,
  1202. pBitmapCaps->desktopHeight));
  1203. /********************************************************************/
  1204. /* Pass the desktop size to UT - it will be picked up in UH_Enable */
  1205. /********************************************************************/
  1206. desktopSize.width = pBitmapCaps->desktopWidth;
  1207. desktopSize.height = pBitmapCaps->desktopHeight;
  1208. _pUi->UI_OnDesktopSizeChange(&desktopSize);
  1209. /********************************************************************/
  1210. /* And notify the client */
  1211. /********************************************************************/
  1212. PostMessage(_pUi->UI_GetUIMainWindow(), WM_DESKTOPSIZECHANGE, 0,
  1213. MAKELPARAM(desktopSize.width, desktopSize.height) );
  1214. }
  1215. #ifdef DC_HICOLOR
  1216. /************************************************************************/
  1217. /* Set up the returned color depth */
  1218. /************************************************************************/
  1219. if( pBitmapCaps )
  1220. {
  1221. TRC_ALT((TB, _T("Server returned %u bpp"), pBitmapCaps->preferredBitsPerPixel));
  1222. _pUi->UI_SetColorDepth(pBitmapCaps->preferredBitsPerPixel);
  1223. }
  1224. #endif
  1225. /************************************************************************/
  1226. /* Pass the input capabilities to IH. */
  1227. /************************************************************************/
  1228. pInputCaps = (PTS_INPUT_CAPABILITYSET)_pUt->UT_GetCapsSet(
  1229. pPDU->lengthCombinedCapabilities,
  1230. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1231. pPDU->lengthSourceDescriptor),
  1232. TS_CAPSETTYPE_INPUT);
  1233. TRC_ASSERT((pInputCaps != NULL),(TB,_T("Input capabilities not found")));
  1234. if (pInputCaps != NULL)
  1235. _pIh->IH_ProcessInputCaps(pInputCaps);
  1236. /************************************************************************/
  1237. /* The orders caps go to UH. */
  1238. /************************************************************************/
  1239. pOrderCaps = (PTS_ORDER_CAPABILITYSET)_pUt->UT_GetCapsSet(
  1240. pPDU->lengthCombinedCapabilities,
  1241. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1242. pPDU->lengthSourceDescriptor),
  1243. TS_CAPSETTYPE_ORDER);
  1244. TRC_ASSERT((pOrderCaps != NULL),(TB,_T("Order capabilities not found")));
  1245. if (pOrderCaps != NULL)
  1246. _pUh->UH_ProcessServerCaps(pOrderCaps);
  1247. /************************************************************************/
  1248. // Send the bitmap cache HOSTSUPPORT caps to UH, whether or not present.
  1249. /************************************************************************/
  1250. _pUh->UH_ProcessBCHostSupportCaps(
  1251. (PTS_BITMAPCACHE_CAPABILITYSET_HOSTSUPPORT)_pUt->UT_GetCapsSet(
  1252. pPDU->lengthCombinedCapabilities,
  1253. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1254. pPDU->lengthSourceDescriptor),
  1255. TS_CAPSETTYPE_BITMAPCACHE_HOSTSUPPORT));
  1256. //
  1257. // Get virtual channel caps
  1258. //
  1259. pVCCaps = (PTS_VIRTUALCHANNEL_CAPABILITYSET)_pUt->UT_GetCapsSet(
  1260. pPDU->lengthCombinedCapabilities,
  1261. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1262. pPDU->lengthSourceDescriptor),
  1263. TS_CAPSETTYPE_VIRTUALCHANNEL);
  1264. if(pVCCaps)
  1265. {
  1266. //Inform VC layer of the capabilities
  1267. _pCChan->SetCapabilities(pVCCaps->vccaps1);
  1268. }
  1269. else
  1270. {
  1271. //No VCCaps, could be an older server. Set default caps
  1272. _pCChan->SetCapabilities(TS_VCCAPS_DEFAULT);
  1273. }
  1274. //
  1275. // Get draw gdiplus caps
  1276. //
  1277. pDrawGdipCaps = (PTS_DRAW_GDIPLUS_CAPABILITYSET)_pUt->UT_GetCapsSet(
  1278. pPDU->lengthCombinedCapabilities,
  1279. (PTS_COMBINED_CAPABILITIES)(pPDU->data +
  1280. pPDU->lengthSourceDescriptor),
  1281. TS_CAPSETTYPE_DRAWGDIPLUS);
  1282. if (pDrawGdipCaps) {
  1283. _pUh->UH_SetServerGdipSupportLevel(pDrawGdipCaps->drawGdiplusSupportLevel);
  1284. }
  1285. else {
  1286. _pUh->UH_SetServerGdipSupportLevel(TS_DRAW_GDIPLUS_DEFAULT);
  1287. }
  1288. /************************************************************************/
  1289. /* Set SessionId */
  1290. /************************************************************************/
  1291. if (pPDU->shareControlHeader.totalLength >
  1292. (sizeof(TS_DEMAND_ACTIVE_PDU) - 1 + pPDU->lengthSourceDescriptor +
  1293. pPDU->lengthCombinedCapabilities))
  1294. {
  1295. memcpy(&sessionId,
  1296. pPDU->data + pPDU->lengthSourceDescriptor +
  1297. pPDU->lengthCombinedCapabilities,
  1298. sizeof(sessionId));
  1299. TRC_ALT((TB, _T("Session ID: %ld"), sessionId));
  1300. }
  1301. else {
  1302. sessionId = 0;
  1303. TRC_ALT((TB, _T("Session ID is zero"), sessionId));
  1304. }
  1305. _pUi->UI_SetSessionId(sessionId);
  1306. DC_EXIT_POINT:
  1307. DC_END_FN();
  1308. return(hrc);
  1309. } /* CCShareStart */
  1310. /****************************************************************************/
  1311. /* Name: CCShareEnd */
  1312. /* */
  1313. /* Purpose: Called when a share ends. */
  1314. /****************************************************************************/
  1315. void DCINTERNAL CCC::CCShareEnd()
  1316. {
  1317. DC_BEGIN_FN("CCShareEnd");
  1318. // Reset ServerMCSID and ChannelID.
  1319. TRC_NRM((TB, _T("Resetting ServerMCSID and ChannelID")));
  1320. _pUi->UI_SetServerMCSID(0);
  1321. // Finally reset the share ID.
  1322. TRC_NRM((TB, _T("Resetting ShareID")));
  1323. _pUi->UI_SetShareID(0);
  1324. DC_END_FN();
  1325. } /* CCShareEnd */