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.

2725 lines
91 KiB

  1. #include "precomp.h"
  2. //
  3. // S20.CPP
  4. // T.128 Protocol
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_NET
  9. BOOL S20AcceptNewCorrelator(PS20CREATEPACKET pS20Packet);
  10. void PrintS20State(void)
  11. {
  12. switch(g_s20State)
  13. {
  14. case S20_TERM:
  15. WARNING_OUT(("g_s20State is S20_TERM"));
  16. break;
  17. case S20_INIT:
  18. WARNING_OUT(("g_s20State is S20_INIT"));
  19. break;
  20. case S20_ATTACH_PEND:
  21. WARNING_OUT(("g_s20State is S20_ATTACH_PEND"));
  22. break;
  23. case S20_JOIN_PEND:
  24. WARNING_OUT(("g_s20State is S20_JOIN_PEND"));
  25. break;
  26. case S20_NO_SHARE:
  27. WARNING_OUT(("g_s20State is S20_NO_SHARE"));
  28. break;
  29. case S20_SHARE_PEND:
  30. WARNING_OUT(("g_s20State is S20_SHARE_PEND"));
  31. break;
  32. case S20_SHARE_STARTING:
  33. WARNING_OUT(("g_s20State is S20_SHARE_STARTING"));
  34. break;
  35. case S20_IN_SHARE:
  36. WARNING_OUT(("g_s20State is S20_IN_SHARE"));
  37. break;
  38. case S20_NUM_STATES:
  39. WARNING_OUT(("g_s20State is S20_NUM_STATES"));
  40. break;
  41. }
  42. }
  43. #ifdef _DEBUG
  44. #define PRINTS20STATE PrintS20State();
  45. #else
  46. #define PRINTS20STATE
  47. #endif
  48. void SetS20State(UINT newState)
  49. {
  50. PRINTS20STATE;
  51. g_s20State = newState;
  52. PRINTS20STATE;
  53. }
  54. //
  55. // S20_Init()
  56. // Initializes the T.128 protocol layer
  57. //
  58. BOOL S20_Init(void)
  59. {
  60. BOOL rc = FALSE;
  61. DebugEntry(S20_Init);
  62. ASSERT(g_s20State == S20_TERM);
  63. //
  64. // Register with the network layer.
  65. //
  66. if (!MG_Register(MGTASK_DCS, &g_s20pmgClient, g_putAS))
  67. {
  68. ERROR_OUT(("Failed to register MG layer"));
  69. DC_QUIT;
  70. }
  71. SetS20State(S20_INIT);
  72. rc = TRUE;
  73. DC_EXIT_POINT:
  74. DebugExitBOOL(S20_Init, rc);
  75. return(rc);
  76. }
  77. //
  78. // S20_Term()
  79. // This cleans up the T.128 protocol layer.
  80. //
  81. void S20_Term(void)
  82. {
  83. DebugEntry(S20_Term);
  84. //
  85. // Note that this case statement is unusual in that it falls through
  86. // from each condition. This happens to suit the termination
  87. // processing rather well.
  88. //
  89. switch (g_s20State)
  90. {
  91. case S20_IN_SHARE:
  92. case S20_SHARE_PEND:
  93. //
  94. // Notify share ended
  95. //
  96. SC_End();
  97. //
  98. // FALL THROUGH
  99. //
  100. case S20_NO_SHARE:
  101. case S20_JOIN_PEND:
  102. //
  103. // Leave our channels
  104. //
  105. if (g_s20BroadcastID != 0)
  106. {
  107. MG_ChannelLeave(g_s20pmgClient, g_s20BroadcastID);
  108. g_s20BroadcastID = 0;
  109. }
  110. if (g_s20JoinedLocal)
  111. {
  112. MG_ChannelLeave(g_s20pmgClient, g_s20LocalID);
  113. g_s20JoinedLocal = FALSE;
  114. }
  115. //
  116. // FALL THROUGH
  117. //
  118. case S20_ATTACH_PEND:
  119. //
  120. // Detach from the domain.
  121. //
  122. MG_Detach(g_s20pmgClient);
  123. case S20_INIT:
  124. //
  125. // We may end up here with g_s20BroadcastID & g_s20JoinedLocal
  126. // non-zero if Term was called in the middle of a share. Clear these
  127. // variables so when we start back up again via Init, it
  128. // works the same way as first initialization.
  129. //
  130. // Note we do not need to leave the channels.
  131. //
  132. g_s20BroadcastID = 0;
  133. g_s20JoinedLocal = FALSE;
  134. //
  135. // Deregister.
  136. //
  137. MG_Deregister(&g_s20pmgClient);
  138. SetS20State(S20_TERM);
  139. case S20_TERM:
  140. WARNING_OUT(("g_s20LocalID was %x", g_s20LocalID));
  141. g_s20LocalID = 0;
  142. WARNING_OUT(("g_s20LocalID is 0"));
  143. //
  144. // Finally we break out.
  145. //
  146. break;
  147. default:
  148. ERROR_OUT(("invalid state %d", g_s20State));
  149. break;
  150. }
  151. DebugExitVOID(S20_Term);
  152. }
  153. //
  154. // S20_AllocPkt
  155. // Allocates a SEND packet for either the S20 protocol, syncs, or data
  156. //
  157. PS20DATAPACKET S20_AllocDataPkt
  158. (
  159. UINT streamID,
  160. UINT_PTR nodeID, // One person or broadcast
  161. UINT_PTR cbSizePacket
  162. )
  163. {
  164. PS20DATAPACKET pS20Packet = NULL;
  165. NET_PRIORITY priority;
  166. BOOL rc = FALSE;
  167. // DebugEntry(S20_AllocDataPkt);
  168. ASSERT(g_s20State == S20_IN_SHARE);
  169. //
  170. // Try to send queued control packets first.
  171. //
  172. if (S20SendQueuedControlPackets() != 0)
  173. {
  174. //
  175. // If there are still queued control packets then don't allow any
  176. // allocation.
  177. //
  178. DC_QUIT;
  179. }
  180. priority = S20StreamToS20Priority(streamID);
  181. //
  182. // Note:
  183. // Sends to an individual node are NOT flow-controlled. Only the
  184. // global app sharing channel is.
  185. //
  186. if (MG_GetBuffer(g_s20pmgClient, (UINT)cbSizePacket, priority,
  187. (NET_CHANNEL_ID)nodeID, (void **)&pS20Packet) != 0)
  188. {
  189. TRACE_OUT(("MG_GetBuffer failed; can't allocate S20 packet"));
  190. }
  191. else
  192. {
  193. pS20Packet->header.packetType = S20_DATA | S20_ALL_VERSIONS;
  194. pS20Packet->header.user = g_s20LocalID;
  195. pS20Packet->correlator = g_s20ShareCorrelator;
  196. pS20Packet->stream = 0;
  197. pS20Packet->dataLength = (USHORT)cbSizePacket - sizeof(S20DATAPACKET) + sizeof(DATAPACKETHEADER);
  198. rc = TRUE;
  199. }
  200. DC_EXIT_POINT:
  201. // DebugExitPVOID(S20_AllocDataPkt, pS20Packet);
  202. return(pS20Packet);
  203. }
  204. //
  205. // S20_FreeDataPkt - see s20.h
  206. //
  207. void S20_FreeDataPkt(PS20DATAPACKET pS20Packet)
  208. {
  209. DebugEntry(S20_FreeDataPkt);
  210. MG_FreeBuffer(g_s20pmgClient, (void **)&pS20Packet);
  211. DebugExitVOID(S20_FreeDataPkt);
  212. }
  213. //
  214. // S20_SendDataPkt - see s20.h
  215. //
  216. void S20_SendDataPkt
  217. (
  218. UINT streamID,
  219. UINT_PTR nodeID,
  220. PS20DATAPACKET pS20Packet
  221. )
  222. {
  223. UINT rc;
  224. NET_PRIORITY priority;
  225. DebugEntry(S20_SendDataPkt);
  226. priority = S20StreamToS20Priority(streamID);
  227. //
  228. // Note:
  229. // Sends to an individual are not flow-controlled. Only sends to
  230. // everybody on the global app sharing channel are.
  231. //
  232. //
  233. // Try to send queued control packets first.
  234. //
  235. rc = S20SendQueuedControlPackets();
  236. if (rc == 0)
  237. {
  238. //
  239. // Fill in the stream, length and correlator before sending.
  240. //
  241. pS20Packet->stream = (BYTE)streamID;
  242. pS20Packet->correlator = g_s20ShareCorrelator;
  243. //
  244. // dataLength includes the DATAPACKETHEADER part of the S20DATAPACKET
  245. // structure
  246. //
  247. TRACE_OUT(("S20_SendPkt: sending data packet size %d",
  248. pS20Packet->dataLength + sizeof(S20DATAPACKET) - sizeof(DATAPACKETHEADER)));
  249. rc = MG_SendData(g_s20pmgClient, priority, (NET_CHANNEL_ID)nodeID,
  250. pS20Packet->dataLength + sizeof(S20DATAPACKET) - sizeof(DATAPACKETHEADER),
  251. (void **)&pS20Packet);
  252. }
  253. // lonchanc: it is ok for MG_SendData returns 0 and NET_CHANNEL_EMPTY
  254. if (rc == NET_RC_MGC_NOT_CONNECTED)
  255. {
  256. WARNING_OUT(("S20_SenddataPacket could not MG_SendData"));
  257. S20LeaveOrEndShare();
  258. }
  259. else
  260. {
  261. if (rc != 0)
  262. {
  263. ERROR_OUT(("SendData rc=%lx - expecting share termination soon", rc));
  264. }
  265. }
  266. DebugExitVOID(S20_SendDataPkt);
  267. }
  268. //
  269. // S20_UTEventProc()
  270. //
  271. BOOL CALLBACK S20_UTEventProc
  272. (
  273. LPVOID userData,
  274. UINT event,
  275. UINT_PTR data1,
  276. UINT_PTR data2
  277. )
  278. {
  279. BOOL processed;
  280. DebugEntry(S20_UTEventProc);
  281. processed = TRUE;
  282. switch (event)
  283. {
  284. case NET_EVENT_USER_ATTACH:
  285. S20AttachConfirm(LOWORD(data1), HIWORD(data1), (UINT)data2);
  286. break;
  287. case NET_EVENT_USER_DETACH:
  288. S20DetachIndication(LOWORD(data1), (UINT)data2);
  289. break;
  290. case NET_EVENT_CHANNEL_JOIN:
  291. S20JoinConfirm((PNET_JOIN_CNF_EVENT)data2);
  292. MG_FreeBuffer(g_s20pmgClient, (void **)&data2);
  293. break;
  294. case NET_EVENT_CHANNEL_LEAVE:
  295. S20LeaveIndication(LOWORD(data1),(UINT)data2);
  296. break;
  297. case NET_EVENT_DATA_RECEIVED:
  298. S20SendIndication((PNET_SEND_IND_EVENT)data2);
  299. break;
  300. case NET_FLOW:
  301. //
  302. // Handle the feedback event.
  303. //
  304. S20Flow((UINT)data1, (UINT)data2);
  305. break;
  306. case CMS_NEW_CALL:
  307. if (g_asSession.scState == SCS_INIT)
  308. {
  309. //
  310. // This happens when (a) a new real call is started
  311. // (b) creating a new share in a call fails, so we want to
  312. // then try to join an existing share.
  313. //
  314. SCCheckForCMCall();
  315. }
  316. break;
  317. case CMS_END_CALL:
  318. if (g_asSession.callID)
  319. {
  320. //
  321. // AS lock protects g_asSession global fields
  322. //
  323. TRACE_OUT(("AS LOCK: CMS_END_CALL"));
  324. UT_Lock(UTLOCK_AS);
  325. g_asSession.gccID = 0;
  326. g_asSession.callID = 0;
  327. g_asSession.attendeePermissions = NM_PERMIT_ALL;
  328. UT_Unlock(UTLOCK_AS);
  329. TRACE_OUT(("AS UNLOCK: CMS_END_CALL"));
  330. if (g_asSession.scState > SCS_SHAREENDING)
  331. {
  332. SC_EndShare();
  333. }
  334. if (g_asSession.hwndHostUI)
  335. {
  336. SendMessage(g_asSession.hwndHostUI, HOST_MSG_CALL, FALSE, 0);
  337. }
  338. DCS_NotifyUI(SH_EVT_APPSHARE_READY, FALSE, 0);
  339. g_s20BroadcastID = 0;
  340. g_s20JoinedLocal = FALSE;
  341. SetS20State(S20_INIT);
  342. g_s20LocalID = 0;
  343. }
  344. break;
  345. default:
  346. processed = FALSE;
  347. break;
  348. }
  349. DebugExitBOOL(S20_UTEventProc, processed);
  350. return(processed);
  351. }
  352. //
  353. // FUNCTION: S20AttachUser
  354. //
  355. // DESCRIPTION:
  356. //
  357. // Called when we want to attach this sets up the various parameters for
  358. // MG_Attach, calls it and handles the return codes from NET.
  359. //
  360. // PARAMETERS:
  361. //
  362. // callID - the callID provided by the SC user
  363. //
  364. //
  365. //
  366. const NET_FLOW_CONTROL c_S20FlowControl =
  367. {
  368. // latency
  369. {
  370. S20_LATENCY_TOP_PRIORITY,
  371. S20_LATENCY_HIGH_PRIORITY,
  372. S20_LATENCY_MEDIUM_PRIORITY,
  373. S20_LATENCY_LOW_PRIORITY
  374. },
  375. // stream size
  376. {
  377. S20_SIZE_TOP_PRIORITY,
  378. S20_SIZE_HIGH_PRIORITY,
  379. S20_SIZE_MEDIUM_PRIORITY,
  380. S20_SIZE_LOW_PRIORITY
  381. }
  382. };
  383. //
  384. // S20CreateOrJoinShare()
  385. // Creates a share for the first time or joins an existing one
  386. //
  387. // Normally, creating a share requires
  388. // * registration
  389. // * broadcast of S20_CREATE packet
  390. // * reception of one S20_RESPOND packet
  391. // for the share to be created. However, if we're the top provider, we
  392. // assume it's created without waiting for an S20_RESPOND. If something
  393. // goes wrong later, it will clean itself up anyway. Then that allows us
  394. // to host a conference, share an app, and have it be shared through the
  395. // life of the conference, even if remotes call/hang up repeatedly.
  396. //
  397. BOOL S20CreateOrJoinShare
  398. (
  399. UINT what,
  400. UINT_PTR callID
  401. )
  402. {
  403. UINT rc = 0;
  404. BOOL noFlowControl;
  405. NET_FLOW_CONTROL flowControl;
  406. DebugEntry(S20CreateOrJoinShare);
  407. ASSERT((what == S20_CREATE) || (what == S20_JOIN));
  408. WARNING_OUT(("S20CreateOrJoinShare: s20 state = %x what is %s g_s20correlator = %x",
  409. g_s20State, what == S20_CREATE ? "S20_CREATE" : "S20_JOIN", g_s20ShareCorrelator));
  410. switch (g_s20State)
  411. {
  412. case S20_INIT:
  413. //
  414. // Remember what to do when we have attached and joined.
  415. //
  416. g_s20Pend = what;
  417. //
  418. // ATTACH the S20 MCS USER
  419. //
  420. COM_ReadProfInt(DBG_INI_SECTION_NAME, S20_INI_NOFLOWCONTROL,
  421. FALSE, &noFlowControl);
  422. if (noFlowControl)
  423. {
  424. WARNING_OUT(("S20 Flow Control is OFF"));
  425. ZeroMemory(&flowControl, sizeof(flowControl));
  426. }
  427. else
  428. {
  429. // Set up our target latencies and stream sizes
  430. flowControl = c_S20FlowControl;
  431. }
  432. //
  433. // Initiate an attach - the domain equals the callID.
  434. //
  435. rc = MG_Attach(g_s20pmgClient, callID, &flowControl);
  436. if (rc == 0)
  437. {
  438. //
  439. // Make the state change if we succeeded
  440. //
  441. SetS20State(S20_ATTACH_PEND);
  442. }
  443. else
  444. {
  445. //
  446. // End the share immediately and no state change.
  447. //
  448. WARNING_OUT(("MG_Attach of S20 User failed, rc = %u", rc));
  449. g_s20Pend = 0;
  450. SC_End();
  451. }
  452. break;
  453. case S20_ATTACH_PEND:
  454. case S20_JOIN_PEND:
  455. //
  456. // We just need to set the flag in these cases - we will try
  457. // to create a share when we have attached and joined our
  458. // channel.
  459. //
  460. g_s20Pend = what;
  461. break;
  462. case S20_SHARE_PEND:
  463. //
  464. // If a share is pending but the SC user wants to create
  465. // or join again we let them. Multiple outstanding joins are
  466. // benign and another create will have a new correlator so the
  467. // previous one (and any responses to it) will be obsolete.
  468. //
  469. // NOTE DELIBERATE FALL THROUGH
  470. //
  471. //
  472. case S20_NO_SHARE:
  473. TRACE_OUT(("S20_NO_SHARE"));
  474. //
  475. // Broadcast a S20CREATE packet.
  476. //
  477. if (what == S20_CREATE)
  478. {
  479. WARNING_OUT(("S20CreateOrJoinShare g_s20ShareCorrelator%x g_s20LocalID %x",
  480. g_s20ShareCorrelator, g_s20LocalID));
  481. g_s20ShareCorrelator = S20NewCorrelator();
  482. WARNING_OUT(("S20CreateOrJoinShare g_s20ShareCorrelator%x g_s20LocalID %x",
  483. g_s20ShareCorrelator, g_s20LocalID));
  484. WARNING_OUT(("CP CREATE %lu %d", g_s20ShareCorrelator, 0));
  485. rc = S20FlushAndSendControlPacket(what,
  486. g_s20ShareCorrelator,
  487. 0,
  488. NET_TOP_PRIORITY);
  489. }
  490. else
  491. {
  492. g_s20ShareCorrelator = 0;
  493. WARNING_OUT(("S20CreateOrJoinShare: S20_JOIN g_s20ShareCorrelator is set to 0 state is S20_NO_SHARE g_s20LocalID %x",
  494. g_s20LocalID));
  495. TRACE_OUT(("CP JOIN %lu %d", 0, 0));
  496. rc = S20FlushAndSendControlPacket(what, 0, 0,
  497. NET_TOP_PRIORITY);
  498. }
  499. WARNING_OUT(("S20FlushAndSendControlPacket %u, what %s", rc, what == S20_CREATE ? "s20_create":"s20_join"));
  500. if (rc == 0)
  501. {
  502. //
  503. // Switch state.
  504. //
  505. SetS20State(S20_SHARE_PEND);
  506. //
  507. // Assume success right away when creating the share. We'll
  508. // hear back in a bit if there's a problem.
  509. //
  510. if (what == S20_CREATE)
  511. {
  512. // Don't check for top provider, assume success always.
  513. WARNING_OUT(("S20: Creating share, assume success"));
  514. //
  515. // LAURABU -- IF THIS CAUSES PROBLEMS, fall back to
  516. // checking for one person only in call.
  517. //
  518. WARNING_OUT(("S20CreateOrJoinShare SC_Start"));
  519. if (!SC_Start(g_s20LocalID))
  520. {
  521. WARNING_OUT(("S20CreateOrJoin: couldn't start share"));
  522. SC_End();
  523. }
  524. else
  525. {
  526. SetS20State(S20_IN_SHARE);
  527. }
  528. }
  529. }
  530. else
  531. {
  532. //
  533. // Something failed so we will just forget about the share.
  534. //
  535. WARNING_OUT(("Failed to create share"));
  536. if (what == S20_CREATE)
  537. {
  538. SC_End();
  539. }
  540. }
  541. break;
  542. default:
  543. ERROR_OUT(("Invalid state %u for %u", g_s20State, what));
  544. }
  545. DebugExitBOOL(S20CreateOrJoinShare, (rc == 0));
  546. return(rc == 0);
  547. }
  548. //
  549. // FUNCTION: S20LeaveOrEndShare
  550. //
  551. // DESCRIPTION:
  552. //
  553. // Handles processing a S20_LeaveShare or a S20_EndShare call.
  554. //
  555. // PARAMETERS:
  556. //
  557. // what - what to do (the protocol packet type corresponding to the
  558. // action).
  559. //
  560. // RETURNS: NONE
  561. //
  562. //
  563. void S20LeaveOrEndShare(void)
  564. {
  565. UINT what;
  566. UINT rc = 0;
  567. DebugEntry(S20LeaveOrEndShare);
  568. //
  569. // The share is destroyed whenever the creator leaves. Nobody else
  570. // can end it.
  571. //
  572. if (S20_GET_CREATOR(g_s20ShareCorrelator) == g_s20LocalID)
  573. {
  574. what = S20_END;
  575. }
  576. else
  577. {
  578. what = S20_LEAVE;
  579. }
  580. ASSERT(what == S20_LEAVE || what == S20_END);
  581. WARNING_OUT((" S20LeaveOrEndShare: g_s20LocalID %x, g_s20State %x what %s",
  582. g_s20LocalID, g_s20State, S20_END == what ? "S20_END" : "S20_LEAVE"));
  583. switch (g_s20State)
  584. {
  585. case S20_ATTACH_PEND:
  586. case S20_JOIN_PEND:
  587. //
  588. // We just need to reset the pending flags here - no state
  589. // change required.
  590. //
  591. g_s20Pend = 0;
  592. break;
  593. case S20_IN_SHARE:
  594. case S20_SHARE_PEND:
  595. TRACE_OUT(("S20_SHARE_PEND"));
  596. //
  597. // Now try and make and send the appropriate control packet.
  598. //
  599. TRACE_OUT(("CP %u %u %d", what, g_s20ShareCorrelator, 0));
  600. rc = S20FlushSendOrQueueControlPacket(what,
  601. g_s20ShareCorrelator,
  602. 0,
  603. NET_TOP_PRIORITY);
  604. if(rc != 0)
  605. {
  606. WARNING_OUT(("S20LeaveOrEndShare could not flushqueue"));
  607. }
  608. //
  609. // Make the SHARE_ENDED callback.
  610. //
  611. SC_End();
  612. break;
  613. default:
  614. WARNING_OUT(("invalid state %d for %d", g_s20State, what));
  615. break;
  616. }
  617. DebugExitVOID(S20LeaveOrEndShare);
  618. }
  619. //
  620. // FUNCTION: S20MakeControlPacket
  621. //
  622. // DESCRIPTION:
  623. //
  624. // Attempts to allocate and construct a S20 control packet.
  625. //
  626. // PARAMETERS:
  627. //
  628. // what - which type of packet
  629. //
  630. // correlator - the correlator to place in the packet
  631. //
  632. // who - the target party (if what is a S20_DELETE) or the originator (if
  633. // what is S20_RESPOND)
  634. //
  635. // ppPacket - where to return a pointer to the packet.
  636. //
  637. // pLength - where to return the length of the packet.
  638. //
  639. // priority - priority of packet to make
  640. //
  641. // RETURNS:
  642. //
  643. //
  644. UINT S20MakeControlPacket
  645. (
  646. UINT what,
  647. UINT correlator,
  648. UINT who,
  649. PS20PACKETHEADER * ppPacket,
  650. LPUINT pcbPacketSize,
  651. UINT priority
  652. )
  653. {
  654. UINT rc;
  655. BOOL fPutNameAndCaps;
  656. UINT cbPacketSize;
  657. UINT personNameLength;
  658. PS20PACKETHEADER pS20Packet = NULL;
  659. LPBYTE pData;
  660. DebugEntry(S20MakeControlPacket);
  661. //
  662. // Assume success
  663. //
  664. rc = 0;
  665. //
  666. // Work out how big the packet needs to be. Start with the fixed
  667. // length then add in capabilities and our name (if they are required).
  668. //
  669. switch (what)
  670. {
  671. case S20_CREATE:
  672. cbPacketSize = sizeof(S20CREATEPACKET) - 1;
  673. fPutNameAndCaps = TRUE;
  674. break;
  675. case S20_JOIN:
  676. cbPacketSize = sizeof(S20JOINPACKET) - 1;
  677. fPutNameAndCaps = TRUE;
  678. break;
  679. case S20_RESPOND:
  680. cbPacketSize = sizeof(S20RESPONDPACKET) - 1;
  681. fPutNameAndCaps = TRUE;
  682. break;
  683. case S20_DELETE:
  684. cbPacketSize = sizeof(S20DELETEPACKET) - 1;
  685. fPutNameAndCaps = FALSE;
  686. break;
  687. case S20_LEAVE:
  688. cbPacketSize = sizeof(S20LEAVEPACKET);
  689. fPutNameAndCaps = FALSE;
  690. break;
  691. case S20_END:
  692. cbPacketSize = sizeof(S20ENDPACKET) - 1;
  693. fPutNameAndCaps = FALSE;
  694. break;
  695. case S20_COLLISION:
  696. cbPacketSize = sizeof(S20COLLISIONPACKET);
  697. fPutNameAndCaps = FALSE;
  698. break;
  699. default:
  700. ERROR_OUT(("BOGUS S20 packet %u", what));
  701. break;
  702. }
  703. if (fPutNameAndCaps)
  704. {
  705. ASSERT(g_asSession.gccID);
  706. ASSERT(g_asSession.cchLocalName);
  707. //
  708. // The name data is always dword aligned (including the NULL)
  709. //
  710. personNameLength = DC_ROUND_UP_4(g_asSession.cchLocalName+1);
  711. cbPacketSize += personNameLength + sizeof(g_cpcLocalCaps);
  712. }
  713. //
  714. // Now try to allocate a buffer for this.
  715. //
  716. rc = MG_GetBuffer( g_s20pmgClient,
  717. cbPacketSize,
  718. (NET_PRIORITY)priority,
  719. g_s20BroadcastID,
  720. (void **)&pS20Packet );
  721. if (rc != 0)
  722. {
  723. WARNING_OUT(("MG_GetBuffer failed; can't send S20 control packet"));
  724. DC_QUIT;
  725. }
  726. pS20Packet->packetType = (TSHR_UINT16)what | S20_ALL_VERSIONS;
  727. pS20Packet->user = g_s20LocalID;
  728. //
  729. // This will point to where we need to stuff the name and/or
  730. // capabilities.
  731. //
  732. pData = NULL;
  733. //
  734. // Now do the packet dependant fields.
  735. //
  736. switch (what)
  737. {
  738. case S20_CREATE:
  739. {
  740. ASSERT(fPutNameAndCaps);
  741. ((PS20CREATEPACKET)pS20Packet)->correlator = correlator;
  742. ((PS20CREATEPACKET)pS20Packet)->lenName = (TSHR_UINT16)personNameLength;
  743. ((PS20CREATEPACKET)pS20Packet)->lenCaps = (TSHR_UINT16)sizeof(g_cpcLocalCaps);
  744. pData = ((PS20CREATEPACKET)pS20Packet)->data;
  745. }
  746. break;
  747. case S20_JOIN:
  748. {
  749. ASSERT(fPutNameAndCaps);
  750. ((PS20JOINPACKET)pS20Packet)->lenName = (TSHR_UINT16)personNameLength;
  751. ((PS20JOINPACKET)pS20Packet)->lenCaps = (TSHR_UINT16)sizeof(g_cpcLocalCaps);
  752. pData = ((PS20JOINPACKET)pS20Packet)->data;
  753. }
  754. break;
  755. case S20_RESPOND:
  756. {
  757. ASSERT(fPutNameAndCaps);
  758. ((PS20RESPONDPACKET)pS20Packet)->correlator = correlator;
  759. ((PS20RESPONDPACKET)pS20Packet)->originator = (TSHR_UINT16)who;
  760. ((PS20RESPONDPACKET)pS20Packet)->lenName = (TSHR_UINT16)personNameLength;
  761. ((PS20RESPONDPACKET)pS20Packet)->lenCaps = (TSHR_UINT16)sizeof(g_cpcLocalCaps);
  762. pData = ((PS20RESPONDPACKET)pS20Packet)->data;
  763. }
  764. break;
  765. case S20_DELETE:
  766. {
  767. ASSERT(!fPutNameAndCaps);
  768. ((PS20DELETEPACKET)pS20Packet)->correlator = correlator;
  769. ((PS20DELETEPACKET)pS20Packet)->target = (TSHR_UINT16)who;
  770. ((PS20DELETEPACKET)pS20Packet)->lenName = 0;
  771. }
  772. break;
  773. case S20_LEAVE:
  774. {
  775. ASSERT(!fPutNameAndCaps);
  776. ((PS20LEAVEPACKET)pS20Packet)->correlator = correlator;
  777. }
  778. break;
  779. case S20_END:
  780. {
  781. ASSERT(!fPutNameAndCaps);
  782. ((PS20ENDPACKET)pS20Packet)->correlator = correlator;
  783. ((PS20ENDPACKET)pS20Packet)->lenName = 0;
  784. }
  785. break;
  786. case S20_COLLISION:
  787. {
  788. ASSERT(!fPutNameAndCaps);
  789. ((PS20COLLISIONPACKET)pS20Packet)->correlator = correlator;
  790. }
  791. break;
  792. default:
  793. {
  794. ERROR_OUT(("Invalid type %u", what));
  795. rc = NET_RC_S20_FAIL;
  796. DC_QUIT;
  797. }
  798. break;
  799. }
  800. //
  801. // Now we can copy in the name and capabilities.
  802. //
  803. if (fPutNameAndCaps)
  804. {
  805. lstrcpy((LPSTR)pData, g_asSession.achLocalName);
  806. // The local name is always null-terminated (truncated to fit in 48 bytes inc. null)
  807. pData += personNameLength;
  808. memcpy(pData, &g_cpcLocalCaps, sizeof(g_cpcLocalCaps));
  809. //
  810. // FILL IN GCC-ID HERE; the local caps are shared but the local
  811. // person entity in the share doesn't exist yet.
  812. //
  813. ((CPCALLCAPS *)pData)->share.gccID = g_asSession.gccID;
  814. }
  815. //
  816. // Return the packet and length.
  817. //
  818. *ppPacket = pS20Packet;
  819. *pcbPacketSize = cbPacketSize;
  820. DC_EXIT_POINT:
  821. DebugExitDWORD(S20MakeControlPacket, rc);
  822. return(rc);
  823. }
  824. //
  825. // FUNCTION: S20FlushSendOrQueueControlPacket
  826. //
  827. // DESCRIPTION:
  828. //
  829. // Attempts to flush any queued S20 control packets and then attempte to
  830. // send a S20 control packet. If this fails the queue the packet (the
  831. // actual packet is freed.
  832. //
  833. // PARAMETERS:
  834. //
  835. // what - which type of packet
  836. //
  837. // correlator - the correlator to place in the packet
  838. //
  839. // who - the target party (if what is a S20_DELETE) or the originator (if
  840. // what is S20_RESPOND)
  841. //
  842. // priority - priority to send packet at
  843. //
  844. // RETURNS: NONE
  845. //
  846. //
  847. UINT S20FlushSendOrQueueControlPacket(
  848. UINT what,
  849. UINT correlator,
  850. UINT who,
  851. UINT priority)
  852. {
  853. UINT rc;
  854. DebugEntry(S20FlushSendOrQueueControlPacket);
  855. rc = S20FlushAndSendControlPacket(what, correlator, who, priority);
  856. if (rc != 0)
  857. {
  858. // Let's queue this packet
  859. if (((g_s20ControlPacketQTail + 1) % S20_MAX_QUEUED_CONTROL_PACKETS) ==
  860. g_s20ControlPacketQHead)
  861. {
  862. //
  863. // There is no more space in the control packet queue. We will
  864. // discard everything from it and say the share ended because of
  865. // a network error (if we're in a share).
  866. //
  867. ERROR_OUT(("No more space in control packet queue"));
  868. }
  869. else
  870. {
  871. S20CONTROLPACKETQENTRY *p = &(g_s20ControlPacketQ[g_s20ControlPacketQTail]);
  872. p->who = who;
  873. p->correlator = correlator;
  874. p->what = what;
  875. p->priority = priority;
  876. g_s20ControlPacketQTail = (g_s20ControlPacketQTail + 1) %
  877. S20_MAX_QUEUED_CONTROL_PACKETS;
  878. rc = 0;
  879. }
  880. }
  881. DebugExitDWORD(S20FlushSendOrQueueControlPacket, rc);
  882. return rc;
  883. }
  884. //
  885. // FUNCTION: S20FlushAndSendControlPacket
  886. //
  887. // DESCRIPTION:
  888. //
  889. // Attempts to flush any queued S20 control packets and then send a S20
  890. // control packet. If sending fails then free the packet.
  891. //
  892. // PARAMETERS:
  893. //
  894. // what - which type of packet
  895. //
  896. // correlator - the correlator to place in the packet
  897. //
  898. // who - the target party (if what is a S20_DELETE) or the originator (if
  899. // what is S20_RESPOND)
  900. //
  901. // priority - priority to send packet at
  902. //
  903. // RETURNS:
  904. //
  905. //
  906. UINT S20FlushAndSendControlPacket
  907. (
  908. UINT what,
  909. UINT correlator,
  910. UINT who,
  911. UINT priority
  912. )
  913. {
  914. UINT rc;
  915. PS20PACKETHEADER pS20Packet;
  916. UINT length;
  917. DebugEntry(S20FlushAndSendControlPacket);
  918. //
  919. // First try to flush.
  920. //
  921. rc = S20SendQueuedControlPackets();
  922. if (rc != 0)
  923. {
  924. WARNING_OUT(("S20SendQueuedControlPackets %u", rc));
  925. DC_QUIT;
  926. }
  927. rc = S20MakeControlPacket(what, correlator, who, &pS20Packet, &length, priority);
  928. if (rc != 0)
  929. {
  930. WARNING_OUT(("S20MakeControlPacket %u", rc));
  931. DC_QUIT;
  932. }
  933. TRACE_OUT(("CP %u %lu %u sent", what, correlator, who));
  934. rc = S20SendControlPacket(pS20Packet, length, priority);
  935. if (rc != 0)
  936. {
  937. WARNING_OUT(("S20SendControlPacket %u", rc));
  938. DC_QUIT;
  939. }
  940. DC_EXIT_POINT:
  941. DebugExitDWORD(S20FlushAndSendControlPacket, rc);
  942. return(rc);
  943. }
  944. //
  945. // FUNCTION: S20SendControlPacket
  946. //
  947. // DESCRIPTION:
  948. //
  949. // Attempts to send a S20 control packet. If sending fails then free the
  950. // packet.
  951. //
  952. // PARAMETERS:
  953. //
  954. // pPacket - pointer to the control packet to send. These are always
  955. // broadcast.
  956. //
  957. // length - length of aforementioned packet.
  958. //
  959. // priority - priority to send packet at
  960. //
  961. // RETURNS:
  962. //
  963. //
  964. UINT S20SendControlPacket
  965. (
  966. PS20PACKETHEADER pS20Packet,
  967. UINT length,
  968. UINT priority
  969. )
  970. {
  971. UINT rc;
  972. DebugEntry(S20SendControlPacket);
  973. TRACE_OUT(("S20SendControlPacket: sending packet type %x, size %d",
  974. pS20Packet->packetType, length));
  975. rc = MG_SendData( g_s20pmgClient,
  976. (NET_PRIORITY)priority,
  977. g_s20BroadcastID,
  978. length,
  979. (void **)&pS20Packet );
  980. if (rc != 0)
  981. {
  982. ERROR_OUT(("MG_SendData FAILED !!! %lx", rc));
  983. }
  984. if (pS20Packet != NULL)
  985. {
  986. //
  987. // The packet was not freed by the NL - we will do it instead.
  988. //
  989. MG_FreeBuffer(g_s20pmgClient, (void **)&pS20Packet);
  990. }
  991. DebugExitDWORD(S20SendControlPacket, rc);
  992. return(rc);
  993. }
  994. //
  995. // FUNCTION: S20SendQueuedControlPackets
  996. //
  997. // DESCRIPTION:
  998. //
  999. // Sends as many queued packets as possible
  1000. //
  1001. // PARAMETERS:
  1002. //
  1003. //
  1004. // RETURNS:
  1005. //
  1006. // 0 - all queued packets have been sent.
  1007. //
  1008. //
  1009. UINT S20SendQueuedControlPackets(void)
  1010. {
  1011. PS20PACKETHEADER pS20Packet;
  1012. UINT length;
  1013. UINT rc;
  1014. UINT priority;
  1015. DebugEntry(S20SendQueuedControlPackets);
  1016. //
  1017. // Assume success until something fails.
  1018. //
  1019. rc = 0;
  1020. //
  1021. // While there are packets to send - try to send them
  1022. //
  1023. while (g_s20ControlPacketQTail != g_s20ControlPacketQHead)
  1024. {
  1025. S20CONTROLPACKETQENTRY *p = &(g_s20ControlPacketQ[g_s20ControlPacketQHead]);
  1026. priority = p->priority;
  1027. rc = S20MakeControlPacket(p->what, p->correlator, p->who,
  1028. &pS20Packet, &length, priority);
  1029. if (rc != 0)
  1030. {
  1031. //
  1032. // Failed to make the packet - give up.
  1033. //
  1034. WARNING_OUT(("S20MakeControlPacket failed error %u", rc));
  1035. break;
  1036. }
  1037. rc = S20SendControlPacket(pS20Packet, length, priority);
  1038. if (rc != 0)
  1039. {
  1040. ERROR_OUT(("MG_SendData FAILED !!! %lx", rc));
  1041. //
  1042. // Failed to send the packet - give up.
  1043. //
  1044. break;
  1045. }
  1046. //
  1047. // Succesfully sent the queue packet - move the head of the queue
  1048. // along one.
  1049. //
  1050. g_s20ControlPacketQHead = (g_s20ControlPacketQHead + 1) %
  1051. S20_MAX_QUEUED_CONTROL_PACKETS;
  1052. }
  1053. DebugExitDWORD(S20SendQueuedControlPackets, rc);
  1054. return(rc);
  1055. }
  1056. //
  1057. // S20AttachConfirm()
  1058. //
  1059. // Handles the MCS attach confirmation
  1060. //
  1061. void S20AttachConfirm
  1062. (
  1063. NET_UID userId,
  1064. NET_RESULT result,
  1065. UINT callID
  1066. )
  1067. {
  1068. NET_CHANNEL_ID correlator;
  1069. UINT rc;
  1070. DebugEntry(S20AttachConfirm);
  1071. if (g_s20State == S20_ATTACH_PEND)
  1072. {
  1073. //
  1074. // Assume we need to clear up.
  1075. //
  1076. rc = NET_RC_S20_FAIL;
  1077. if (result == NET_RESULT_OK)
  1078. {
  1079. //
  1080. // We're in. Now try to join our channel and remember our
  1081. // userID.
  1082. //
  1083. g_s20LocalID = userId;
  1084. //
  1085. // We must join our single member channel for flow control
  1086. //
  1087. rc = MG_ChannelJoin(g_s20pmgClient,
  1088. &correlator,
  1089. g_s20LocalID);
  1090. if (rc == 0)
  1091. {
  1092. //
  1093. // Now join the broadcast channel
  1094. //
  1095. rc = MG_ChannelJoinByKey(g_s20pmgClient,
  1096. &correlator,
  1097. GCC_AS_CHANNEL_KEY);
  1098. if (rc != 0)
  1099. {
  1100. MG_ChannelLeave(g_s20pmgClient, g_s20LocalID);
  1101. }
  1102. }
  1103. if (rc == 0)
  1104. {
  1105. //
  1106. // It worked - make the state change.
  1107. //
  1108. SetS20State(S20_JOIN_PEND);
  1109. }
  1110. else
  1111. {
  1112. //
  1113. // Everything else is some sort of logic error (we will
  1114. // follow our recovery path).
  1115. //
  1116. ERROR_OUT(("ChannelJoin unexpected error %u", rc));
  1117. }
  1118. }
  1119. if (rc != 0)
  1120. {
  1121. //
  1122. // Something didn't work work out - clear up with a
  1123. // SHARE_ENDED if a create or join was pending.
  1124. //
  1125. if (result == NET_RESULT_OK)
  1126. {
  1127. //
  1128. // The attach succeeded so detach because the join
  1129. // failed and we want to go back to initialised state.
  1130. //
  1131. MG_Detach(g_s20pmgClient);
  1132. g_s20LocalID = 0;
  1133. }
  1134. //
  1135. // Now make the state change and generate event if
  1136. // necessary.
  1137. //
  1138. SetS20State(S20_INIT);
  1139. if (g_s20Pend)
  1140. {
  1141. g_s20Pend = 0;
  1142. SC_End();
  1143. }
  1144. }
  1145. }
  1146. DebugExitVOID(S20AttachConfirm);
  1147. }
  1148. //
  1149. // S20DetachIndication()
  1150. //
  1151. // Handles NET_EVENT_DETACH notification for a user
  1152. //
  1153. void S20DetachIndication
  1154. (
  1155. NET_UID userId,
  1156. UINT callID
  1157. )
  1158. {
  1159. DebugEntry(S20DetachIndication);
  1160. //
  1161. // There are three possibilities here
  1162. //
  1163. // 1. We have been forced out.
  1164. // 2. All remote users have detached.
  1165. // 3. A remote user has detached.
  1166. //
  1167. // 2 is effectively a 3 for each current remote user. We report 1 as a
  1168. // network error.
  1169. //
  1170. if (userId == g_s20LocalID)
  1171. {
  1172. //
  1173. // We have been forced out.
  1174. //
  1175. switch (g_s20State)
  1176. {
  1177. case S20_IN_SHARE:
  1178. case S20_SHARE_PEND:
  1179. case S20_SHARE_STARTING:
  1180. //
  1181. // Generate a share ended event.
  1182. //
  1183. SC_End();
  1184. // FALL THROUGH
  1185. case S20_NO_SHARE:
  1186. //
  1187. // Just revert to init state.
  1188. //
  1189. SetS20State(S20_INIT);
  1190. break;
  1191. case S20_JOIN_PEND:
  1192. case S20_ATTACH_PEND:
  1193. //
  1194. // Check the join or create pending flags here and if
  1195. // either one is set then generate a share ended
  1196. //
  1197. if (g_s20Pend)
  1198. {
  1199. g_s20Pend = 0;
  1200. SC_End();
  1201. }
  1202. SetS20State(S20_INIT);
  1203. break;
  1204. case S20_TERM:
  1205. case S20_INIT:
  1206. //
  1207. // Unusual but not impossible.
  1208. //
  1209. TRACE_OUT(("Ignored in state %u", g_s20State));
  1210. break;
  1211. default:
  1212. ERROR_OUT(("Invalid state %u", g_s20State));
  1213. break;
  1214. }
  1215. WARNING_OUT(("S20DetachIndication <MAKING LOCALID = 0"));
  1216. g_s20LocalID = 0;
  1217. }
  1218. else
  1219. {
  1220. ASSERT(userId != NET_ALL_REMOTES);
  1221. //
  1222. // A single remote user has left.
  1223. //
  1224. switch (g_s20State)
  1225. {
  1226. case S20_IN_SHARE:
  1227. {
  1228. //
  1229. // If we are in a share then issue a PARTY_DELETED event
  1230. // for the appropriate party if they have been added.
  1231. // S20MaybeIssuePersonDelete will only issue deletes for
  1232. // parties which have been added succesfully.
  1233. //
  1234. S20MaybeIssuePersonDelete(userId);
  1235. }
  1236. break;
  1237. default:
  1238. {
  1239. //
  1240. // In any other state this makes no difference to us.
  1241. //
  1242. TRACE_OUT(("ignored in state %u", g_s20State));
  1243. }
  1244. break;
  1245. }
  1246. }
  1247. DebugExitVOID(S20DetachIndication);
  1248. }
  1249. //
  1250. // FUNCTION: S20JoinConfirm
  1251. //
  1252. // DESCRIPTION:
  1253. //
  1254. // Handles the NET_EVENT_CHANNEL_JOIN message from the NL
  1255. //
  1256. // PARAMETERS:
  1257. //
  1258. // pNetEventHeader - pointer to the event
  1259. //
  1260. // RETURNS: NONE
  1261. //
  1262. //
  1263. void S20JoinConfirm(PNET_JOIN_CNF_EVENT pJoinConfirm)
  1264. {
  1265. UINT rc;
  1266. DebugEntry(S20JoinConfirm);
  1267. if (g_s20State == S20_JOIN_PEND)
  1268. {
  1269. //
  1270. // Handle the join completing
  1271. //
  1272. if (pJoinConfirm->result == NET_RESULT_OK)
  1273. {
  1274. //
  1275. // We have sucessfully joined, either our single user
  1276. // channel or our broadcast channel
  1277. // We detect that both are successful when the g_s20BroadcastID
  1278. // field is filled in and g_s20JoinedLocal is TRUE
  1279. //
  1280. if (pJoinConfirm->channel == g_s20LocalID)
  1281. {
  1282. g_s20JoinedLocal = TRUE;
  1283. TRACE_OUT(("Joined user channel"));
  1284. }
  1285. else
  1286. {
  1287. //
  1288. // Store the assigned channel.
  1289. //
  1290. g_s20BroadcastID = pJoinConfirm->channel;
  1291. TRACE_OUT(("Joined channel %u", (UINT)g_s20BroadcastID));
  1292. }
  1293. //
  1294. // If we have joined both channels then let it rip
  1295. //
  1296. if (g_s20JoinedLocal && g_s20BroadcastID)
  1297. {
  1298. SetS20State(S20_NO_SHARE);
  1299. if (g_asSession.hwndHostUI &&
  1300. (g_asSession.attendeePermissions & NM_PERMIT_SHARE))
  1301. {
  1302. SendMessage(g_asSession.hwndHostUI, HOST_MSG_CALL, TRUE, 0);
  1303. }
  1304. DCS_NotifyUI(SH_EVT_APPSHARE_READY, TRUE, 0);
  1305. //
  1306. // Issue create or join if they are pending.
  1307. //
  1308. if (g_s20Pend != 0)
  1309. {
  1310. ASSERT(g_s20Pend == S20_JOIN);
  1311. UINT sPend;
  1312. sPend = g_s20Pend;
  1313. g_s20Pend = 0;
  1314. S20CreateOrJoinShare(sPend, pJoinConfirm->callID);
  1315. }
  1316. }
  1317. }
  1318. else
  1319. {
  1320. ERROR_OUT(("Channel join failed"));
  1321. //
  1322. // Clear up by reverting to initialised state.
  1323. //
  1324. MG_Detach(g_s20pmgClient);
  1325. g_s20LocalID = 0;
  1326. g_s20BroadcastID = 0;
  1327. g_s20JoinedLocal = FALSE;
  1328. //
  1329. // Now make the state change and generate event if
  1330. // necessary.
  1331. //
  1332. SetS20State(S20_INIT);
  1333. if (g_s20Pend)
  1334. {
  1335. g_s20Pend = 0;
  1336. SC_End();
  1337. }
  1338. }
  1339. }
  1340. DebugExitVOID(S20JoinConfirm);
  1341. }
  1342. //
  1343. // FUNCTION: S20LeaveIndication
  1344. //
  1345. // DESCRIPTION:
  1346. //
  1347. // Handles the NET_EV_LEAVE_INDICATION message from the NL
  1348. //
  1349. // PARAMETERS:
  1350. //
  1351. // pNetEventHeader - pointer to the event
  1352. //
  1353. // RETURNS: NONE
  1354. //
  1355. //
  1356. void S20LeaveIndication
  1357. (
  1358. NET_CHANNEL_ID channelID,
  1359. UINT callID
  1360. )
  1361. {
  1362. UINT rc;
  1363. DebugEntry(S20LeaveIndication);
  1364. //
  1365. // A leave indication means we were forced out of a channel. As we
  1366. // only use one channel this is bound to be terminal and we will
  1367. // generate appropriate share ending type events and detach (this will
  1368. // hopefully tell the remote systems we have gone - also we have no
  1369. // state which is attached but not trying to join so the alternatives
  1370. // would be to 1) add a new state or 2) try and re-join a channel
  1371. // immediately we get chucked out. Neither appeals.
  1372. //
  1373. switch (g_s20State)
  1374. {
  1375. case S20_IN_SHARE:
  1376. case S20_SHARE_PEND:
  1377. case S20_SHARE_STARTING:
  1378. //
  1379. // Generate a share ended event.
  1380. //
  1381. SC_End();
  1382. // FALL THROUGH
  1383. case S20_NO_SHARE:
  1384. case S20_JOIN_PEND:
  1385. case S20_ATTACH_PEND:
  1386. //
  1387. // Detach from the domain.
  1388. //
  1389. MG_Detach(g_s20pmgClient);
  1390. g_s20LocalID = 0;
  1391. //
  1392. // Check the join or create pending flags here and if either
  1393. // one is set then generate a share ended
  1394. //
  1395. if (g_s20Pend)
  1396. {
  1397. g_s20Pend = 0;
  1398. SC_End();
  1399. }
  1400. SetS20State(S20_INIT);
  1401. break;
  1402. case S20_TERM:
  1403. case S20_INIT:
  1404. //
  1405. // Unusual but not impossible.
  1406. //
  1407. TRACE_OUT(("Ignored in state %u", g_s20State));
  1408. break;
  1409. default:
  1410. ERROR_OUT(("Invalid state %u", g_s20State));
  1411. break;
  1412. }
  1413. DebugExitVOID(S20LeaveIndication);
  1414. }
  1415. //
  1416. // S20SendIndication()
  1417. //
  1418. // Handles received data notification
  1419. //
  1420. void S20SendIndication(PNET_SEND_IND_EVENT pSendIndication)
  1421. {
  1422. PS20PACKETHEADER pS20Packet;
  1423. DebugEntry(S20SendIndication);
  1424. pS20Packet = (PS20PACKETHEADER)(pSendIndication->data_ptr);
  1425. //
  1426. // If App Sharing detaches from the T.120 conference, it will free up
  1427. // all data indication buffers. We need to check for this condition.
  1428. //
  1429. if (NULL != pS20Packet)
  1430. {
  1431. if (!(pS20Packet->packetType & S20_ALL_VERSIONS))
  1432. {
  1433. ERROR_OUT(("User is trying to connect from %#hx system",
  1434. pS20Packet->packetType & 0xF0));
  1435. //
  1436. // This should never happen, but if it does then we assert in the
  1437. // debug build and quietly fail in the retail build.
  1438. //
  1439. ERROR_OUT(("An unsupported version of app sharing joined the conference"));
  1440. DC_QUIT;
  1441. }
  1442. //
  1443. // Mask out the protocol version
  1444. //
  1445. switch (pS20Packet->packetType & S20_PACKET_TYPE_MASK)
  1446. {
  1447. case S20_CREATE:
  1448. S20CreateMsg((PS20CREATEPACKET)pS20Packet);
  1449. break;
  1450. case S20_JOIN:
  1451. S20JoinMsg((PS20JOINPACKET)pS20Packet);
  1452. break;
  1453. case S20_RESPOND:
  1454. S20RespondMsg((PS20RESPONDPACKET)pS20Packet);
  1455. break;
  1456. case S20_DELETE:
  1457. S20DeleteMsg((PS20DELETEPACKET)pS20Packet);
  1458. break;
  1459. case S20_LEAVE:
  1460. S20LeaveMsg((PS20LEAVEPACKET)pS20Packet);
  1461. break;
  1462. case S20_END:
  1463. S20EndMsg((PS20ENDPACKET)pS20Packet);
  1464. break;
  1465. case S20_COLLISION:
  1466. S20CollisionMsg((PS20COLLISIONPACKET)pS20Packet);
  1467. break;
  1468. case S20_DATA:
  1469. S20DataMsg((PS20DATAPACKET)pS20Packet);
  1470. break;
  1471. default:
  1472. ERROR_OUT(("invalid packet %hu", pS20Packet->packetType));
  1473. break;
  1474. }
  1475. }
  1476. DC_EXIT_POINT:
  1477. MG_FreeBuffer(g_s20pmgClient, (void **)&pSendIndication);
  1478. DebugExitVOID(S20SendIndication);
  1479. }
  1480. //
  1481. // FUNCTION: S20Flow
  1482. //
  1483. // DESCRIPTION:
  1484. //
  1485. // Handles the NET_FLOW event
  1486. //
  1487. // PARAMETERS:
  1488. //
  1489. // data1, data2 - the data from the UT event handler
  1490. //
  1491. // RETURNS: NONE
  1492. //
  1493. //
  1494. void S20Flow
  1495. (
  1496. UINT priority,
  1497. UINT newBufferSize
  1498. )
  1499. {
  1500. DebugEntry(S20Flow);
  1501. //
  1502. // We know this is our data channel (it is the only one we flow
  1503. // control) but if this is not the UPDATE stream, then ignore it.
  1504. // UPDATEs are low priority.
  1505. //
  1506. ASSERT(priority == NET_LOW_PRIORITY);
  1507. if (g_asSession.pShare != NULL)
  1508. {
  1509. TRACE_OUT(("Received flow control notification, new size %lu",
  1510. newBufferSize));
  1511. if (g_asSession.pShare->m_pHost != NULL)
  1512. {
  1513. //
  1514. // First try and improve the LAN performance by sending orders in
  1515. // large buffers, if we find that the throughput can handle it.
  1516. //
  1517. g_asSession.pShare->m_pHost->UP_FlowControl(newBufferSize);
  1518. //
  1519. // Adjust the depth which we try to spoil orders to based on
  1520. // feedback.
  1521. //
  1522. g_asSession.pShare->m_pHost->OA_FlowControl(newBufferSize);
  1523. }
  1524. //
  1525. // Tell DCS so that we can skip GDC compression.
  1526. // This improves responsiveness over high bandwidth links because it
  1527. // reduces the CPU loading on the sender
  1528. //
  1529. g_asSession.pShare->DCS_FlowControl(newBufferSize);
  1530. }
  1531. DebugExitVOID(S20Flow);
  1532. }
  1533. //
  1534. // FUNCTION: S20CreateMsg
  1535. //
  1536. // DESCRIPTION:
  1537. //
  1538. // Handles an incoming create message.
  1539. //
  1540. // PARAMETERS:
  1541. //
  1542. // pS20Packet - pointer to the create message itself
  1543. //
  1544. // RETURNS: NONE
  1545. //
  1546. void S20CreateMsg
  1547. (
  1548. PS20CREATEPACKET pS20Packet
  1549. )
  1550. {
  1551. BOOL rc;
  1552. DebugEntry(S20CreateMsg);
  1553. WARNING_OUT(("S20_CREATE from [%d - %s], correlator %x",
  1554. pS20Packet->header.user, (LPSTR)pS20Packet->data,
  1555. pS20Packet->correlator));
  1556. //
  1557. // First of all check if the correlator on this CREATE is the same as
  1558. // our current view of the correlator. This may happen if a sweep
  1559. // RESPOND overtakes a CREATE - in this case we will create the share
  1560. // on the RESPOND and this is simply the delayed CREATE arriving now so
  1561. // we don't need to do anything here.
  1562. //
  1563. if (g_s20ShareCorrelator == pS20Packet->correlator)
  1564. {
  1565. WARNING_OUT(("Received S20_CREATE from [%d] with bogus correlator %x",
  1566. pS20Packet->header.user, pS20Packet->correlator));
  1567. DC_QUIT;
  1568. }
  1569. if ((g_s20State == S20_NO_SHARE) ||
  1570. ((g_s20State == S20_SHARE_PEND) &&
  1571. (g_s20ShareCorrelator == 0)))
  1572. {
  1573. rc = S20AcceptNewCorrelator(pS20Packet);
  1574. }
  1575. else if ((g_s20State == S20_SHARE_PEND) ||
  1576. (g_s20State == S20_SHARE_STARTING) ||
  1577. (g_s20State == S20_IN_SHARE))
  1578. {
  1579. //
  1580. // Only current share creator should tell other dude there's an
  1581. // error.
  1582. //
  1583. if (S20_GET_CREATOR(g_s20ShareCorrelator) == g_s20LocalID)
  1584. {
  1585. //
  1586. // If we know about a share already then ignore this one.
  1587. //
  1588. WARNING_OUT(("Received S20_CREATE from [%d] with correlator %x, share colllision",
  1589. pS20Packet->header.user, pS20Packet->correlator));
  1590. S20FlushSendOrQueueControlPacket(S20_END,
  1591. pS20Packet->correlator, 0, NET_TOP_PRIORITY);
  1592. S20FlushSendOrQueueControlPacket(S20_COLLISION,
  1593. pS20Packet->correlator, 0, NET_TOP_PRIORITY);
  1594. }
  1595. }
  1596. else
  1597. {
  1598. SC_End();
  1599. SetS20State(S20_NO_SHARE);
  1600. rc = S20AcceptNewCorrelator(pS20Packet);
  1601. }
  1602. DC_EXIT_POINT:
  1603. DebugExitVOID(S20CreateMsg);
  1604. }
  1605. //
  1606. // FUNCTION: S20JoinMsg
  1607. //
  1608. // DESCRIPTION:
  1609. //
  1610. // Handles an incoming join message.
  1611. //
  1612. // PARAMETERS:
  1613. //
  1614. // pS20Packet - pointer to the join message itself
  1615. //
  1616. // RETURNS: NONE
  1617. //
  1618. void S20JoinMsg
  1619. (
  1620. PS20JOINPACKET pS20Packet
  1621. )
  1622. {
  1623. DebugEntry(S20JoinMsg);
  1624. WARNING_OUT(("S20_JOIN from [%d - %s]",
  1625. pS20Packet->header.user, (LPSTR)pS20Packet->data));
  1626. switch (g_s20State)
  1627. {
  1628. case S20_SHARE_PEND:
  1629. //
  1630. // If we receive a join when a share is pending which we are
  1631. // creating then we will try to add the party. If it succeeds
  1632. // then we will respond to the join as we would if we were in a
  1633. // share (and we will indeed then be in a share). If it fails
  1634. // we will delete the joiner.
  1635. //
  1636. // If we receive a join when a share is pending because we are
  1637. // trying to join (ie simultaneous joiners) then we can just
  1638. // ignore it because a party which is joining a share will send
  1639. // a respond as soon as they know the correlator for the share
  1640. // they have succesfully joined. This respond will be ignored
  1641. // by any parties which saw and added the new party but it will
  1642. // be seen by any simultaneous joiners and they will then get a
  1643. // chance to try and add the other joiner. If this fails they
  1644. // will then do the normal processing for a failure handling a
  1645. // respond message when we joined a share (ie delete
  1646. // themselves).
  1647. //
  1648. // This will potentially mean that simultaneous joiners will
  1649. // cause each other to delete themselves when there was room
  1650. // for one of them in the share - we accept this.
  1651. //
  1652. //
  1653. // Why is the share pending? If the correlator is non-zero
  1654. // then we are creating a share.
  1655. //
  1656. if (g_s20ShareCorrelator != 0)
  1657. {
  1658. //
  1659. // We are creating a share - treat this like a respond.
  1660. //
  1661. WARNING_OUT(("S20JoinMsg SC_Start"));
  1662. if (!SC_Start(g_s20LocalID))
  1663. {
  1664. WARNING_OUT(("S20Join: couldn't create share, clean up"));
  1665. SC_End();
  1666. }
  1667. else
  1668. {
  1669. SetS20State(S20_SHARE_STARTING);
  1670. S20MaybeAddNewParty(pS20Packet->header.user,
  1671. pS20Packet->lenCaps, pS20Packet->lenName,
  1672. pS20Packet->data);
  1673. }
  1674. }
  1675. else
  1676. {
  1677. //
  1678. // We are joining a share - simultaneous joiners.
  1679. //
  1680. WARNING_OUT(("Simultaneous joiner - ignored for now, expect a respond"));
  1681. }
  1682. break;
  1683. case S20_IN_SHARE:
  1684. case S20_SHARE_STARTING:
  1685. {
  1686. //
  1687. // When we are in a share we will try and add this person then
  1688. // give them a respond or a delete depending on what we did.
  1689. //
  1690. S20MaybeAddNewParty(pS20Packet->header.user,
  1691. pS20Packet->lenCaps, pS20Packet->lenName,
  1692. pS20Packet->data);
  1693. break;
  1694. }
  1695. default:
  1696. break;
  1697. }
  1698. DebugExitVOID(S20JoinMsg);
  1699. }
  1700. //
  1701. // FUNCTION: S20RespondMsg
  1702. //
  1703. // DESCRIPTION:
  1704. //
  1705. // Handles an incoming respond message.
  1706. //
  1707. // PARAMETERS:
  1708. //
  1709. // pS20Packet - pointer to the respond message itself
  1710. //
  1711. // RETURNS: NONE
  1712. //
  1713. void S20RespondMsg
  1714. (
  1715. PS20RESPONDPACKET pS20Packet
  1716. )
  1717. {
  1718. BOOL rc;
  1719. DebugEntry(S20RespondMsg);
  1720. TRACE_OUT(("S20_RESPOND from [%d - %s], for [%d], correlator %x",
  1721. pS20Packet->header.user, pS20Packet->data, pS20Packet->originator,
  1722. pS20Packet->correlator));
  1723. //
  1724. // First filter the incoming respond messages as follows.
  1725. //
  1726. // If we know what share we are in and this does not have the same
  1727. // correlator then respond with a delete and don't process any further.
  1728. //
  1729. // If the respond is not a response for us (ie we are not the
  1730. // originator and it is not a sweep-up response (the originator equals
  1731. // zero) then ignore it.
  1732. //
  1733. if ((g_s20ShareCorrelator != 0) &&
  1734. (pS20Packet->correlator != g_s20ShareCorrelator))
  1735. {
  1736. //
  1737. // Make sure sender knows we're not in this share.
  1738. //
  1739. WARNING_OUT(("S20_RESPOND from [%d] with unknown correlator %x",
  1740. pS20Packet->header.user, pS20Packet->correlator));
  1741. S20FlushSendOrQueueControlPacket(S20_LEAVE,
  1742. pS20Packet->correlator, 0, NET_TOP_PRIORITY);
  1743. DC_QUIT;
  1744. }
  1745. //
  1746. // Now handle incoming message according to state.
  1747. //
  1748. switch (g_s20State)
  1749. {
  1750. case S20_SHARE_PEND:
  1751. if ((pS20Packet->originator == g_s20LocalID) ||
  1752. (pS20Packet->originator == 0))
  1753. {
  1754. //
  1755. // A respond in share pending and it is for us. First,
  1756. // start a share.
  1757. //
  1758. WARNING_OUT(("S20RespondMsg SC_Start"));
  1759. rc = SC_Start(g_s20LocalID);
  1760. if (!rc)
  1761. {
  1762. SC_End();
  1763. }
  1764. else
  1765. {
  1766. SetS20State(S20_SHARE_STARTING);
  1767. //
  1768. // Why is the share pending? If the correlator is non-zero
  1769. // then we are creating a share.
  1770. //
  1771. if (g_s20ShareCorrelator == 0)
  1772. {
  1773. //
  1774. // We are joining a share so do nothing if we fail (we
  1775. // will move back to NO_SHARE state if this happens).
  1776. //
  1777. WARNING_OUT(("g_s20ShareCorrelator %x = pS20Packet->correlator %x", g_s20ShareCorrelator , pS20Packet->correlator));
  1778. g_s20ShareCorrelator = pS20Packet->correlator;
  1779. }
  1780. //
  1781. // Now try and add this new party.
  1782. //
  1783. rc = S20MaybeAddNewParty(pS20Packet->header.user,
  1784. pS20Packet->lenCaps, pS20Packet->lenName,
  1785. pS20Packet->data);
  1786. if (!rc)
  1787. {
  1788. //
  1789. // The responding party has been rejected by us. What
  1790. // happens next depends on whether we are creating the
  1791. // share or not.
  1792. //
  1793. if (S20_GET_CREATOR(g_s20ShareCorrelator) != g_s20LocalID)
  1794. {
  1795. //
  1796. // We are not creating (ie we are joining) and we
  1797. // have failed to add a party so end the share
  1798. // (indicating that we are rejecting the remote
  1799. // party).
  1800. //
  1801. WARNING_OUT(("S20Respond we are going to end"));
  1802. SC_End();
  1803. }
  1804. //
  1805. // If we were creating the share then there is nothing
  1806. // to do - just stay in SHARE_STARTING waiting for the
  1807. // next response.
  1808. //
  1809. }
  1810. }
  1811. }
  1812. break;
  1813. case S20_IN_SHARE:
  1814. case S20_SHARE_STARTING:
  1815. //
  1816. // Who created this share. If it was us then we want to
  1817. // delete people we reject, otherwise we want to leave if we
  1818. // reject people.
  1819. //
  1820. //
  1821. // Now try and add this new party. Of course it is entirely
  1822. // possible that we've already added them at this stage - but
  1823. // S20MaybeAddNewParty will just pretend to add them and return
  1824. // if that's the case.
  1825. //
  1826. rc = S20MaybeAddNewParty(pS20Packet->header.user,
  1827. pS20Packet->lenCaps, pS20Packet->lenName,
  1828. pS20Packet->data);
  1829. if (!rc)
  1830. {
  1831. WARNING_OUT(("Couldn't add [%d] to our share party list",
  1832. pS20Packet->header.user));
  1833. }
  1834. break;
  1835. default:
  1836. break;
  1837. }
  1838. DC_EXIT_POINT:
  1839. DebugExitVOID(S20RespondMsg);
  1840. }
  1841. //
  1842. // FUNCTION: S20DeleteMsg
  1843. //
  1844. // DESCRIPTION:
  1845. //
  1846. // Handles an incoming delete message.
  1847. //
  1848. // PARAMETERS:
  1849. //
  1850. // pS20Packet - pointer to the delete message itself
  1851. //
  1852. // RETURNS: NONE
  1853. //
  1854. void S20DeleteMsg
  1855. (
  1856. PS20DELETEPACKET pS20Packet
  1857. )
  1858. {
  1859. DebugEntry(S20DeleteMsg);
  1860. TRACE_OUT(("S20_DELETE from [%d], for [%d], correlator %x",
  1861. pS20Packet->header.user, pS20Packet->target, pS20Packet->correlator));
  1862. //
  1863. // ONLY SHARE CREATOR can delete people from share
  1864. //
  1865. if (!g_s20ShareCorrelator)
  1866. {
  1867. WARNING_OUT(("S20_DELETE, ignoring we're not in a share"));
  1868. DC_QUIT;
  1869. }
  1870. if (pS20Packet->target != g_s20LocalID)
  1871. {
  1872. //
  1873. // Not for us, ignore.
  1874. //
  1875. DC_QUIT;
  1876. }
  1877. if (g_s20ShareCorrelator != pS20Packet->correlator)
  1878. {
  1879. WARNING_OUT(("Received S20_DELETE from [%d] with unknown correlator %x",
  1880. pS20Packet->header.user, pS20Packet->correlator));
  1881. S20FlushSendOrQueueControlPacket(S20_LEAVE, pS20Packet->correlator,
  1882. 0, NET_TOP_PRIORITY);
  1883. DC_QUIT;
  1884. }
  1885. if (S20_GET_CREATOR(g_s20ShareCorrelator) != pS20Packet->header.user)
  1886. {
  1887. WARNING_OUT(("Received S20_DELETE from [%d] who did not create share, ignore",
  1888. pS20Packet->header.user));
  1889. DC_QUIT;
  1890. }
  1891. //
  1892. // Now handle incoming messages according to state.
  1893. //
  1894. switch (g_s20State)
  1895. {
  1896. case S20_SHARE_PEND:
  1897. case S20_SHARE_STARTING:
  1898. //
  1899. // Just tell everyone else we're leaving and then issue a
  1900. // SHARE_ENDED event.
  1901. //
  1902. TRACE_OUT(("CP LEAVE %lu %d", g_s20ShareCorrelator, 0));
  1903. S20FlushSendOrQueueControlPacket(S20_LEAVE,
  1904. g_s20ShareCorrelator,
  1905. 0,
  1906. NET_TOP_PRIORITY);
  1907. // FALL THROUGH
  1908. case S20_IN_SHARE:
  1909. SC_End();
  1910. SetS20State(S20_NO_SHARE);
  1911. break;
  1912. default:
  1913. break;
  1914. }
  1915. DC_EXIT_POINT:
  1916. DebugExitVOID(S20DeleteMsg);
  1917. }
  1918. //
  1919. // FUNCTION: S20LeaveMsg
  1920. //
  1921. // DESCRIPTION:
  1922. //
  1923. // Handles an incoming leave message.
  1924. //
  1925. // PARAMETERS:
  1926. //
  1927. // pS20Packet - pointer to the leave message itself
  1928. //
  1929. // RETURNS: NONE
  1930. //
  1931. void S20LeaveMsg(PS20LEAVEPACKET pS20Packet)
  1932. {
  1933. DebugEntry(S20LeaveMsg);
  1934. TRACE_OUT(("S20_LEAVE from [%d], correlator %x",
  1935. pS20Packet->header.user, pS20Packet->correlator));
  1936. if (!g_s20ShareCorrelator)
  1937. {
  1938. WARNING_OUT(("S20_LEAVE, ignoring we're not in a share"));
  1939. DC_QUIT;
  1940. }
  1941. if (g_s20ShareCorrelator != pS20Packet->correlator)
  1942. {
  1943. WARNING_OUT(("S20LeaveMsg Received S20_LEAVE from [%d] for unknown correlator %x",
  1944. pS20Packet->header.user, pS20Packet->correlator));
  1945. DC_QUIT;
  1946. }
  1947. switch (g_s20State)
  1948. {
  1949. case S20_IN_SHARE:
  1950. //
  1951. // We only need to handle this when we are in a share.
  1952. //
  1953. S20MaybeIssuePersonDelete(pS20Packet->header.user);
  1954. break;
  1955. default:
  1956. break;
  1957. }
  1958. DC_EXIT_POINT:
  1959. DebugExitVOID(S20LeaveMsg);
  1960. }
  1961. //
  1962. // FUNCTION: S20EndMsg
  1963. //
  1964. // DESCRIPTION:
  1965. //
  1966. // Handles an incoming end message.
  1967. //
  1968. // PARAMETERS:
  1969. //
  1970. // pS20Packet - pointer to the end message itself
  1971. //
  1972. // RETURNS: NONE
  1973. //
  1974. void S20EndMsg(PS20ENDPACKET pS20Packet)
  1975. {
  1976. DebugEntry(S20EndMsg);
  1977. WARNING_OUT(("S20EndMsg S20_END from [%d], correlator %x",
  1978. pS20Packet->header.user, pS20Packet->correlator));
  1979. if (!g_s20ShareCorrelator)
  1980. {
  1981. // We don't care
  1982. WARNING_OUT(("S20EndMsg S20_END ignored, not in share and state is %x", g_s20State));
  1983. DC_QUIT;
  1984. }
  1985. //
  1986. // Only the share creator can end the share.
  1987. //
  1988. if (S20_GET_CREATOR(g_s20ShareCorrelator) != pS20Packet->header.user)
  1989. {
  1990. WARNING_OUT(("S20EndMsg Received S20_END from [%d] who did not create share, simply remove from user list.",
  1991. pS20Packet->header.user));
  1992. if (g_s20State == S20_IN_SHARE)
  1993. {
  1994. S20MaybeIssuePersonDelete(pS20Packet->header.user);
  1995. }
  1996. DC_QUIT;
  1997. }
  1998. switch (g_s20State)
  1999. {
  2000. case S20_IN_SHARE:
  2001. case S20_SHARE_PEND:
  2002. case S20_SHARE_STARTING:
  2003. //
  2004. // We just need to generate a share ended event.
  2005. //
  2006. SC_End();
  2007. SetS20State(S20_NO_SHARE);
  2008. break;
  2009. default:
  2010. WARNING_OUT(("S20EndMsg Unhandled case g_s20State %x",g_s20State));
  2011. break;
  2012. }
  2013. DC_EXIT_POINT:
  2014. DebugExitVOID(S20EndMsg);
  2015. }
  2016. //
  2017. // S20CollisionMsg()
  2018. //
  2019. // DESCRIPTION:
  2020. //
  2021. // Handles an incoming collision message.
  2022. //
  2023. // PARAMETERS:
  2024. //
  2025. // pS20Packet - pointer to the collision message itself
  2026. //
  2027. // RETURNS: NONE
  2028. //
  2029. void S20CollisionMsg(PS20COLLISIONPACKET pS20Packet)
  2030. {
  2031. DebugEntry(S20CollisionMsg);
  2032. WARNING_OUT(("S20_COLLISION from [%d], correlator %x",
  2033. pS20Packet->header.user, pS20Packet->correlator));
  2034. if (!g_s20ShareCorrelator)
  2035. {
  2036. // We don't care
  2037. WARNING_OUT(("S20_COLLISION ignored, not in share"));
  2038. DC_QUIT;
  2039. }
  2040. if (g_s20ShareCorrelator != pS20Packet->correlator)
  2041. {
  2042. //
  2043. // Just discard this.
  2044. //
  2045. WARNING_OUT(("Received S20_COLLISION from [%d] with unknown correlator %x",
  2046. pS20Packet->header.user, pS20Packet->correlator));
  2047. DC_QUIT;
  2048. }
  2049. //
  2050. // If we created our own share, but got a collision from the remote,
  2051. // then kill our share.
  2052. //
  2053. if (S20_GET_CREATOR(g_s20ShareCorrelator) != g_s20LocalID)
  2054. {
  2055. TRACE_OUT(("S20_COLLISION ignored, we didn't create share"));
  2056. DC_QUIT;
  2057. }
  2058. switch (g_s20State)
  2059. {
  2060. case S20_IN_SHARE:
  2061. case S20_SHARE_PEND:
  2062. case S20_SHARE_STARTING:
  2063. //
  2064. // We just need to generate a share ended event.
  2065. //
  2066. SC_End();
  2067. SetS20State(S20_NO_SHARE);
  2068. break;
  2069. default:
  2070. WARNING_OUT(("S20ColisionMsg Unhandled case g_s20State %x",g_s20State));
  2071. break;
  2072. }
  2073. DC_EXIT_POINT:
  2074. DebugExitVOID(S20CollisionMsg);
  2075. }
  2076. //
  2077. // FUNCTION: S20DataMsg
  2078. //
  2079. // DESCRIPTION:
  2080. //
  2081. // Handles an incoming data message.
  2082. //
  2083. // PARAMETERS:
  2084. //
  2085. // pS20Packet - pointer to the data message itself
  2086. //
  2087. // RETURNS: TRUE - free the event, FALSE - do not free the event
  2088. //
  2089. void S20DataMsg(PS20DATAPACKET pS20Packet)
  2090. {
  2091. DebugEntry(S20DataMsg);
  2092. ASSERT(!IsBadWritePtr(pS20Packet, sizeof(S20DATAPACKET)));
  2093. ASSERT(!IsBadWritePtr(pS20Packet, sizeof(S20DATAPACKET) - sizeof(DATAPACKETHEADER) +
  2094. pS20Packet->dataLength));
  2095. //
  2096. // Check if we're interseted in this data.
  2097. //
  2098. if ((pS20Packet->correlator == g_s20ShareCorrelator) &&
  2099. (g_s20State == S20_IN_SHARE) &&
  2100. g_asSession.pShare)
  2101. {
  2102. //
  2103. // Return it.
  2104. //
  2105. g_asSession.pShare->SC_ReceivedPacket(pS20Packet);
  2106. }
  2107. DebugExitVOID(S20DataMsg);
  2108. }
  2109. //
  2110. // FUNCTION: S20MaybeAddNewParty
  2111. //
  2112. // DESCRIPTION:
  2113. //
  2114. // If the specified party has not already been added then try to add them
  2115. // now.
  2116. //
  2117. // PARAMETERS:
  2118. //
  2119. // userID - the new party's network user ID.
  2120. // lenCaps - the length of the new party's capabilities.
  2121. // lenName - the length of the new party's name.
  2122. // pData - a pointer to the new party's data which contains the name
  2123. // followed by the capabilities data.
  2124. //
  2125. // RETURNS:
  2126. // BOOL for success
  2127. //
  2128. BOOL S20MaybeAddNewParty
  2129. (
  2130. MCSID mcsID,
  2131. UINT lenCaps,
  2132. UINT lenName,
  2133. LPBYTE pData
  2134. )
  2135. {
  2136. BOOL rc = FALSE;
  2137. UINT oldState;
  2138. LPBYTE pCaps = NULL;
  2139. BOOL memAllocated = FALSE;
  2140. DebugEntry(S20MaybeAddNewParty);
  2141. //
  2142. // If we don't have a share, fail.
  2143. //
  2144. if (!g_asSession.pShare)
  2145. {
  2146. WARNING_OUT(("No ASShare; ignoring add party for [%d]", mcsID));
  2147. DC_QUIT;
  2148. }
  2149. //
  2150. // Check if this party has already been added.
  2151. //
  2152. if (g_asSession.pShare->SC_ValidateNetID(mcsID, NULL))
  2153. {
  2154. TRACE_OUT(("S20MaybeAddNewParty: already added %u", mcsID));
  2155. rc = TRUE;
  2156. DC_QUIT;
  2157. }
  2158. //
  2159. // We need the caps structure to be 4-byte aligned. It currently
  2160. // follows a variable-length name string and may therefore not be
  2161. // aligned. If it is not aligned, we allocate an aligned buffer and
  2162. // copy it there.
  2163. //
  2164. if (0 != (((UINT_PTR)pData + lenName) % 4))
  2165. {
  2166. TRACE_OUT(("Capabilities data is unaligned - realigning"));
  2167. //
  2168. // Get a 4-byte aligned buffer for the capabilities data.
  2169. //
  2170. pCaps = new BYTE[lenCaps];
  2171. if (!pCaps)
  2172. {
  2173. ERROR_OUT(("Could not allocate %u bytes for aligned caps.",
  2174. lenCaps));
  2175. DC_QUIT;
  2176. }
  2177. //
  2178. // Flag so we know to free the memory later.
  2179. //
  2180. memAllocated = TRUE;
  2181. //
  2182. // Copy the caps data into our 4-byte aligned memory block.
  2183. //
  2184. memcpy(pCaps, (pData + lenName), lenCaps);
  2185. }
  2186. else
  2187. {
  2188. //
  2189. // The capabilities data is already aligned so we don't need to
  2190. // move it.
  2191. //
  2192. pCaps = pData + lenName;
  2193. }
  2194. //
  2195. // Make sure we are in a share before we issue person add events.
  2196. //
  2197. oldState = g_s20State;
  2198. SetS20State(S20_IN_SHARE);
  2199. //
  2200. // Attempt to add the new party.
  2201. //
  2202. rc = g_asSession.pShare->SC_PartyAdded(mcsID, (LPSTR)pData, lenCaps, pCaps);
  2203. if (rc)
  2204. {
  2205. //
  2206. // The new party has been accepted so send a response packet. Do
  2207. // this at ALL priorities, so it gets there before any type of data
  2208. // at one particular priority.
  2209. //
  2210. WARNING_OUT(("CP RESPOND %lu %d", g_s20ShareCorrelator, 0));
  2211. S20FlushSendOrQueueControlPacket(S20_RESPOND, g_s20ShareCorrelator,
  2212. mcsID, NET_TOP_PRIORITY | NET_SEND_ALL_PRIORITIES);
  2213. }
  2214. else
  2215. {
  2216. g_asSession.pShare->SC_PartyDeleted(mcsID);
  2217. //
  2218. // Reset the state back to what it was if we failed.
  2219. //
  2220. SetS20State(oldState);
  2221. WARNING_OUT(("S20MaybeAddNewParty g_s20State is %x because we could not add the party", g_s20State));
  2222. if (S20_GET_CREATOR(g_s20ShareCorrelator) == g_s20LocalID)
  2223. {
  2224. //
  2225. // The new party has been rejected so send a delete packet.
  2226. //
  2227. WARNING_OUT(("S20MaybeAddNewParty CP DELETE %lu %u", g_s20ShareCorrelator, mcsID));
  2228. S20FlushSendOrQueueControlPacket(S20_DELETE, g_s20ShareCorrelator,
  2229. mcsID, NET_TOP_PRIORITY);
  2230. }
  2231. }
  2232. DC_EXIT_POINT:
  2233. //
  2234. // Free memory used to store aligned caps.
  2235. //
  2236. if (memAllocated)
  2237. {
  2238. delete[] pCaps;
  2239. }
  2240. DebugExitBOOL(S20MaybeAddNewParty, rc);
  2241. return(rc);
  2242. }
  2243. //
  2244. // FUNCTION: S20NewCorrelator
  2245. //
  2246. // DESCRIPTION:
  2247. //
  2248. // Returns a new correlator for us to use when we are creating a share.
  2249. // This is a combination of our mcsID (low 16 bits in Intel format) and
  2250. // a generation count (high 16 bits in Intel format).
  2251. //
  2252. // PARAMETERS: NONE
  2253. //
  2254. // RETURNS: the new correlator
  2255. //
  2256. //
  2257. UINT S20NewCorrelator(void)
  2258. {
  2259. UINT correlator;
  2260. DebugEntry(S20NewCorrelator);
  2261. g_s20Generation++;
  2262. correlator = g_s20LocalID | (((UINT)(g_s20Generation & 0xFFFF)) << 16);
  2263. WARNING_OUT(("Getting a new correlator %x local id = %x",correlator, g_s20LocalID));
  2264. DebugExitDWORD(S20NewCorrelator, correlator);
  2265. return(correlator);
  2266. }
  2267. //
  2268. // FUNCTION: S20MaybeIssuePersonDelete
  2269. //
  2270. // DESCRIPTION:
  2271. //
  2272. // If the supplied person is in the share then issue a PARTY_DELETED event
  2273. // for them.
  2274. //
  2275. // PARAMTERS:
  2276. //
  2277. // mcsID - a network personID
  2278. //
  2279. // reason - the reason code to use
  2280. //
  2281. // RETURNS: NONE
  2282. //
  2283. //
  2284. void S20MaybeIssuePersonDelete(MCSID mcsID)
  2285. {
  2286. DebugEntry(S20MaybeIssuePersonDelete);
  2287. if (g_asSession.pShare)
  2288. {
  2289. g_asSession.pShare->SC_PartyDeleted(mcsID);
  2290. }
  2291. //
  2292. // HET will kill the share if there aren't any hosts left. So we
  2293. // don't need to do anything here.
  2294. //
  2295. DebugExitVOID(S20MaybeIssuePersonDelete);
  2296. }
  2297. //
  2298. // FUNCTION: S20StreamToS20Priority
  2299. //
  2300. // DESCRIPTION:
  2301. //
  2302. // Converts a stream ID into a NET priority
  2303. //
  2304. // PARAMETERS:
  2305. //
  2306. // streamID - the stream ID.
  2307. //
  2308. // RETURNS: the priority
  2309. //
  2310. //
  2311. const NET_PRIORITY c_StreamS20Priority[NUM_PROT_STR - 1] =
  2312. {
  2313. NET_LOW_PRIORITY, // PROT_STR_UPDATES
  2314. NET_MEDIUM_PRIORITY, // PROT_STR_MISC
  2315. NET_MEDIUM_PRIORITY, // PROT_STR_UNUSED
  2316. NET_MEDIUM_PRIORITY, // PROT_STR_INPUT
  2317. };
  2318. NET_PRIORITY S20StreamToS20Priority(UINT streamID)
  2319. {
  2320. NET_PRIORITY priority;
  2321. DebugEntry(S20StreamToS20Priority);
  2322. ASSERT(streamID > PROT_STR_INVALID);
  2323. ASSERT(streamID < NUM_PROT_STR);
  2324. ASSERT(streamID != PROT_STR_UNUSED);
  2325. priority = c_StreamS20Priority[streamID - 1];
  2326. DebugExitDWORD(S20StreamToS20Priority, priority);
  2327. return(priority);
  2328. }
  2329. BOOL S20AcceptNewCorrelator(PS20CREATEPACKET pS20Packet)
  2330. {
  2331. BOOL rc = FALSE;
  2332. //
  2333. // Either there is no share or we have issued a join. In these
  2334. // curcumstances we want to try to accept the create message.
  2335. //
  2336. //
  2337. // Remember the share correlator.
  2338. //
  2339. g_s20ShareCorrelator = pS20Packet->correlator;
  2340. //
  2341. // Start the share
  2342. // CHECK FOR FAILURE FOR THE FIRST ONE.
  2343. //
  2344. WARNING_OUT(("S20CreateMsg SC_Start"));
  2345. rc = SC_Start(g_s20LocalID);
  2346. if (rc)
  2347. {
  2348. SetS20State(S20_SHARE_STARTING);
  2349. rc = S20MaybeAddNewParty(pS20Packet->header.user,
  2350. pS20Packet->lenCaps, pS20Packet->lenName,
  2351. pS20Packet->data);
  2352. }
  2353. if (!rc)
  2354. {
  2355. //
  2356. // Something went wrong. Kill the share, this will clean up
  2357. // everything.
  2358. //
  2359. SC_End();
  2360. }
  2361. WARNING_OUT(("S20CreateMsg not hadled case g_state %x correlator %x", g_s20State, g_s20ShareCorrelator));
  2362. return rc;
  2363. }