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.

473 lines
14 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999, 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: fwdserver.cpp
  6. * Content: Implements the forwarding server portion of the server class
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 11/01/2000 rodtoll Split out from dvsereng.cpp
  12. *
  13. ***************************************************************************/
  14. #include "dxvoicepch.h"
  15. #undef DPF_MODNAME
  16. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_CreatePlayer"
  17. HRESULT CDirectVoiceServerEngine::Send_CreatePlayer( DVID dvidTarget, const CVoicePlayer *pPlayer )
  18. {
  19. PDVPROTOCOLMSG_PLAYERJOIN pdvPlayerJoin;
  20. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  21. PVOID pvSendContext;
  22. HRESULT hr;
  23. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_PLAYERJOIN ), &pvSendContext );
  24. if( pBufferDesc == NULL )
  25. {
  26. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  27. return DVERR_OUTOFMEMORY;
  28. }
  29. pdvPlayerJoin = (PDVPROTOCOLMSG_PLAYERJOIN) pBufferDesc->pBufferData;
  30. pdvPlayerJoin->dwType = DVMSGID_CREATEVOICEPLAYER;
  31. pdvPlayerJoin->dvidID = pPlayer->GetPlayerID();
  32. pdvPlayerJoin->dwFlags = pPlayer->GetTransportFlags();
  33. pdvPlayerJoin->dwHostOrderID = pPlayer->GetHostOrder();
  34. hr = m_lpSessionTransport->SendToIDS( &dvidTarget, 1, pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  35. if( hr == DVERR_PENDING )
  36. {
  37. hr = DV_OK;
  38. }
  39. else if( FAILED( hr ) )
  40. {
  41. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending create player to 0x%x hr=0x%x", dvidTarget, hr );
  42. }
  43. return hr;
  44. }
  45. #undef DPF_MODNAME
  46. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_ConnectRefuse"
  47. HRESULT CDirectVoiceServerEngine::Send_ConnectRefuse( DVID dvidID, HRESULT hrReason )
  48. {
  49. PDVPROTOCOLMSG_CONNECTREFUSE pdvConnectRefuse;
  50. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  51. PVOID pvSendContext;
  52. HRESULT hr;
  53. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_CONNECTREFUSE ), &pvSendContext );
  54. if( pBufferDesc == NULL )
  55. {
  56. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  57. return DVERR_OUTOFMEMORY;
  58. }
  59. pdvConnectRefuse = (PDVPROTOCOLMSG_CONNECTREFUSE) pBufferDesc->pBufferData;
  60. pdvConnectRefuse->dwType = DVMSGID_CONNECTREFUSE;
  61. pdvConnectRefuse->hresResult = hrReason;
  62. pdvConnectRefuse->ucVersionMajor = DVPROTOCOL_VERSION_MAJOR;
  63. pdvConnectRefuse->ucVersionMinor = DVPROTOCOL_VERSION_MINOR;
  64. pdvConnectRefuse->dwVersionBuild = DVPROTOCOL_VERSION_BUILD;
  65. hr = m_lpSessionTransport->SendToIDS( &dvidID, 1, pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  66. if( hr == DVERR_PENDING )
  67. {
  68. hr = DV_OK;
  69. }
  70. else if( FAILED( hr ) )
  71. {
  72. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending disconnect confirm migrated to all hr=0x%x", hr );
  73. }
  74. return hr;
  75. }
  76. #undef DPF_MODNAME
  77. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_DisconnectConfirm"
  78. HRESULT CDirectVoiceServerEngine::Send_DisconnectConfirm( DVID dvidID, HRESULT hrReason )
  79. {
  80. PDVPROTOCOLMSG_DISCONNECT pdvDisconnectConfirm;
  81. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  82. PVOID pvSendContext;
  83. HRESULT hr;
  84. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_DISCONNECT ), &pvSendContext );
  85. if( pBufferDesc == NULL )
  86. {
  87. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  88. return DVERR_OUTOFMEMORY;
  89. }
  90. pdvDisconnectConfirm = (PDVPROTOCOLMSG_DISCONNECT) pBufferDesc->pBufferData;
  91. pdvDisconnectConfirm->dwType = DVMSGID_DISCONNECTCONFIRM;
  92. pdvDisconnectConfirm->hresDisconnect = hrReason;
  93. hr = m_lpSessionTransport->SendToIDS( &dvidID, 1, pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  94. if( hr == DVERR_PENDING )
  95. {
  96. hr = DV_OK;
  97. }
  98. else if( FAILED( hr ) )
  99. {
  100. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending disconnect confirm migrated to all hr=0x%x", hr );
  101. }
  102. return hr;
  103. }
  104. #undef DPF_MODNAME
  105. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_ConnectAccept"
  106. HRESULT CDirectVoiceServerEngine::Send_ConnectAccept( DVID dvidID )
  107. {
  108. PDVPROTOCOLMSG_CONNECTACCEPT pdvConnectAccept;
  109. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  110. PVOID pvSendContext;
  111. HRESULT hr;
  112. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_CONNECTACCEPT ), &pvSendContext );
  113. if( pBufferDesc == NULL )
  114. {
  115. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  116. return DVERR_OUTOFMEMORY;
  117. }
  118. pdvConnectAccept = (PDVPROTOCOLMSG_CONNECTACCEPT) pBufferDesc->pBufferData;
  119. pdvConnectAccept->dwType = DVMSGID_CONNECTACCEPT;
  120. pdvConnectAccept->dwSessionFlags = m_dvSessionDesc.dwFlags;
  121. pdvConnectAccept->dwSessionType = m_dvSessionDesc.dwSessionType;
  122. pdvConnectAccept->ucVersionMajor = DVPROTOCOL_VERSION_MAJOR;
  123. pdvConnectAccept->ucVersionMinor = DVPROTOCOL_VERSION_MINOR;
  124. pdvConnectAccept->dwVersionBuild = DVPROTOCOL_VERSION_BUILD;
  125. pdvConnectAccept->guidCT = m_dvSessionDesc.guidCT;
  126. hr = m_lpSessionTransport->SendToIDS( &dvidID, 1, pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  127. if( hr == DVERR_PENDING )
  128. {
  129. hr = DV_OK;
  130. }
  131. else if( FAILED( hr ) )
  132. {
  133. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending connect accept to player hr=0x%x", hr );
  134. }
  135. return hr;
  136. }
  137. #undef DPF_MODNAME
  138. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_DeletePlayer"
  139. HRESULT CDirectVoiceServerEngine::Send_DeletePlayer( DVID dvidID )
  140. {
  141. PDVPROTOCOLMSG_PLAYERQUIT pdvPlayerQuit;
  142. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  143. PVOID pvSendContext;
  144. HRESULT hr;
  145. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_PLAYERQUIT ), &pvSendContext );
  146. if( pBufferDesc == NULL )
  147. {
  148. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  149. return DVERR_OUTOFMEMORY;
  150. }
  151. pdvPlayerQuit = (PDVPROTOCOLMSG_PLAYERQUIT) pBufferDesc->pBufferData;
  152. pdvPlayerQuit->dwType = DVMSGID_DELETEVOICEPLAYER;
  153. pdvPlayerQuit->dvidID = dvidID;
  154. hr = m_lpSessionTransport->SendToAll( pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  155. if( hr == DVERR_PENDING )
  156. {
  157. hr = DV_OK;
  158. }
  159. else if( FAILED( hr ) )
  160. {
  161. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending delete player migrated to all hr=0x%x", hr );
  162. ReturnTransmitBuffer( pvSendContext );
  163. }
  164. return hr;
  165. }
  166. #undef DPF_MODNAME
  167. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_SessionLost"
  168. HRESULT CDirectVoiceServerEngine::Send_SessionLost( HRESULT hrReason )
  169. {
  170. PDVPROTOCOLMSG_SESSIONLOST pdvSessionLost;
  171. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  172. PVOID pvSendContext;
  173. HRESULT hr;
  174. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_SESSIONLOST ), &pvSendContext );
  175. if( pBufferDesc == NULL )
  176. {
  177. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  178. return DVERR_OUTOFMEMORY;
  179. }
  180. pdvSessionLost = (PDVPROTOCOLMSG_SESSIONLOST) pBufferDesc->pBufferData;
  181. pdvSessionLost->dwType = DVMSGID_SESSIONLOST;
  182. pdvSessionLost->hresReason = hrReason;
  183. hr = m_lpSessionTransport->SendToAll( pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED | DVTRANSPORT_SEND_SYNC );
  184. if( FAILED( hr ) )
  185. {
  186. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending session lost to all hr=0x%x", hr );
  187. }
  188. ReturnTransmitBuffer( pvSendContext );
  189. return hr;
  190. }
  191. #undef DPF_MODNAME
  192. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_HostMigrateLeave"
  193. HRESULT CDirectVoiceServerEngine::Send_HostMigrateLeave( )
  194. {
  195. PDVPROTOCOLMSG_HOSTMIGRATELEAVE pdvHostMigrateLeave;
  196. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  197. PVOID pvSendContext;
  198. HRESULT hr;
  199. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_HOSTMIGRATELEAVE ), &pvSendContext );
  200. if( pBufferDesc == NULL )
  201. {
  202. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  203. return DVERR_OUTOFMEMORY;
  204. }
  205. pdvHostMigrateLeave = (PDVPROTOCOLMSG_HOSTMIGRATELEAVE) pBufferDesc->pBufferData;
  206. pdvHostMigrateLeave->dwType = DVMSGID_HOSTMIGRATELEAVE;
  207. // Send this message with sync. Sync messages do not generate callbacks
  208. //
  209. hr = m_lpSessionTransport->SendToAll( pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED | DVTRANSPORT_SEND_SYNC );
  210. if( FAILED( hr ) )
  211. {
  212. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending host migrated to all hr=0x%x", hr );
  213. }
  214. ReturnTransmitBuffer( pvSendContext );
  215. return hr;
  216. }
  217. #undef DPF_MODNAME
  218. #define DPF_MODNAME "CDirectVoiceServerEngine::Send_HostMigrated"
  219. HRESULT CDirectVoiceServerEngine::Send_HostMigrated()
  220. {
  221. PDVPROTOCOLMSG_HOSTMIGRATED pvMigrated;
  222. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  223. PVOID pvSendContext;
  224. HRESULT hr;
  225. pBufferDesc = GetTransmitBuffer( sizeof( DVPROTOCOLMSG_HOSTMIGRATED ), &pvSendContext );
  226. if( pBufferDesc == NULL )
  227. {
  228. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc error" );
  229. return DVERR_OUTOFMEMORY;
  230. }
  231. pvMigrated = (PDVPROTOCOLMSG_HOSTMIGRATED) pBufferDesc->pBufferData;
  232. pvMigrated->dwType = DVMSGID_HOSTMIGRATED;
  233. hr = m_lpSessionTransport->SendToAll( pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  234. if( hr == DVERR_PENDING )
  235. {
  236. hr = DV_OK;
  237. }
  238. else if( FAILED( hr ) )
  239. {
  240. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error sending host migrated to all hr=0x%x", hr );
  241. ReturnTransmitBuffer( pvSendContext );
  242. }
  243. return hr;
  244. }
  245. BOOL CDirectVoiceServerEngine::CheckProtocolCompatible( BYTE ucMajor, BYTE ucMinor, DWORD dwBuild )
  246. {
  247. /*
  248. if( ucMajor != DVPROTOCOL_VERSION_MAJOR ||
  249. ucMinor != DVPROTOCOL_VERSION_MINOR ||
  250. dwBuild != DVPROTOCOL_VERSION_BUILD )
  251. {
  252. return FALSE;
  253. }
  254. else
  255. {
  256. return TRUE;
  257. }*/
  258. return TRUE;
  259. }
  260. #undef DPF_MODNAME
  261. #define DPF_MODNAME "CDirectVoiceServerEngine::SendPlayerList"
  262. //
  263. // SendPlayerList
  264. //
  265. // This function sends a bunch of DVMSGID_PLAYERLIST messages to the
  266. // client containing the list of current players.
  267. //
  268. // This will send multiple structues if the number
  269. //
  270. HRESULT CDirectVoiceServerEngine::SendPlayerList( DVID dvidSource, DWORD dwHostOrderID )
  271. {
  272. BOOL bContinueEnum = FALSE;
  273. CVoicePlayer *lpPlayer;
  274. CBilink *pblSearch;
  275. HRESULT hr = DV_OK;
  276. BOOL fAtLeastOneSent = FALSE;
  277. DWORD dwCurrentBufferLoc;
  278. DWORD dwNumInCurrentPacket;
  279. PDVTRANSPORT_BUFFERDESC pBufferDesc;
  280. PDVPROTOCOLMSG_PLAYERLIST lpdvPlayerList;
  281. DVPROTOCOLMSG_PLAYERLIST_ENTRY *pdvPlayerEntries;
  282. PVOID pvSendContext;
  283. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "Building player list" );
  284. pBufferDesc = GetTransmitBuffer(DVPROTOCOL_PLAYERLIST_MAXSIZE, &pvSendContext);
  285. if( pBufferDesc == NULL )
  286. {
  287. DPFX(DPFPREP, DVF_ERRORLEVEL, "Out of memory!" );
  288. return DVERR_OUTOFMEMORY;
  289. }
  290. lpdvPlayerList = (PDVPROTOCOLMSG_PLAYERLIST) pBufferDesc->pBufferData;
  291. pdvPlayerEntries = (DVPROTOCOLMSG_PLAYERLIST_ENTRY *) &lpdvPlayerList[1];
  292. lpdvPlayerList->dwType = DVMSGID_PLAYERLIST;
  293. lpdvPlayerList->dwHostOrderID = dwHostOrderID;
  294. dwNumInCurrentPacket = 0;
  295. dwCurrentBufferLoc = sizeof(DVPROTOCOLMSG_PLAYERLIST);
  296. DNEnterCriticalSection( &m_csPlayerActiveList );
  297. pblSearch = m_blPlayerActiveList.GetNext();
  298. while( pblSearch != &m_blPlayerActiveList )
  299. {
  300. lpPlayer = CONTAINING_RECORD( pblSearch, CVoicePlayer, m_blNotifyList );
  301. // We need to split the packet, start a new packet, transmit this one.
  302. if( (dwCurrentBufferLoc+sizeof(DVPROTOCOLMSG_PLAYERLIST_ENTRY)) > DVPROTOCOL_PLAYERLIST_MAXSIZE )
  303. {
  304. // Wrap up current packet and transmit
  305. lpdvPlayerList->dwNumEntries = dwNumInCurrentPacket;
  306. pBufferDesc->dwBufferSize = dwCurrentBufferLoc;
  307. hr = m_lpSessionTransport->SendToIDS( &dvidSource, 1,pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  308. if( hr == DVERR_PENDING )
  309. {
  310. hr = DV_OK;
  311. }
  312. else if( FAILED( hr ) )
  313. {
  314. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Error on internal send hr=0x%x (Didn't get playerlist)", hr );
  315. return hr;
  316. }
  317. // Reset for further players
  318. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "Transmitting playerlist chunk %d players", dwNumInCurrentPacket );
  319. pBufferDesc = GetTransmitBuffer(DVPROTOCOL_PLAYERLIST_MAXSIZE, &pvSendContext);
  320. if( pBufferDesc == NULL )
  321. {
  322. DPFX(DPFPREP, DVF_ERRORLEVEL, "Out of memory!" );
  323. return DVERR_OUTOFMEMORY;
  324. }
  325. lpdvPlayerList = (PDVPROTOCOLMSG_PLAYERLIST) pBufferDesc->pBufferData;
  326. pdvPlayerEntries = (DVPROTOCOLMSG_PLAYERLIST_ENTRY *) &lpdvPlayerList[1];
  327. lpdvPlayerList->dwType = DVMSGID_PLAYERLIST;
  328. lpdvPlayerList->dwHostOrderID = dwHostOrderID;
  329. dwCurrentBufferLoc = sizeof(DVPROTOCOLMSG_PLAYERLIST);
  330. dwNumInCurrentPacket = 0;
  331. fAtLeastOneSent = TRUE;
  332. }
  333. pdvPlayerEntries[dwNumInCurrentPacket].dvidID = lpPlayer->GetPlayerID();
  334. pdvPlayerEntries[dwNumInCurrentPacket].dwPlayerFlags = lpPlayer->GetTransportFlags();
  335. pdvPlayerEntries[dwNumInCurrentPacket].dwHostOrderID = lpPlayer->GetHostOrder();
  336. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "PlayerList: Adding player ID 0x%x", lpPlayer->GetPlayerID() );
  337. dwNumInCurrentPacket++;
  338. dwCurrentBufferLoc += sizeof(DVPROTOCOLMSG_PLAYERLIST_ENTRY);
  339. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "PlayerList: Got next player" );
  340. pblSearch = pblSearch->GetNext();
  341. }
  342. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "PlayerList: Build Complete" );
  343. DNLeaveCriticalSection( &m_csPlayerActiveList );
  344. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "PlayerList: Total of %d entries", dwNumInCurrentPacket );
  345. // Remaining entries to be sent
  346. //
  347. // (Or empty packet just so user gets their ID)
  348. //
  349. if( !fAtLeastOneSent )
  350. {
  351. // Wrap up current packet and transmit
  352. lpdvPlayerList->dwNumEntries = dwNumInCurrentPacket;
  353. pBufferDesc->dwBufferSize = dwCurrentBufferLoc;
  354. hr = m_lpSessionTransport->SendToIDS( &dvidSource, 1, pBufferDesc, pvSendContext, DVTRANSPORT_SEND_GUARANTEED );
  355. if( hr == DVERR_PENDING || hr == DV_OK )
  356. {
  357. DPFX(DPFPREP, DVF_PLAYERMANAGE_DEBUG_LEVEL, "Playerlist sent" );
  358. }
  359. else
  360. {
  361. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error on internal send hr=0x%x (Didn't get playerlist)", hr );
  362. }
  363. }
  364. return hr;
  365. }