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.

314 lines
8.2 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. // Only send change if all support it
  162. //
  163. for (pasT = m_pasLocal; pasT != NULL; pasT = pasT->pasNext)
  164. {
  165. if (pasT->cpcCaps.general.supportsCapsUpdate != CAPS_SUPPORTED)
  166. {
  167. WARNING_OUT(("Not sending caps update; person [%d] doesn't support it",
  168. pasT->mcsID));
  169. DC_QUIT;
  170. }
  171. }
  172. // Everybody supports a caps change. Try to send the changed packet
  173. //
  174. // Allocate a DT_CPC packet and send it to the remote site
  175. //
  176. packetSize = sizeof(CPCPACKET) + pCaps->header.capSize - sizeof(PROTCAPS);
  177. pCPCPacket = (PCPCPACKET)SC_AllocPkt(PROT_STR_MISC, g_s20BroadcastID, packetSize);
  178. if (!pCPCPacket)
  179. {
  180. WARNING_OUT(("Failed to alloc CPC packet, size %u", packetSize));
  181. DC_QUIT;
  182. }
  183. //
  184. // Fill in the capabilities that have changed
  185. //
  186. pCPCPacket->header.data.dataType = DT_CPC;
  187. memcpy(&pCPCPacket->caps, pCaps, pCaps->header.capSize);
  188. //
  189. // Compress and send the packet
  190. //
  191. #ifdef _DEBUG
  192. sentSize =
  193. #endif // _DEBUG
  194. DCS_CompressAndSendPacket(PROT_STR_MISC, g_s20BroadcastID,
  195. &(pCPCPacket->header), packetSize);
  196. TRACE_OUT(("CPC packet size: %08d, sent %08d", packetSize, sentSize));
  197. // Handle change
  198. CPCCapabilitiesChange(m_pasLocal, pCaps);
  199. DC_EXIT_POINT:
  200. DebugExitVOID(ASShare::CPC_UpdatedCaps);
  201. }
  202. //
  203. // CPC_ReceivedPacket()
  204. //
  205. void ASShare::CPC_ReceivedPacket
  206. (
  207. ASPerson * pasPerson,
  208. PS20DATAPACKET pPacket
  209. )
  210. {
  211. PCPCPACKET pCPCPacket;
  212. DebugEntry(ASShare::CPC_ReceivedPacket);
  213. ValidatePerson(pasPerson);
  214. pCPCPacket = (PCPCPACKET)pPacket;
  215. //
  216. // Capabilities have changed - update the local copy and inform all
  217. // components
  218. //
  219. TRACE_OUT(( "Capabilities changing for person [%d]", pasPerson->mcsID));
  220. TRACE_OUT(("Size of new capabilities 0x%08x", pCPCPacket->caps.header.capSize));
  221. CPCCapabilitiesChange(pasPerson, &(pCPCPacket->caps));
  222. DebugExitVOID(ASShare::CPC_ReceivedPacket);
  223. }
  224. //
  225. // CPCCapabilitiesChange()
  226. //
  227. BOOL ASShare::CPCCapabilitiesChange
  228. (
  229. ASPerson * pasPerson,
  230. PPROTCAPS pCaps
  231. )
  232. {
  233. BOOL changed;
  234. DebugEntry(ASShare::CPCCapabilitiesChange);
  235. ValidatePerson(pasPerson);
  236. //
  237. // Get pointer to the caps we're changing (SHOULD ONLY BE SCREEN!)
  238. //
  239. if (pCaps->header.capID != CAPS_ID_SCREEN)
  240. {
  241. ERROR_OUT(("Received caps change from [%d] for cap ID %d we can't handle",
  242. pasPerson->mcsID, pCaps->header.capID));
  243. changed = FALSE;
  244. }
  245. else
  246. {
  247. CopyMemory(&(pasPerson->cpcCaps.screen), pCaps,
  248. min(sizeof(PROTCAPS_SCREEN), pCaps->header.capSize));
  249. pasPerson->cpcCaps.screen.header.capSize = sizeof(PROTCAPS_SCREEN);
  250. USR_ScreenChanged(pasPerson);
  251. changed = TRUE;
  252. }
  253. DebugExitBOOL(ASShare::CPCCapabilitiesChange, changed);
  254. return(changed);
  255. }
  256.