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.

300 lines
7.5 KiB

  1. #include "precomp.h"
  2. //
  3. // CPC.CPP
  4. // Capabilities Coordinator
  5. //
  6. // Copyright(c) Microsoft 1997-
  7. //
  8. #define MLZ_FILE_ZONE ZONE_CORE
  9. //
  10. // CPC_PartyJoiningShare()
  11. //
  12. BOOL ASShare::CPC_PartyJoiningShare
  13. (
  14. ASPerson * pasPerson,
  15. UINT cbCaps,
  16. LPVOID pCapsData
  17. )
  18. {
  19. PPROTCOMBINEDCAPS pCombinedCaps;
  20. LPBYTE pCapsSrc;
  21. PPROTCAPS pCapsDst;
  22. UINT sizeSrc;
  23. UINT sizeDst;
  24. BOOL rc = FALSE;
  25. int i;
  26. PPROTCAPS pCapCheck;
  27. DebugEntry(ASShare::CPC_PartyJoiningShare);
  28. //
  29. // Set up caps
  30. //
  31. if (pasPerson == m_pasLocal)
  32. {
  33. // Copy the global variable caps
  34. memcpy(&pasPerson->cpcCaps, pCapsData, cbCaps);
  35. pasPerson->cpcCaps.share.gccID = g_asSession.gccID;
  36. }
  37. else
  38. {
  39. // When the person is created, it is zeroed out, so cpcCaps is too
  40. pCombinedCaps = (PPROTCOMBINEDCAPS)pCapsData;
  41. memcpy(&(pasPerson->cpcCaps.header), &(pCombinedCaps->header),
  42. sizeof(pCombinedCaps->header));
  43. //
  44. // Save the caps we care about in a simple easy structure
  45. //
  46. pCapsSrc = (LPBYTE)pCombinedCaps->capabilities;
  47. for (i = 0; i < pCombinedCaps->header.numCapabilities; i++)
  48. {
  49. sizeSrc = (UINT)(((PPROTCAPS)pCapsSrc)->header.capSize);
  50. switch (((PPROTCAPS)pCapsSrc)->header.capID)
  51. {
  52. case CAPS_ID_GENERAL:
  53. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.general);
  54. sizeDst = sizeof(PROTCAPS_GENERAL);
  55. break;
  56. case CAPS_ID_SCREEN:
  57. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.screen);
  58. sizeDst = sizeof(PROTCAPS_SCREEN);
  59. break;
  60. case CAPS_ID_ORDERS:
  61. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.orders);
  62. sizeDst = sizeof(PROTCAPS_ORDERS);
  63. break;
  64. case CAPS_ID_BITMAPCACHE:
  65. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.bitmaps);
  66. sizeDst = sizeof(PROTCAPS_BITMAPCACHE);
  67. break;
  68. case CAPS_ID_CM:
  69. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.cursor);
  70. sizeDst = sizeof(PROTCAPS_CM);
  71. break;
  72. case CAPS_ID_PM:
  73. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.palette);
  74. sizeDst = sizeof(PROTCAPS_PM);
  75. break;
  76. case CAPS_ID_SC:
  77. pCapsDst = (PPROTCAPS)&(pasPerson->cpcCaps.share);
  78. sizeDst = sizeof(PROTCAPS_SC);
  79. break;
  80. default:
  81. // Skip caps we don't recognize
  82. WARNING_OUT(("Ignoring unrecognized cap ID %d, size %d from person [%d]",
  83. ((PPROTCAPS)pCapsSrc)->header.capID, sizeSrc,
  84. pasPerson->mcsID));
  85. pCapsDst = NULL;
  86. break;
  87. }
  88. if (pCapsDst)
  89. {
  90. //
  91. // Only copy the amount given, but keep the size of the
  92. // structure in the header the right one.
  93. //
  94. CopyMemory(pCapsDst, pCapsSrc, min(sizeSrc, sizeDst));
  95. pCapsDst->header.capSize = (TSHR_UINT16)sizeDst;
  96. }
  97. pCapsSrc += sizeSrc;
  98. }
  99. }
  100. //
  101. // Check that we have the basic 7 caps
  102. //
  103. if (!pasPerson->cpcCaps.general.header.capID)
  104. {
  105. ERROR_OUT(("Bogus GENERAL caps for person [%d]", pasPerson->mcsID));
  106. DC_QUIT;
  107. }
  108. if (!pasPerson->cpcCaps.screen.header.capID)
  109. {
  110. ERROR_OUT(("Bogus SCREEN caps for person [%d]", pasPerson->mcsID));
  111. DC_QUIT;
  112. }
  113. if (!pasPerson->cpcCaps.orders.header.capID)
  114. {
  115. ERROR_OUT(("Bogus ORDERS caps for person [%d]", pasPerson->mcsID));
  116. DC_QUIT;
  117. }
  118. if (!pasPerson->cpcCaps.bitmaps.header.capID)
  119. {
  120. ERROR_OUT(("Bogus BITMAPS caps for person [%d]", pasPerson->mcsID));
  121. DC_QUIT;
  122. }
  123. if (!pasPerson->cpcCaps.cursor.header.capID)
  124. {
  125. ERROR_OUT(("Bogus CURSOR caps for person [%d]", pasPerson->mcsID));
  126. DC_QUIT;
  127. }
  128. if (!pasPerson->cpcCaps.palette.header.capID)
  129. {
  130. ERROR_OUT(("Bogus PALETTE caps for person [%d]", pasPerson->mcsID));
  131. DC_QUIT;
  132. }
  133. if (!pasPerson->cpcCaps.share.header.capID)
  134. {
  135. ERROR_OUT(("Bogus SHARE caps for person [%d]", pasPerson->mcsID));
  136. DC_QUIT;
  137. }
  138. // SUCCESS!
  139. rc = TRUE;
  140. DC_EXIT_POINT:
  141. DebugExitBOOL(ASShare::CPC_PartyJoiningShare, rc);
  142. return(rc);
  143. }
  144. //
  145. // CPC_UpdatedCaps()
  146. //
  147. void ASShare::CPC_UpdatedCaps(PPROTCAPS pCaps)
  148. {
  149. ASPerson * pasT;
  150. PCPCPACKET pCPCPacket;
  151. UINT packetSize;
  152. #ifdef _DEBUG
  153. UINT sentSize;
  154. #endif
  155. DebugEntry(ASShare::CPC_UpdatedCaps);
  156. //
  157. // Only allow screen size change!
  158. //
  159. ASSERT(pCaps->header.capID == CAPS_ID_SCREEN);
  160. //
  161. // Allocate a DT_CPC packet and send it to the remote site
  162. //
  163. packetSize = sizeof(CPCPACKET) + pCaps->header.capSize - sizeof(PROTCAPS);
  164. pCPCPacket = (PCPCPACKET)SC_AllocPkt(PROT_STR_MISC, g_s20BroadcastID, packetSize);
  165. if (!pCPCPacket)
  166. {
  167. WARNING_OUT(("Failed to alloc CPC packet, size %u", packetSize));
  168. DC_QUIT;
  169. }
  170. //
  171. // Fill in the capabilities that have changed
  172. //
  173. pCPCPacket->header.data.dataType = DT_CPC;
  174. memcpy(&pCPCPacket->caps, pCaps, pCaps->header.capSize);
  175. //
  176. // Compress and send the packet
  177. //
  178. #ifdef _DEBUG
  179. sentSize =
  180. #endif // _DEBUG
  181. DCS_CompressAndSendPacket(PROT_STR_MISC, g_s20BroadcastID,
  182. &(pCPCPacket->header), packetSize);
  183. TRACE_OUT(("CPC packet size: %08d, sent %08d", packetSize, sentSize));
  184. // Handle change
  185. CPCCapabilitiesChange(m_pasLocal, pCaps);
  186. DC_EXIT_POINT:
  187. DebugExitVOID(ASShare::CPC_UpdatedCaps);
  188. }
  189. //
  190. // CPC_ReceivedPacket()
  191. //
  192. void ASShare::CPC_ReceivedPacket
  193. (
  194. ASPerson * pasPerson,
  195. PS20DATAPACKET pPacket
  196. )
  197. {
  198. PCPCPACKET pCPCPacket;
  199. DebugEntry(ASShare::CPC_ReceivedPacket);
  200. ValidatePerson(pasPerson);
  201. pCPCPacket = (PCPCPACKET)pPacket;
  202. //
  203. // Capabilities have changed - update the local copy and inform all
  204. // components
  205. //
  206. TRACE_OUT(( "Capabilities changing for person [%d]", pasPerson->mcsID));
  207. TRACE_OUT(("Size of new capabilities 0x%08x", pCPCPacket->caps.header.capSize));
  208. CPCCapabilitiesChange(pasPerson, &(pCPCPacket->caps));
  209. DebugExitVOID(ASShare::CPC_ReceivedPacket);
  210. }
  211. //
  212. // CPCCapabilitiesChange()
  213. //
  214. BOOL ASShare::CPCCapabilitiesChange
  215. (
  216. ASPerson * pasPerson,
  217. PPROTCAPS pCaps
  218. )
  219. {
  220. BOOL changed;
  221. DebugEntry(ASShare::CPCCapabilitiesChange);
  222. ValidatePerson(pasPerson);
  223. //
  224. // Get pointer to the caps we're changing (SHOULD ONLY BE SCREEN!)
  225. //
  226. if (pCaps->header.capID != CAPS_ID_SCREEN)
  227. {
  228. ERROR_OUT(("Received caps change from [%d] for cap ID %d we can't handle",
  229. pasPerson->mcsID, pCaps->header.capID));
  230. changed = FALSE;
  231. }
  232. else
  233. {
  234. CopyMemory(&(pasPerson->cpcCaps.screen), pCaps,
  235. min(sizeof(PROTCAPS_SCREEN), pCaps->header.capSize));
  236. pasPerson->cpcCaps.screen.header.capSize = sizeof(PROTCAPS_SCREEN);
  237. USR_ScreenChanged(pasPerson);
  238. changed = TRUE;
  239. }
  240. DebugExitBOOL(ASShare::CPCCapabilitiesChange, changed);
  241. return(changed);
  242. }
  243.