Source code of Windows XP (NT5)
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.

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