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.

957 lines
32 KiB

  1. #include "precomp.h"
  2. //
  3. // UP.CPP
  4. // Update Packager
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_NET
  9. //
  10. // UP_FlowControl()
  11. // Checks if we've switched between slow and fast throughput
  12. //
  13. void ASHost::UP_FlowControl(UINT newBufferSize)
  14. {
  15. DebugEntry(ASHost::UP_FlowControl);
  16. if (newBufferSize > (LARGE_ORDER_PACKET_SIZE / 2))
  17. {
  18. if (m_upfUseSmallPackets)
  19. {
  20. m_upfUseSmallPackets = FALSE;
  21. TRACE_OUT(("UP_FlowControl: FAST; use large packets"));
  22. }
  23. }
  24. else
  25. {
  26. if (!m_upfUseSmallPackets)
  27. {
  28. m_upfUseSmallPackets = TRUE;
  29. TRACE_OUT(("UP_FlowControl: SLOW; use small packets"));
  30. }
  31. }
  32. DebugExitVOID(ASHost::UP_FlowControl);
  33. }
  34. //
  35. // UP_Periodic()
  36. //
  37. // Called periodically, to send graphical updates as orders and/or screen
  38. // data.
  39. //
  40. void ASHost::UP_Periodic(UINT currentTime)
  41. {
  42. BOOL fSendSD = FALSE;
  43. BOOL fSendOrders = FALSE;
  44. UINT tmpTime;
  45. UINT timeSinceOrders;
  46. UINT timeSinceSD;
  47. UINT timeSinceTrying;
  48. DebugEntry(ASHost::UP_Periodic);
  49. //
  50. // This is a
  51. // performance critical part of the scheduling so we apply some
  52. // heuristics to try and keep the overheads down.
  53. //
  54. // 1.If there was no back pressure last time then we check the
  55. // rate of accumulation of screendata over the last period.
  56. // If it was high then we apply a time slice to the sending
  57. // of screendata.
  58. //
  59. // 2.If the rate of order accumulation was also high then we
  60. // apply a timeslice to the order accumulation as well, just
  61. // to avoid too high a CPU overhead trying to send orders
  62. // when we will eventually fail to keep up. We keep this
  63. // time period low because the objective is simply to avoid
  64. // sending hundreds of packets containing few orders each.
  65. // (On the other hand, we want to send the single textout
  66. // following a keystoke ASAP so we must not timeslice all the
  67. // time.)
  68. //
  69. // 3.If neither orders nor screendata is piling up quickly then
  70. // we do a full send immediately.
  71. //
  72. // 4.If there was back pressure on the last send then we still
  73. // send orders, but always on the time slice, independent of
  74. // the order accumulation rate.
  75. //
  76. // Note that we cannot sample the accumulation rates for every
  77. // pass because the app doing the drawing may be interrupted by
  78. // us for a few hundred milliseconds. Therefore we only sample
  79. // the bounds every VOLUME_SAMPLE milliseconds.
  80. //
  81. //
  82. timeSinceSD = currentTime - m_upLastSDTime;
  83. timeSinceOrders = currentTime - m_upLastOrdersTime;
  84. timeSinceTrying = currentTime - m_upLastTrialTime;
  85. //
  86. // Sample the accumulation rates.
  87. //
  88. m_upSDAccum += BA_QueryAccumulation();
  89. m_upOrdersAccum += OA_QueryOrderAccum();
  90. //
  91. // Sample the throughput over the last period to see whether we
  92. // can operate in rapid respose mode or whether we should
  93. // timeslice.
  94. //
  95. if (timeSinceTrying > DCS_VOLUME_SAMPLE)
  96. {
  97. //
  98. // Take the newly accumulated deltas.
  99. //
  100. m_upDeltaSD = m_upSDAccum;
  101. m_upDeltaOrders = m_upOrdersAccum;
  102. //
  103. // Store time of last retrieval.
  104. //
  105. m_upLastTrialTime = currentTime;
  106. //
  107. // Reset the running totals.
  108. //
  109. m_upSDAccum = 0;
  110. m_upOrdersAccum = 0;
  111. }
  112. //
  113. // If we are way out of line then send updates. Not that this
  114. // will reset the update timer independent of whether the send
  115. // works or not, so that we don't enter this arm continually
  116. // when we time out but are in a back pressure situation
  117. //
  118. // The long stop timer is there to catch apps that keep a
  119. // continual flow of orders/SD at above the suppression rate.
  120. // We want to tune our heuristics to avoid this, but if it
  121. // happens than we must send the data eventually. The problem
  122. // is that this objective clashes with the scenario of the user
  123. // paging down twenty times, where our most efficient approach
  124. // is to let him run and snapshot the SD at the end, rather
  125. // than every PERIOD_LONG milliseconds. (A screen snapshot
  126. // will stop the host for a second!).
  127. //
  128. if (timeSinceSD > DCS_SD_UPDATE_LONG_PERIOD)
  129. {
  130. fSendSD = TRUE;
  131. }
  132. else
  133. {
  134. //
  135. // We only disregard our time slicing if the rate of orders
  136. // and screendata is low enough to warrant it. If the rate
  137. // is too high then hold off so that we can do some packet
  138. // consolidation. If we had no back pressure last time or
  139. // the screendata rate is now low enough then try sending
  140. // SD as well as orders.
  141. //
  142. // The order threshold is measured in number of orders over
  143. // the period. Screendata is measured in the total area
  144. // accumulated (prior to any spoiling).
  145. //
  146. if (!m_upBackPressure)
  147. {
  148. if (m_upDeltaOrders < DCS_ORDERS_TURNOFF_FREQUENCY)
  149. {
  150. fSendOrders = TRUE;
  151. if (m_upDeltaSD < DCS_BOUNDS_TURNOFF_RATE)
  152. {
  153. if ((timeSinceSD < DCS_SD_UPDATE_SHORT_PERIOD) &&
  154. (m_upDeltaSD > DCS_BOUNDS_IMMEDIATE_RATE))
  155. {
  156. fSendSD = FALSE;
  157. }
  158. else
  159. {
  160. fSendSD = TRUE;
  161. }
  162. }
  163. }
  164. }
  165. //
  166. // Even in a back pressure situation we try and send orders
  167. // periodically to keep current. If we overflow the order
  168. // buffer then we will constrain the buffer size to prevent
  169. // sending too many non-productive orders. (But we dont
  170. // turn orders off because we still want the user to see
  171. // things happening.) Generally we send orders immediately,
  172. // provided the rate of accumulation is within the limits.
  173. // This test is to time slice orders if they are being
  174. // generated at a high rate. The constant must be
  175. // reasonably small otherwise we force the order buffer to
  176. // overflow and order processing will be turned off.
  177. //
  178. if (!fSendSD && !fSendOrders)
  179. {
  180. if (timeSinceOrders > DCS_ORDER_UPDATE_PERIOD)
  181. {
  182. fSendOrders = TRUE;
  183. }
  184. }
  185. }
  186. //
  187. // Now we can go ahead and try sending! First look to see if
  188. // we can do both screendata and orders
  189. //
  190. if (fSendSD)
  191. {
  192. //
  193. // Indicate no back pressure (even if this send is
  194. // triggered by a timout our initial assumption is no back
  195. // pressure). Back pressure will be reinstated by
  196. // SendUpdates if necessary.
  197. //
  198. m_upBackPressure = FALSE;
  199. UPSendUpdates();
  200. //
  201. // Sending screendata can take a long time. It messes up
  202. // our heuristics unless we adjust for it.
  203. //
  204. tmpTime = GetTickCount();
  205. timeSinceTrying -= (tmpTime - currentTime);
  206. m_pShare->m_dcsLastScheduleTime = tmpTime;
  207. m_upLastSDTime = tmpTime;
  208. m_upLastOrdersTime = tmpTime;
  209. }
  210. else
  211. {
  212. if (fSendOrders)
  213. {
  214. //
  215. // Either the update rate is too high or we are
  216. // experiencing back pressure so just send the orders
  217. // and not the screendata. This is because we want to
  218. // avoid entering screendata mode as a result of order
  219. // back pressure for as long as we can. The screendata
  220. // will come later, when things have settled down a bit
  221. //
  222. m_upLastOrdersTime = currentTime;
  223. m_upBackPressure = TRUE;
  224. if (!UPSendUpdates())
  225. {
  226. //
  227. // This is the only real action so leave all the
  228. // tracing separate for cleanliness. If there are
  229. // orders in transit then everything is fine. If none
  230. // are sent for a while then we want to break out of
  231. // our SD back pressure wait. This is because we are
  232. // only sampling the flow rates every DCS_VOLUME_SAMPLE msecs,
  233. // but we dont want to have to wait that long to flush the SD.
  234. // We cannot increase the flow sample rate because then
  235. // it becomes too erratic because of system scheduling.
  236. //
  237. m_upBackPressure = FALSE;
  238. UPSendUpdates();
  239. m_upLastSDTime = currentTime;
  240. }
  241. }
  242. }
  243. DebugExitVOID(ASHost::UP_Periodic);
  244. }
  245. //
  246. // UPSendUpdates()
  247. // Actually tries to allocate and send orders + screen data. What it does
  248. // depends on
  249. // * Presence of back-pressure due to previous send failures
  250. // * How much screen data & orders there are
  251. // * Whether we're in serious spoiling mode and can't keep up
  252. // * What packet size to send
  253. //
  254. // Returns:
  255. // # of packets sent
  256. //
  257. UINT ASHost::UPSendUpdates(void)
  258. {
  259. BOOL synced;
  260. BOOL ordersSent;
  261. UINT numPackets = 0;
  262. DebugEntry(ASHost::UPSendUpdates);
  263. //
  264. // If we actually have updates to send then try to send a sync token.
  265. //
  266. if ((OA_GetTotalOrderListBytes() > 0) ||
  267. (m_sdgcLossy != 0) ||
  268. (m_baNumRects > 0))
  269. {
  270. synced = UP_MaybeSendSyncToken();
  271. //
  272. // Only send updates if we have sent the sync token succesfully.
  273. //
  274. if (synced)
  275. {
  276. //
  277. // There is no outstanding sync token waiting to be sent, so we
  278. // can send the orders and screen data updates.
  279. //
  280. //
  281. // Send accumulated orders. If this call fails (probably out
  282. // of memory) then don't send any other updates - we'll try
  283. // sending the whole lot later. The orders MUST be sent before
  284. // the screen data.
  285. //
  286. if (PM_MaybeSendPalettePacket())
  287. {
  288. ordersSent = UPSendOrders(&numPackets);
  289. if (!ordersSent)
  290. {
  291. m_upBackPressure = TRUE;
  292. }
  293. else
  294. {
  295. //
  296. // Orders sent OK so go for the screendata, provided
  297. // the caller wants us to.
  298. //
  299. if (!m_upBackPressure)
  300. {
  301. //
  302. // We may now try and send screen data. However,
  303. // we need to be careful not to do this too
  304. // frequently, because DC-Share is now being
  305. // scheduled to send as soon as network buffers
  306. // become available. On the other hand, some
  307. // apps respond to keystrokes with screendata so
  308. // we cannot just slow it down!
  309. //
  310. // The approach is to have SendScreenDataArea
  311. // return the amount of data sent, together with
  312. // an indication as to whether we hit back pressure
  313. //
  314. // We return these to dcsapi which has control of
  315. // when we are scheduled and passes the paramaters
  316. // in again
  317. //
  318. //
  319. TRACE_OUT(( "Sending SD"));
  320. SDG_SendScreenDataArea(&m_upBackPressure, &numPackets);
  321. }
  322. else
  323. {
  324. //
  325. // We sent the orders OK an so we must reset
  326. // the back pressure indicator even though we
  327. // were asked not to send screendata
  328. //
  329. TRACE_OUT(( "Orders sent and BP relieved"));
  330. m_upBackPressure = FALSE;
  331. }
  332. }
  333. }
  334. }
  335. }
  336. else
  337. {
  338. m_upBackPressure = FALSE;
  339. }
  340. DebugExitDWORD(ASHost::UPSendUpdates, numPackets);
  341. return(numPackets);
  342. }
  343. //
  344. // UP_MaybeSendSyncToken()
  345. //
  346. BOOL ASHost::UP_MaybeSendSyncToken(void)
  347. {
  348. PUPSPACKET pUPSPacket;
  349. #ifdef _DEBUG
  350. UINT sentSize;
  351. #endif // _DEBUG
  352. DebugEntry(ASHost::UP_MaybeSendSyncToken);
  353. //
  354. // Check to see if we should send a sync token.
  355. //
  356. if (m_upfSyncTokenRequired)
  357. {
  358. //
  359. // The sync packet consists of an updates packets as far as the end
  360. // of the header.
  361. //
  362. pUPSPacket = (PUPSPACKET)m_pShare->SC_AllocPkt(PROT_STR_UPDATES,
  363. g_s20BroadcastID, sizeof(UPSPACKET));
  364. if (!pUPSPacket)
  365. {
  366. //
  367. // We will try again later.
  368. //
  369. TRACE_OUT(("Failed to alloc UP sync packet"));
  370. }
  371. else
  372. {
  373. //
  374. // Fill in the packet contents.
  375. //
  376. pUPSPacket->header.header.data.dataType = DT_UP;
  377. pUPSPacket->header.updateType = UPD_SYNC;
  378. //
  379. // Now send the packet to the remote application.
  380. //
  381. if (m_pShare->m_scfViewSelf)
  382. m_pShare->UP_ReceivedPacket(m_pShare->m_pasLocal,
  383. &(pUPSPacket->header.header));
  384. #ifdef _DEBUG
  385. sentSize =
  386. #endif // _DEBUG
  387. m_pShare->DCS_CompressAndSendPacket(PROT_STR_UPDATES,
  388. g_s20BroadcastID, &(pUPSPacket->header.header),
  389. sizeof(*pUPSPacket));
  390. TRACE_OUT(("UP SYNC packet size: %08d, sent %08d",
  391. sizeof(*pUPSPacket), sentSize));
  392. //
  393. // The sync packet was successfully sent.
  394. //
  395. m_upfSyncTokenRequired = FALSE;
  396. }
  397. }
  398. DebugExitBOOL(ASHost::UP_MaybeSendSyncToken, (!m_upfSyncTokenRequired));
  399. return(!m_upfSyncTokenRequired);
  400. }
  401. //
  402. // UPSendOrders(..)
  403. //
  404. // Sends all accumulated orders.
  405. //
  406. // Returns:
  407. // TRUE if all orders successfully sent
  408. // FALSE if send failed (e.g. if unable to allocate network packet)
  409. //
  410. //
  411. BOOL ASHost::UPSendOrders(UINT * pcPackets)
  412. {
  413. PORDPACKET pPacket = NULL;
  414. UINT cbOrderBytes;
  415. UINT cbOrderBytesRemaining;
  416. UINT cbPacketSize;
  417. BOOL rc = TRUE;
  418. #ifdef _DEBUG
  419. UINT sentSize;
  420. #endif // _DEBUG
  421. DebugEntry(ASHost::UPSendOrders);
  422. //
  423. // Find out how many bytes of orders there are in the Order List.
  424. //
  425. cbOrderBytesRemaining = UPFetchOrdersIntoBuffer(NULL, NULL, NULL);
  426. //
  427. // Process any orders on the list.
  428. //
  429. if (cbOrderBytesRemaining > 0)
  430. {
  431. TRACE_OUT(( "%u order bytes to fetch", cbOrderBytesRemaining));
  432. //
  433. // Keep sending packets while there are some orders to do.
  434. //
  435. while (cbOrderBytesRemaining > 0)
  436. {
  437. UINT cbMax;
  438. //
  439. // Make sure the order size does not exceed the max packet
  440. // size.
  441. //
  442. cbMax = (m_upfUseSmallPackets) ? SMALL_ORDER_PACKET_SIZE :
  443. LARGE_ORDER_PACKET_SIZE;
  444. cbPacketSize = min(cbOrderBytesRemaining,
  445. (cbMax - sizeof(ORDPACKET) + 1));
  446. //
  447. // Allocate a packet to send the data in.
  448. //
  449. pPacket = (PORDPACKET)m_pShare->SC_AllocPkt(PROT_STR_UPDATES, g_s20BroadcastID,
  450. sizeof(ORDPACKET) + cbPacketSize - 1);
  451. if (!pPacket)
  452. {
  453. //
  454. // Failed to allocate a packet. We skip out immediately -
  455. // we'll try again later.
  456. //
  457. TRACE_OUT(("Failed to alloc UP order packet, size %u",
  458. sizeof(ORDPACKET) + cbPacketSize - 1));
  459. rc = FALSE;
  460. DC_QUIT;
  461. }
  462. //
  463. // Transfer as many orders into the packet as will fit.
  464. //
  465. cbOrderBytes = cbPacketSize;
  466. cbOrderBytesRemaining = UPFetchOrdersIntoBuffer(
  467. pPacket->data, &pPacket->cOrders, &cbOrderBytes);
  468. TRACE_OUT(( "%u bytes fetched into %u byte pkt. %u remain.",
  469. cbOrderBytes, cbPacketSize, cbOrderBytesRemaining));
  470. //
  471. // If no order bytes were transferred then try again with a
  472. // Large Order Packet.
  473. //
  474. if (cbOrderBytes == 0)
  475. {
  476. //
  477. // We need to use a larger packet to transfer the
  478. // orders into. (The first order must be a very large
  479. // order such as a large bitmap cache update).
  480. //
  481. S20_FreeDataPkt(&(pPacket->header.header));
  482. //
  483. // cbOrderBytesRemaining may not accurate if there are
  484. // any MemBlt orders in the order heap. This is
  485. // because we may have to insert a color table order
  486. // and / or a bitmap bits order before the MemBlt.
  487. //
  488. // To avoid getting into an infinite loop if there is
  489. // only a MemBlt remaining but we actually have to send
  490. // a color table and / or a bitmap bits order
  491. // (cbOrderBytesRemaining would never get set high
  492. // enough to allow us to send the color table / bitmap
  493. // bits order), make the buffer at least large enough
  494. // to hold the largest amount of data required for all
  495. // the parts of a MemBlt.
  496. //
  497. //
  498. // The maximum number of bytes required to send a MemBlt order. This is
  499. // The size of the largest possible color table order
  500. // + the size of the largest possible bitmap bits order
  501. // + the size of the largest MemBlt order.
  502. //
  503. cbPacketSize = sizeof(BMC_COLOR_TABLE_ORDER) +
  504. (256 * sizeof(TSHR_RGBQUAD)) +
  505. sizeof(BMC_BITMAP_BITS_ORDER_R2) +
  506. sizeof(MEM3BLT_R2_ORDER) +
  507. MP_CACHE_CELLSIZE(MP_LARGE_TILE_WIDTH, MP_LARGE_TILE_HEIGHT,
  508. m_usrSendingBPP);
  509. cbPacketSize = max(cbPacketSize, cbOrderBytesRemaining);
  510. if (cbPacketSize > (UINT)(LARGE_ORDER_PACKET_SIZE -
  511. sizeof(ORDPACKET) + 1))
  512. {
  513. TRACE_OUT(("Too many order bytes for large packet(%d)",
  514. cbOrderBytesRemaining));
  515. cbPacketSize = LARGE_ORDER_PACKET_SIZE -
  516. sizeof(ORDPACKET) + 1;
  517. }
  518. pPacket = (PORDPACKET)m_pShare->SC_AllocPkt(PROT_STR_UPDATES,
  519. g_s20BroadcastID, sizeof(ORDPACKET) + cbPacketSize - 1);
  520. if (!pPacket)
  521. {
  522. TRACE_OUT(("Failed to alloc UP order packet, size %u",
  523. sizeof(ORDPACKET) + cbPacketSize - 1));
  524. rc = FALSE;
  525. DC_QUIT;
  526. }
  527. //
  528. // Transfer as many orders into the packet as will
  529. // fit.
  530. //
  531. cbOrderBytes = cbPacketSize;
  532. cbOrderBytesRemaining = UPFetchOrdersIntoBuffer(
  533. pPacket->data, &pPacket->cOrders, &cbOrderBytes );
  534. //
  535. // If no orders were transferred then something has
  536. // gone wrong. Probably flow control kicked in or
  537. // a dekstop switch occurred.
  538. // Return failure now!
  539. // Hopefully things will sort themselves out later
  540. // or we will resort to sending updates as screen
  541. // data once the order accumulation heap becomes
  542. // full.
  543. //
  544. if (cbOrderBytes == 0)
  545. {
  546. WARNING_OUT(("No orders fetched into %u byte packet, %u bytes left",
  547. cbPacketSize, cbOrderBytesRemaining));
  548. S20_FreeDataPkt(&(pPacket->header.header));
  549. rc = FALSE;
  550. DC_QUIT;
  551. }
  552. }
  553. //
  554. // Fill in the packet header.
  555. //
  556. pPacket->header.header.data.dataType = DT_UP;
  557. pPacket->header.updateType = UPD_ORDERS;
  558. pPacket->sendBPP = (TSHR_UINT16)m_usrSendingBPP;
  559. //
  560. // If encoding is switched on, update the data size to reflect
  561. // it with encoded orders
  562. //
  563. if (m_pShare->m_oefOE2EncodingOn)
  564. {
  565. pPacket->header.header.dataLength = sizeof(ORDPACKET) + cbOrderBytes - 1
  566. - sizeof(S20DATAPACKET) + sizeof(DATAPACKETHEADER);
  567. }
  568. //
  569. // Now send it.
  570. //
  571. if (m_pShare->m_scfViewSelf)
  572. m_pShare->UP_ReceivedPacket(m_pShare->m_pasLocal,
  573. &(pPacket->header.header));
  574. #ifdef _DEBUG
  575. sentSize =
  576. #endif // _DEBUG
  577. m_pShare->DCS_CompressAndSendPacket(PROT_STR_UPDATES, g_s20BroadcastID,
  578. &(pPacket->header.header), sizeof(ORDPACKET) + cbOrderBytes - 1);
  579. TRACE_OUT(("UP ORDERS packet size: %08d, sent %08d",
  580. sizeof(ORDPACKET) + cbOrderBytes - 1, sentSize));
  581. ++(*pcPackets);
  582. }
  583. }
  584. DC_EXIT_POINT:
  585. DebugExitBOOL(ASHost::UPSendOrders, rc);
  586. return(rc);
  587. }
  588. //
  589. //
  590. // UPFetchOrdersIntoBuffer(..)
  591. //
  592. // Encodes orders from the Order List and copies them into the supplied
  593. // buffer, then frees up the memory of each order copied.
  594. //
  595. // Orders are copied until the buffer is full or there are no more orders.
  596. //
  597. // Returns:
  598. // The number of order bytes that were NOT returned.
  599. // i.e. 0 if all orders were returned.
  600. // A simple way to find out the total number of order bytes
  601. // in the Order List is to call the function with a buffer length
  602. // of zero.
  603. //
  604. // *pcbBufferSize is updated to contain the total number of bytes
  605. // returned.
  606. //
  607. //
  608. UINT ASHost::UPFetchOrdersIntoBuffer
  609. (
  610. LPBYTE pBuffer,
  611. LPTSHR_UINT16 pcOrders,
  612. LPUINT pcbBufferSize
  613. )
  614. {
  615. LPINT_ORDER pListOrder;
  616. LPINT_ORDER pCurrentOrder;
  617. UINT cbFreeBytesInBuffer;
  618. UINT cOrdersCopied;
  619. LPBYTE pDst;
  620. UINT cbOrderSize;
  621. UINT ulRemainingOrderBytes;
  622. BOOL processingMemBlt;
  623. DebugEntry(ASHost::UPFetchOrdersIntoBuffer);
  624. //
  625. // Make a quick exit if the Order List length is being queried.
  626. //
  627. if ( (pcbBufferSize == NULL) ||
  628. (*pcbBufferSize == 0) )
  629. {
  630. goto fetch_orders_exit;
  631. }
  632. //
  633. // Initialize the buffer pointer and size.
  634. //
  635. pDst = pBuffer;
  636. cbFreeBytesInBuffer = *pcbBufferSize;
  637. //
  638. // Keep a count of the number of orders we copy.
  639. //
  640. cOrdersCopied = 0;
  641. //
  642. // Return as many orders as possible.
  643. //
  644. pListOrder = OA_GetFirstListOrder();
  645. TRACE_OUT(( "First order: 0x%08x", pListOrder));
  646. while (pListOrder != NULL)
  647. {
  648. if (pListOrder->OrderHeader.Common.fOrderFlags & OF_INTERNAL)
  649. {
  650. //
  651. // This is an internal order. Currently SBC is the only
  652. // component to use internal orders, so get SBC to process it.
  653. //
  654. SBC_ProcessInternalOrder(pListOrder);
  655. //
  656. // Internal order must not get sent over the wire, so skip on
  657. // to the next order
  658. //
  659. pListOrder = OA_RemoveListOrder(pListOrder);
  660. continue;
  661. }
  662. if (ORDER_IS_MEMBLT(pListOrder) || ORDER_IS_MEM3BLT(pListOrder))
  663. {
  664. //
  665. // This is a MEMBLT or a MEM3BLT so we have to do some extra
  666. // processing... This function returns us a pointer to the
  667. // next order which should be sent - this will often not be the
  668. // MEMBLT, but a color table order or a bitmap bits order.
  669. //
  670. if (!SBC_ProcessMemBltOrder(pListOrder, &pCurrentOrder))
  671. {
  672. //
  673. // This can fail if
  674. // * we're low on memory
  675. // * we changed from 8BPP to 24BPP sending, because
  676. // somebody left the share, and we have queued up
  677. // SBC orders that we can no longer process.
  678. //
  679. TRACE_OUT(("Failed to process SBC order, fall back to SDG"));
  680. pListOrder = OA_RemoveListOrder(pListOrder);
  681. continue;
  682. }
  683. processingMemBlt = TRUE;
  684. }
  685. else
  686. {
  687. //
  688. // This isn't a MEMBLT or a MEM3BLT - just set pCurrentOrder to
  689. // be pListOrder
  690. //
  691. pCurrentOrder = pListOrder;
  692. processingMemBlt = FALSE;
  693. }
  694. if (m_pShare->m_oefOE2EncodingOn)
  695. {
  696. //
  697. // Encoding is switched on.
  698. // Encode the order into the next free space in the buffer
  699. //
  700. cbOrderSize = OE2_EncodeOrder( pCurrentOrder,
  701. pDst,
  702. (TSHR_UINT16)cbFreeBytesInBuffer );
  703. TRACE_OUT(( "Encoded size, %u bytes", cbOrderSize));
  704. }
  705. else
  706. {
  707. //
  708. // Copy the order into the buffer.
  709. //
  710. cbOrderSize = COM_ORDER_SIZE(
  711. ((LPCOM_ORDER)(&(pCurrentOrder->OrderHeader.Common))));
  712. if (cbOrderSize <= cbFreeBytesInBuffer)
  713. {
  714. memcpy(pDst,
  715. (LPCOM_ORDER)(&(pCurrentOrder->OrderHeader.Common)),
  716. cbOrderSize);
  717. }
  718. else
  719. {
  720. //
  721. // No room for this order in this packet.
  722. //
  723. cbOrderSize = 0;
  724. }
  725. }
  726. //
  727. // Check whether the order was copied into the buffer.
  728. //
  729. if (cbOrderSize == 0)
  730. {
  731. //
  732. // The order was too big to fit in this buffer.
  733. // Exit the loop - this order will go in the next packet.
  734. //
  735. break;
  736. }
  737. //
  738. // Update the buffer pointer past the encoded order.
  739. //
  740. pDst += cbOrderSize;
  741. cbFreeBytesInBuffer -= cbOrderSize;
  742. cOrdersCopied++;
  743. if (processingMemBlt)
  744. {
  745. //
  746. // If we are processing a MEMBLT order, we have to notify SBC
  747. // that we've dealt with it successfully so that it returns us
  748. // a different order next time.
  749. //
  750. SBC_OrderSentNotification(pCurrentOrder);
  751. }
  752. if (pCurrentOrder == pListOrder)
  753. {
  754. //
  755. // We successfully copied the order into the buffer - on to the
  756. // next one UNLESS we haven't processed the last one we picked
  757. // out of the order list i.e. pCurrentOrder is not the same as
  758. // pListOrder. This will happen if we just processed a color
  759. // table order or a bitmap bits order returned from
  760. // SBC_ProcessMemBltOrder (if we processed the MEMBLT itself,
  761. // we can safely move on to the next order).
  762. //
  763. pListOrder = OA_RemoveListOrder(pListOrder);
  764. }
  765. }
  766. //
  767. // Fill in the packet header.
  768. //
  769. if (pcOrders != NULL)
  770. {
  771. *pcOrders = (TSHR_UINT16)cOrdersCopied;
  772. }
  773. //
  774. // Update the buffer size to indicate how much data we have
  775. // written.
  776. //
  777. *pcbBufferSize -= cbFreeBytesInBuffer;
  778. TRACE_OUT(( "Returned %d orders in %d bytes",
  779. cOrdersCopied,
  780. *pcbBufferSize));
  781. fetch_orders_exit:
  782. //
  783. // Return the number of bytes still to be processed
  784. //
  785. ulRemainingOrderBytes = OA_GetTotalOrderListBytes();
  786. DebugExitDWORD(ASHost::UPFetchOrdersIntoBuffer, ulRemainingOrderBytes);
  787. return(ulRemainingOrderBytes);
  788. }
  789. //
  790. // UP_ReceivePacket()
  791. //
  792. void ASShare::UP_ReceivedPacket
  793. (
  794. ASPerson * pasPerson,
  795. PS20DATAPACKET pPacket
  796. )
  797. {
  798. PUPPACKETHEADER pUPPacket;
  799. DebugEntry(ASShare::UP_ReceivedPacket);
  800. ValidatePerson(pasPerson);
  801. if (!pasPerson->m_pView)
  802. {
  803. //
  804. // Updates for parties which we don't recognise as hosts are just
  805. // discarded.
  806. //
  807. // NOTE:
  808. // 2.0 Win95 does not have HET, where we kick off sharing/unsharing.
  809. // But it did have TT, and the packet type/messages were defined
  810. // cleverly for HET so that 2.0 Win95 works the same. When they
  811. // start to share, we get a PT_TT packet with a non-zero count.
  812. // The difference really is that the number is apps for Win95 2.0
  813. // and HWNDs for everybody else.
  814. //
  815. WARNING_OUT(("UP_ReceivedUpdates: Ignoring updates from person [%d] not hosting",
  816. pasPerson->mcsID));
  817. DC_QUIT;
  818. }
  819. pUPPacket = (PUPPACKETHEADER)pPacket;
  820. switch (pUPPacket->updateType)
  821. {
  822. case UPD_SCREEN_DATA:
  823. SDP_ReceivedPacket(pasPerson, pPacket);
  824. break;
  825. case UPD_ORDERS:
  826. OD_ReceivedPacket(pasPerson, pPacket);
  827. break;
  828. case UPD_PALETTE:
  829. PM_ReceivedPacket(pasPerson, pPacket);
  830. break;
  831. case UPD_SYNC:
  832. //
  833. // We need to reset our INCOMING decoding info since the sender
  834. // resets his OUTGOING encoding info for a sync.
  835. //
  836. OD2_SyncIncoming(pasPerson);
  837. //
  838. // NOTE:
  839. // We do not need to reset INCOMING data for
  840. // PM -- the host won't send us old palette references
  841. // RBC -- the host won't send us old bitmap references.
  842. // Even though it would be nice to delete the existing
  843. // bitmaps, recreating the cache is a hassle.
  844. // CM -- the host won't send us old cursor references
  845. // SSI -- the host won't send us old savebits references
  846. //
  847. break;
  848. default:
  849. ERROR_OUT(("Unknown UP packet type %u from [%d]",
  850. pUPPacket->updateType,
  851. pasPerson->mcsID));
  852. break;
  853. }
  854. DC_EXIT_POINT:
  855. DebugExitVOID(ASShare::UP_ReceivedPacket);
  856. }
  857.