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.

1962 lines
50 KiB

  1. #include "stdafx.h"
  2. #include "Direct.h"
  3. #include "dms.h"
  4. #include "dplayaddressobj.h"
  5. #include "DPlayPeerObj.h"
  6. extern void *g_dxj_DirectPlayPeer;
  7. extern void *g_dxj_DirectPlayAddress;
  8. extern BSTR GUIDtoBSTR(LPGUID);
  9. extern HRESULT DPLAYBSTRtoGUID(LPGUID,BSTR);
  10. extern BOOL IsEmptyString(BSTR szString);
  11. #define SAFE_DELETE(p) { if(p) { delete (p); p=NULL; } }
  12. #define SAFE_RELEASE(p) { __try { if(p) { int i = 0; i = (p)->Release(); DPF1(1,"--DirectPlayPeer SafeRelease (RefCount = %d)\n",i); if (!i) { (p)=NULL;}} } __except(EXCEPTION_EXECUTE_HANDLER) { (p) = NULL;} }
  13. HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext,
  14. DWORD dwMessageId,
  15. PVOID pMsgBuffer );
  16. DWORD WINAPI ClosePeerThreadProc(void* lpParam);
  17. ///////////////////////////////////////////////////////////////////
  18. // InternalAddRef
  19. ///////////////////////////////////////////////////////////////////
  20. DWORD C_dxj_DirectPlayPeerObject::InternalAddRef(){
  21. DWORD i;
  22. i=CComObjectRoot::InternalAddRef();
  23. DPF1(1,"------ DXVB: DirectPlayPeer8 AddRef %d \n",i);
  24. return i;
  25. }
  26. ///////////////////////////////////////////////////////////////////
  27. // InternalRelease
  28. ///////////////////////////////////////////////////////////////////
  29. DWORD C_dxj_DirectPlayPeerObject::InternalRelease(){
  30. DWORD i;
  31. i=CComObjectRoot::InternalRelease();
  32. DPF1(1,"------ DXVB: DirectPlayPeer8 Release %d \n",i);
  33. return i;
  34. }
  35. ///////////////////////////////////////////////////////////////////
  36. // C_dxj_DirectPlayPeerObject
  37. ///////////////////////////////////////////////////////////////////
  38. C_dxj_DirectPlayPeerObject::C_dxj_DirectPlayPeerObject(){
  39. DPF(1,"------ DXVB: Constructor Creation DirectPlayPeer8 Object\n ");
  40. m__dxj_DirectPlayPeer = NULL;
  41. m_SPInfo = NULL;
  42. m_dwSPCount = 0;
  43. m_ClientsGroups = NULL;
  44. m_GroupMembers = NULL;
  45. m_dwGroupID = 0;
  46. m_dwClientCount = 0;
  47. m_dwGroupMemberCount = 0;
  48. m_fInit = FALSE;
  49. m_pUserData = NULL;
  50. m_fHandleEvents = FALSE;
  51. m_dwUserDataSize = 0;
  52. m_pReplyData = NULL;
  53. m_dwReplyDataSize = 0;
  54. m_pEventStream=NULL;
  55. m_dwMsgCount = 0;
  56. }
  57. ///////////////////////////////////////////////////////////////////
  58. // ~C_dxj_DirectPlayPeerObject
  59. ///////////////////////////////////////////////////////////////////
  60. C_dxj_DirectPlayPeerObject::~C_dxj_DirectPlayPeerObject()
  61. {
  62. DPF(1,"------ DXVB: Entering ~C_dxj_DirectPlayPeerObject destructor \n");
  63. //We still have messages to process get rid of them
  64. m_fHandleEvents = FALSE;
  65. FlushBuffer(0);
  66. SAFE_RELEASE(m__dxj_DirectPlayPeer);
  67. SAFE_RELEASE(m_pEventStream);
  68. SAFE_DELETE(m_SPInfo);
  69. SAFE_DELETE(m_ClientsGroups);
  70. SAFE_DELETE(m_GroupMembers);
  71. SAFE_DELETE(m_pReplyData);
  72. }
  73. HRESULT C_dxj_DirectPlayPeerObject::InternalGetObject(IUnknown **pUnk){
  74. *pUnk=(IUnknown*)m__dxj_DirectPlayPeer;
  75. return S_OK;
  76. }
  77. HRESULT C_dxj_DirectPlayPeerObject::InternalSetObject(IUnknown *pUnk){
  78. m__dxj_DirectPlayPeer=(IDirectPlay8Peer*)pUnk;
  79. return S_OK;
  80. }
  81. HRESULT C_dxj_DirectPlayPeerObject::CancelAsyncOperation(long lAsyncHandle, long lFlags)
  82. {
  83. HRESULT hr;
  84. __try {
  85. DPF(1,"-----Entering (DplayPeer) CancelAsyncOp call...\n");
  86. if (FAILED( hr= m__dxj_DirectPlayPeer->CancelAsyncOperation((DPNHANDLE) lAsyncHandle, (DWORD) lFlags) ) )
  87. return hr;
  88. }
  89. __except(EXCEPTION_EXECUTE_HANDLER)
  90. {
  91. return E_FAIL;
  92. }
  93. return S_OK;
  94. }
  95. HRESULT C_dxj_DirectPlayPeerObject::GetApplicationDesc(long lFlags, DPN_APPLICATION_DESC_CDESC *ret)
  96. {
  97. HRESULT hr;
  98. DWORD dwSize = 0;
  99. DPN_APPLICATION_DESC *desc = NULL;
  100. __try {
  101. DPF(1,"-----Entering (DplayPeer) GetAppDesc call...\n");
  102. //First get the size
  103. hr = m__dxj_DirectPlayPeer->GetApplicationDesc(NULL, &dwSize, (DWORD) lFlags);
  104. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  105. return hr;
  106. desc = (DPN_APPLICATION_DESC*) new BYTE[dwSize];
  107. if (!desc)
  108. return E_OUTOFMEMORY;
  109. ZeroMemory(desc, dwSize);
  110. desc->dwSize = sizeof(DPN_APPLICATION_DESC);
  111. if (FAILED( hr= m__dxj_DirectPlayPeer->GetApplicationDesc(desc, &dwSize, (DWORD) lFlags) ) )
  112. return hr;
  113. // Now return the vals
  114. ret->lSize = dwSize;
  115. ret->lFlags = desc->dwFlags;
  116. ret->guidInstance = GUIDtoBSTR(&desc->guidInstance);
  117. ret->guidApplication = GUIDtoBSTR(&desc->guidApplication);
  118. ret->lMaxPlayers = desc->dwMaxPlayers;
  119. ret->lCurrentPlayers = desc->dwCurrentPlayers;
  120. ret->SessionName = SysAllocString(desc->pwszSessionName);
  121. ret->Password = SysAllocString(desc->pwszPassword);
  122. }
  123. __except(EXCEPTION_EXECUTE_HANDLER)
  124. {
  125. return E_FAIL;
  126. }
  127. return S_OK;
  128. }
  129. HRESULT C_dxj_DirectPlayPeerObject::SetApplicationDesc(DPN_APPLICATION_DESC_CDESC *AppDesc, long lFlags)
  130. {
  131. HRESULT hr;
  132. DPN_APPLICATION_DESC *desc = NULL;
  133. GUID guidApp;
  134. GUID guidInst;
  135. WCHAR wszSessionName[MAX_PATH];
  136. WCHAR wszPassword[MAX_PATH];
  137. __try {
  138. DPF(1,"-----Entering (DplayPeer) SetAppDesc call...\n");
  139. desc = (DPN_APPLICATION_DESC*) new BYTE[AppDesc->lSize];
  140. if (!desc)
  141. return E_OUTOFMEMORY;
  142. ZeroMemory(desc, AppDesc->lSize);
  143. // Set up our Desc
  144. desc->dwSize = sizeof(DPN_APPLICATION_DESC);
  145. if (!IsEmptyString(AppDesc->SessionName))
  146. {
  147. wcscpy(wszSessionName,AppDesc->SessionName);
  148. desc->pwszSessionName = wszSessionName;
  149. }
  150. if (!IsEmptyString(AppDesc->Password))
  151. {
  152. wcscpy(wszPassword,AppDesc->Password);
  153. desc->pwszPassword = wszPassword;
  154. }
  155. desc->dwFlags = AppDesc->lFlags;
  156. desc->dwMaxPlayers = AppDesc->lMaxPlayers;
  157. desc->dwCurrentPlayers = AppDesc->lCurrentPlayers;
  158. if (FAILED(hr = DPLAYBSTRtoGUID(&guidApp, AppDesc->guidApplication) ) )
  159. return hr;
  160. desc->guidApplication = guidApp;
  161. if (FAILED(hr = DPLAYBSTRtoGUID(&guidInst, AppDesc->guidInstance) ) )
  162. return hr;
  163. desc->guidInstance = guidInst;
  164. if (FAILED( hr= m__dxj_DirectPlayPeer->SetApplicationDesc(desc, (DWORD) lFlags) ) )
  165. return hr;
  166. SAFE_DELETE(desc);
  167. }
  168. __except(EXCEPTION_EXECUTE_HANDLER)
  169. {
  170. return E_FAIL;
  171. }
  172. return S_OK;
  173. }
  174. HRESULT C_dxj_DirectPlayPeerObject::Close(long lFlags)
  175. {
  176. HRESULT hr;
  177. BOOL bGotMsg = FALSE;
  178. BOOL bWait = FALSE;
  179. DWORD dwObj = 0;
  180. int i=0;
  181. MSG msg;
  182. __try {
  183. DPF(1,"-----Entering (DplayPeer) Close call...\n");
  184. FlushBuffer(0);
  185. HANDLE hThread = NULL;
  186. DWORD dwThread = 0;
  187. hThread = CreateThread(NULL, 0, &ClosePeerThreadProc, this->m__dxj_DirectPlayPeer, 0, &dwThread);
  188. msg.message = WM_NULL;
  189. while ((WM_QUIT != msg.message) && (!bWait))
  190. {
  191. bGotMsg = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
  192. i++;
  193. if ((!bGotMsg) || (i>10))
  194. {
  195. dwObj = WaitForSingleObject(hThread, 10);
  196. bWait = (dwObj == WAIT_OBJECT_0);
  197. i = 0;
  198. }
  199. if (bGotMsg)
  200. {
  201. TranslateMessage( &msg );
  202. DispatchMessage( &msg );
  203. }
  204. bGotMsg = FALSE;
  205. }
  206. }
  207. __except(EXCEPTION_EXECUTE_HANDLER)
  208. {
  209. return E_FAIL;
  210. }
  211. DPF(1,"-----Leaving (DplayPeer) Close call...\n");
  212. return S_OK;
  213. }
  214. HRESULT C_dxj_DirectPlayPeerObject::GetCaps(long lFlags, DPNCAPS_CDESC *ret)
  215. {
  216. HRESULT hr;
  217. __try {
  218. DPF(1,"-----Entering (DplayPeer) GetCaps call...\n");
  219. ret->lSize = sizeof(DPN_CAPS);
  220. if (FAILED (hr=m__dxj_DirectPlayPeer->GetCaps( (DPN_CAPS*) ret, (DWORD) lFlags) ) )
  221. return hr;
  222. }
  223. __except(EXCEPTION_EXECUTE_HANDLER)
  224. {
  225. return E_FAIL;
  226. }
  227. return S_OK;
  228. }
  229. HRESULT C_dxj_DirectPlayPeerObject::SetCaps(DPNCAPS_CDESC *Caps, long lFlags)
  230. {
  231. HRESULT hr;
  232. __try {
  233. DPF(1,"-----Entering (DplayPeer) SetCaps call...\n");
  234. if (FAILED( hr = m__dxj_DirectPlayPeer->SetCaps((DPN_CAPS*)Caps, (DWORD)lFlags)))
  235. return hr;
  236. }
  237. __except(EXCEPTION_EXECUTE_HANDLER)
  238. {
  239. return E_FAIL;
  240. }
  241. return S_OK;
  242. }
  243. HRESULT C_dxj_DirectPlayPeerObject::DestroyGroup(long idGroup,long lFlags, long *hAsyncHandle)
  244. {
  245. HRESULT hr;
  246. DPNHANDLE *dpAsync = NULL;
  247. __try {
  248. if (!(lFlags & DPNSEND_SYNC))
  249. {
  250. dpAsync = new DPNHANDLE;
  251. if (!dpAsync)
  252. return E_OUTOFMEMORY;
  253. }
  254. DPF(1,"-----Entering (DplayPeer) DestroyGroup call...\n");
  255. hr= m__dxj_DirectPlayPeer->DestroyGroup((DPNID) idGroup, NULL, dpAsync, (DWORD) lFlags);
  256. if (dpAsync)
  257. {
  258. *hAsyncHandle = (long)*dpAsync;
  259. SAFE_DELETE(dpAsync);
  260. }
  261. if ((hr != DPNERR_PENDING) && FAILED(hr))
  262. return hr;
  263. }
  264. __except(EXCEPTION_EXECUTE_HANDLER)
  265. {
  266. return E_FAIL;
  267. }
  268. return S_OK;
  269. }
  270. HRESULT C_dxj_DirectPlayPeerObject::RemovePlayerFromGroup(long idGroup, long idClient,long lFlags, long *hAsyncHandle)
  271. {
  272. HRESULT hr;
  273. DPNHANDLE *dpAsync = NULL;
  274. __try {
  275. if (!(lFlags & DPNSEND_SYNC))
  276. {
  277. dpAsync = new DPNHANDLE;
  278. if (!dpAsync)
  279. return E_OUTOFMEMORY;
  280. }
  281. DPF(1,"-----Entering (DplayPeer) RemovePlayerFromGroup call...\n");
  282. hr = m__dxj_DirectPlayPeer->RemovePlayerFromGroup( (DPNID) idGroup,
  283. (DPNID) idClient, NULL, dpAsync, (DWORD) lFlags);
  284. if (dpAsync)
  285. {
  286. *hAsyncHandle = (long)*dpAsync;
  287. SAFE_DELETE(dpAsync);
  288. }
  289. if ((hr != DPNERR_PENDING) && FAILED(hr))
  290. return hr;
  291. }
  292. __except(EXCEPTION_EXECUTE_HANDLER)
  293. {
  294. return E_FAIL;
  295. }
  296. return S_OK;
  297. }
  298. HRESULT C_dxj_DirectPlayPeerObject::DestroyPeer(long idClient, long lFlags, void *UserData, long UserDataSize)
  299. {
  300. HRESULT hr;
  301. __try {
  302. DPF(1,"-----Entering (DplayPeer) DestroyPeer call...\n");
  303. if (FAILED( hr= m__dxj_DirectPlayPeer->DestroyPeer((DPNID) idClient, UserData, UserDataSize, (DWORD) lFlags) ))
  304. return hr;
  305. }
  306. __except(EXCEPTION_EXECUTE_HANDLER)
  307. {
  308. return E_FAIL;
  309. }
  310. return S_OK;
  311. }
  312. HRESULT C_dxj_DirectPlayPeerObject::Connect(DPN_APPLICATION_DESC_CDESC *AppDesc,I_dxj_DirectPlayAddress *Address,I_dxj_DirectPlayAddress *DeviceInfo, long lFlags, void *UserData, long UserDataSize, long *hAsyncHandle)
  313. {
  314. HRESULT hr;
  315. DPN_APPLICATION_DESC desc;
  316. WCHAR wszSessionName[MAX_PATH];
  317. WCHAR wszPassword[MAX_PATH];
  318. DPNHANDLE *dpAsync = NULL;
  319. __try {
  320. if (!(lFlags & DPNSEND_SYNC))
  321. {
  322. dpAsync = new DPNHANDLE;
  323. if (!dpAsync)
  324. return E_OUTOFMEMORY;
  325. }
  326. DPF(1,"-----Entering (DplayPeer) Connect call...\n");
  327. if (!IsEmptyString(AppDesc->SessionName)) wcscpy(wszSessionName,AppDesc->SessionName);
  328. if (!IsEmptyString(AppDesc->Password)) wcscpy(wszPassword,AppDesc->Password);
  329. ZeroMemory(&desc, sizeof(desc));
  330. // Set up our Desc
  331. desc.dwSize = sizeof(DPN_APPLICATION_DESC);
  332. desc.dwFlags = AppDesc->lFlags;
  333. desc.dwMaxPlayers = AppDesc->lMaxPlayers;
  334. desc.dwCurrentPlayers = AppDesc->lCurrentPlayers;
  335. if (!IsEmptyString(AppDesc->SessionName))
  336. desc.pwszSessionName = wszSessionName;
  337. if (!IsEmptyString(AppDesc->Password))
  338. desc.pwszPassword = wszPassword;
  339. if (AppDesc->guidApplication)
  340. {
  341. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidApplication, AppDesc->guidApplication) ) )
  342. return hr;
  343. }
  344. if (AppDesc->guidInstance)
  345. {
  346. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidInstance , AppDesc->guidInstance) ) )
  347. return hr;
  348. }
  349. // Get our host and device address
  350. IDirectPlay8Address *lpAddress = NULL;
  351. IDirectPlay8Address *lpDevice = NULL;
  352. if(Address)
  353. {
  354. Address->InternalGetObject((IUnknown **)(&lpAddress));
  355. }
  356. if(DeviceInfo)
  357. {
  358. DeviceInfo->InternalGetObject((IUnknown **)(&lpDevice));
  359. }
  360. // Time to connect
  361. hr = m__dxj_DirectPlayPeer->Connect(&desc, lpAddress, lpDevice, NULL, NULL, UserData, (DWORD)UserDataSize, NULL, NULL, dpAsync, (DWORD) lFlags);
  362. if (dpAsync)
  363. {
  364. *hAsyncHandle = (long)*dpAsync;
  365. SAFE_DELETE(dpAsync);
  366. }
  367. if ((hr != DPNERR_PENDING) && FAILED(hr))
  368. return hr;
  369. }
  370. __except(EXCEPTION_EXECUTE_HANDLER)
  371. {
  372. return E_FAIL;
  373. }
  374. return S_OK;
  375. }
  376. HRESULT C_dxj_DirectPlayPeerObject::GetCountPlayersAndGroups(long lFlags, long *ret)
  377. {
  378. HRESULT hr;
  379. __try {
  380. DPF(1,"-----Entering (DplayPeer) GetCountPlayersAndGroups call...\n");
  381. // On the GetCount call we will always get the latest info
  382. if (FAILED ( hr = GetClientsAndGroups(lFlags) ) )
  383. return hr;
  384. *ret = m_dwClientCount;
  385. }
  386. __except(EXCEPTION_EXECUTE_HANDLER)
  387. {
  388. return E_FAIL;
  389. }
  390. return S_OK;
  391. }
  392. HRESULT C_dxj_DirectPlayPeerObject::GetPlayerOrGroup(long lIndex, long *ret)
  393. {
  394. __try {
  395. DPF(1,"-----Entering (DplayPeer) GetPlayerOrGroup call...\n");
  396. if (!m_ClientsGroups)
  397. return E_INVALIDARG;
  398. if ((lIndex < 1 ) || ((DWORD)lIndex > m_dwClientCount))
  399. return E_INVALIDARG;
  400. // Fill out our structure
  401. *ret = m_ClientsGroups[lIndex - 1];
  402. }
  403. __except(EXCEPTION_EXECUTE_HANDLER)
  404. {
  405. return E_FAIL;
  406. }
  407. return S_OK;
  408. }
  409. HRESULT C_dxj_DirectPlayPeerObject::GetCountGroupMembers(long dpid,long lFlags, long *ret)
  410. {
  411. HRESULT hr;
  412. __try {
  413. DPF(1,"-----Entering (DplayPeer) GetCountGroupMembers call...\n");
  414. // On the GetCount call we will always get the latest info
  415. if (FAILED ( hr = GetGroupMembers(lFlags, (DPNID) dpid) ) )
  416. return hr;
  417. *ret = m_dwGroupMemberCount;
  418. }
  419. __except(EXCEPTION_EXECUTE_HANDLER)
  420. {
  421. return E_FAIL;
  422. }
  423. return S_OK;
  424. }
  425. HRESULT C_dxj_DirectPlayPeerObject::GetGroupMember(long lIndex,long dpid, long *ret)
  426. {
  427. HRESULT hr;
  428. __try {
  429. DPF(1,"-----Entering (DplayPeer) GetGroupMember call...\n");
  430. if ((!m_GroupMembers) || ((DPNID)dpid != m_dwGroupID) )
  431. if (FAILED (hr = GetGroupMembers(0, (DPNID) dpid) ) )
  432. return hr;
  433. if ((lIndex < 1 ) || ((DWORD)lIndex > m_dwGroupMemberCount))
  434. return E_INVALIDARG;
  435. if (!m_GroupMembers)
  436. return E_INVALIDARG;
  437. // Fill out our structure
  438. *ret = m_GroupMembers[lIndex - 1];
  439. }
  440. __except(EXCEPTION_EXECUTE_HANDLER)
  441. {
  442. return E_FAIL;
  443. }
  444. return S_OK;
  445. }
  446. HRESULT C_dxj_DirectPlayPeerObject::EnumHosts(DPN_APPLICATION_DESC_CDESC *ApplicationDesc,I_dxj_DirectPlayAddress *AddrHost,I_dxj_DirectPlayAddress *DeviceInfo,long lRetryCount, long lRetryInterval, long lTimeOut,long lFlags, void *UserData, long UserDataSize, long *lAsync)
  447. {
  448. HRESULT hr;
  449. DPN_APPLICATION_DESC desc;
  450. WCHAR wszSessionName[MAX_PATH];
  451. WCHAR wszPassword[MAX_PATH];
  452. DPNHANDLE *dpAsync = NULL;
  453. __try {
  454. if (!(lFlags & DPNSEND_SYNC))
  455. {
  456. dpAsync = new DPNHANDLE;
  457. if (!dpAsync)
  458. return E_OUTOFMEMORY;
  459. }
  460. DPF(1,"-----Entering (DplayPeer) EnumHosts call...\n");
  461. if (!IsEmptyString(ApplicationDesc->SessionName)) wcscpy(wszSessionName,ApplicationDesc->SessionName);
  462. if (!IsEmptyString(ApplicationDesc->Password)) wcscpy(wszPassword,ApplicationDesc->Password);
  463. ZeroMemory(&desc, sizeof(desc));
  464. // Set up our Desc
  465. desc.dwSize = sizeof(DPN_APPLICATION_DESC);
  466. desc.dwFlags = ApplicationDesc->lFlags;
  467. desc.dwMaxPlayers = ApplicationDesc->lMaxPlayers;
  468. desc.dwCurrentPlayers = ApplicationDesc->lCurrentPlayers;
  469. if (!IsEmptyString(ApplicationDesc->SessionName))
  470. desc.pwszSessionName = wszSessionName;
  471. if (!IsEmptyString(ApplicationDesc->Password))
  472. desc.pwszPassword = wszPassword;
  473. if (ApplicationDesc->guidApplication)
  474. {
  475. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidApplication, ApplicationDesc->guidApplication) ) )
  476. return hr;
  477. }
  478. if (ApplicationDesc->guidInstance)
  479. {
  480. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidInstance, ApplicationDesc->guidInstance) ) )
  481. return hr;
  482. }
  483. // Get our host and device address
  484. DO_GETOBJECT_NOTNULL( IDirectPlay8Address*, lpHost, AddrHost);
  485. DO_GETOBJECT_NOTNULL( IDirectPlay8Address*, lpDevice, DeviceInfo);
  486. hr = m__dxj_DirectPlayPeer->EnumHosts(&desc, lpHost, lpDevice, UserData, UserDataSize, (DWORD) lRetryCount, (DWORD) lRetryInterval, (DWORD) lTimeOut, NULL, dpAsync, (DWORD) lFlags);
  487. // This should return E_PENDING
  488. if (dpAsync)
  489. {
  490. *lAsync = (long)*dpAsync;
  491. SAFE_DELETE(dpAsync);
  492. }
  493. if( hr != E_PENDING && FAILED(hr) )
  494. return hr;
  495. }
  496. __except(EXCEPTION_EXECUTE_HANDLER)
  497. {
  498. return E_FAIL;
  499. }
  500. return S_OK;
  501. }
  502. HRESULT C_dxj_DirectPlayPeerObject::ReturnBuffer(long lBufferHandle)
  503. {
  504. HRESULT hr;
  505. __try {
  506. //We should actually never get here since this is hidden, but just in case
  507. DPF(1,"-----Entering (DplayPeer) ReturnBuffer call...\n");
  508. if (FAILED(hr = m__dxj_DirectPlayPeer->ReturnBuffer( (DPNHANDLE) lBufferHandle, 0 ) ) )
  509. return hr;
  510. }
  511. __except(EXCEPTION_EXECUTE_HANDLER)
  512. {
  513. return E_FAIL;
  514. }
  515. return S_OK;
  516. }
  517. HRESULT C_dxj_DirectPlayPeerObject::Host(DPN_APPLICATION_DESC_CDESC *AppDesc,I_dxj_DirectPlayAddress *Address, long lFlags)
  518. {
  519. HRESULT hr;
  520. DPN_APPLICATION_DESC desc;
  521. GUID guidApp;
  522. GUID guidInst;
  523. WCHAR wszSessionName[MAX_PATH];
  524. WCHAR wszPassword[MAX_PATH];
  525. __try {
  526. DPF(1,"-----Entering (DplayPeer) Host call...\n");
  527. if (!IsEmptyString(AppDesc->SessionName)) wcscpy(wszSessionName,AppDesc->SessionName);
  528. if (!IsEmptyString(AppDesc->Password)) wcscpy(wszPassword,AppDesc->Password);
  529. DO_GETOBJECT_NOTNULL( IDirectPlay8Address*, lpAddress, Address);
  530. ZeroMemory(&desc, sizeof(DPN_APPLICATION_DESC) );
  531. desc.dwSize = sizeof(DPN_APPLICATION_DESC);
  532. desc.dwFlags = AppDesc->lFlags;
  533. desc.dwMaxPlayers = AppDesc->lMaxPlayers;
  534. desc.dwCurrentPlayers = AppDesc->lCurrentPlayers;
  535. if (!IsEmptyString(AppDesc->SessionName))
  536. desc.pwszSessionName = wszSessionName;
  537. if (!IsEmptyString(AppDesc->Password))
  538. desc.pwszPassword = wszPassword;
  539. if (AppDesc->guidApplication)
  540. {
  541. if (FAILED(hr = DPLAYBSTRtoGUID(&guidApp, AppDesc->guidApplication) ) )
  542. return hr;
  543. desc.guidApplication = guidApp;
  544. }
  545. if (AppDesc->guidInstance)
  546. {
  547. if (FAILED(hr = DPLAYBSTRtoGUID(&guidInst, AppDesc->guidInstance) ) )
  548. return hr;
  549. desc.guidInstance = guidInst;
  550. }
  551. if (FAILED (hr = m__dxj_DirectPlayPeer->Host(&desc, &lpAddress, 1, NULL, NULL, NULL, (DWORD) lFlags ) ) )
  552. return hr;
  553. }
  554. __except(EXCEPTION_EXECUTE_HANDLER)
  555. {
  556. return E_FAIL;
  557. }
  558. return S_OK;
  559. }
  560. HRESULT C_dxj_DirectPlayPeerObject::SendTo(long idSend, SAFEARRAY **Buffer, long lTimeOut,long lFlags, long *hAsyncHandle)
  561. {
  562. HRESULT hr;
  563. DPN_BUFFER_DESC lpBuf;
  564. DWORD dwBufSize = ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements;
  565. DPNHANDLE *dpAsync = NULL;
  566. __try {
  567. DPF(1,"-----Entering (DplayPeer) SendTo call...\n");
  568. if (!(lFlags & DPNSEND_SYNC))
  569. {
  570. dpAsync = new DPNHANDLE;
  571. if (!dpAsync)
  572. return E_OUTOFMEMORY;
  573. }
  574. lpBuf.dwBufferSize = dwBufSize;
  575. lpBuf.pBufferData = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  576. hr = m__dxj_DirectPlayPeer->SendTo((DPNID) idSend, &lpBuf, 1, (DWORD) lTimeOut, NULL, dpAsync, (DWORD) lFlags);
  577. if (dpAsync)
  578. {
  579. *hAsyncHandle = (long)*dpAsync;
  580. SAFE_DELETE(dpAsync);
  581. }
  582. if ((hr != DPNERR_PENDING) && FAILED(hr))
  583. return hr;
  584. }
  585. __except(EXCEPTION_EXECUTE_HANDLER)
  586. {
  587. return E_FAIL;
  588. }
  589. return S_OK;
  590. }
  591. HRESULT C_dxj_DirectPlayPeerObject::CreateGroup(DPN_GROUP_INFO_CDESC *GroupInfo, long lFlags, long *hAsyncHandle)
  592. {
  593. HRESULT hr;
  594. DPN_GROUP_INFO dpnGroup;
  595. WCHAR wszName[MAX_PATH];
  596. DPNHANDLE *dpAsync = NULL;
  597. __try {
  598. if (!(lFlags & DPNSEND_SYNC))
  599. {
  600. dpAsync = new DPNHANDLE;
  601. if (!dpAsync)
  602. return E_OUTOFMEMORY;
  603. }
  604. DPF(1,"-----Entering (DplayPeer) CreateGroup call...\n");
  605. if (!IsEmptyString(GroupInfo->Name)) wcscpy(wszName,GroupInfo->Name);
  606. ZeroMemory(&dpnGroup, sizeof(DPN_GROUP_INFO) );
  607. dpnGroup.dwSize = sizeof(DPN_GROUP_INFO);
  608. dpnGroup.dwInfoFlags = GroupInfo->lInfoFlags;
  609. dpnGroup.dwGroupFlags = GroupInfo->lGroupFlags;
  610. dpnGroup.pwszName = wszName;
  611. hr = m__dxj_DirectPlayPeer->CreateGroup(&dpnGroup, NULL, NULL, dpAsync, (DWORD) lFlags);
  612. if (dpAsync)
  613. {
  614. *hAsyncHandle = (long)*dpAsync;
  615. SAFE_DELETE(dpAsync);
  616. }
  617. if ((hr != DPNERR_PENDING) && FAILED(hr))
  618. return hr;
  619. }
  620. __except(EXCEPTION_EXECUTE_HANDLER)
  621. {
  622. return E_FAIL;
  623. }
  624. return S_OK;
  625. }
  626. HRESULT C_dxj_DirectPlayPeerObject::AddPlayerToGroup(long idGroup, long idClient,long lFlags, long *hAsyncHandle)
  627. {
  628. HRESULT hr;
  629. DPNHANDLE *dpAsync = NULL;
  630. __try {
  631. if (!(lFlags & DPNSEND_SYNC))
  632. {
  633. dpAsync = new DPNHANDLE;
  634. if (!dpAsync)
  635. return E_OUTOFMEMORY;
  636. }
  637. DPF(1,"-----Entering (DplayPeer) AddPlayerToGroup call...\n");
  638. hr = m__dxj_DirectPlayPeer->AddPlayerToGroup((DPNID) idGroup, (DPNID) idClient, NULL, dpAsync, (DWORD) lFlags);
  639. if (dpAsync)
  640. {
  641. *hAsyncHandle = (long)*dpAsync;
  642. SAFE_DELETE(dpAsync);
  643. }
  644. if ((hr != DPNERR_PENDING) && FAILED(hr))
  645. return hr;
  646. }
  647. __except(EXCEPTION_EXECUTE_HANDLER)
  648. {
  649. return E_FAIL;
  650. }
  651. return S_OK;
  652. }
  653. HRESULT C_dxj_DirectPlayPeerObject::GetSendQueueInfo(long idPlayer, long *lNumMsgs, long *lNumBytes, long lFlags)
  654. {
  655. HRESULT hr;
  656. __try {
  657. DPF(1,"-----Entering (DplayPeer) GetSendQueueInfo call...\n");
  658. if (FAILED (hr = m__dxj_DirectPlayPeer->GetSendQueueInfo((DPNID) idPlayer, (DWORD*)lNumMsgs, (DWORD*)lNumBytes, (DWORD) lFlags) ) )
  659. return hr;
  660. }
  661. __except(EXCEPTION_EXECUTE_HANDLER)
  662. {
  663. return E_FAIL;
  664. }
  665. return S_OK;
  666. }
  667. HRESULT C_dxj_DirectPlayPeerObject::SetGroupInfo(long idGroup, DPN_GROUP_INFO_CDESC *PlayerInfo, long lFlags, long *hAsyncHandle)
  668. {
  669. HRESULT hr;
  670. DPN_GROUP_INFO dpInfo;
  671. DPNHANDLE *dpAsync = NULL;
  672. __try {
  673. if (!(lFlags & DPNSEND_SYNC))
  674. {
  675. dpAsync = new DPNHANDLE;
  676. if (!dpAsync)
  677. return E_OUTOFMEMORY;
  678. }
  679. DPF(1,"-----Entering (DplayPeer) SetGroupInfo call...\n");
  680. ZeroMemory(&dpInfo, sizeof(DPN_GROUP_INFO) );
  681. dpInfo.dwSize = sizeof(DPN_GROUP_INFO);
  682. dpInfo.dwInfoFlags = PlayerInfo->lInfoFlags;
  683. dpInfo.pwszName = PlayerInfo->Name;
  684. dpInfo.dwGroupFlags = PlayerInfo->lGroupFlags;
  685. hr = m__dxj_DirectPlayPeer->SetGroupInfo((DPNID) idGroup, &dpInfo, NULL, dpAsync, (DWORD) lFlags);
  686. if (dpAsync)
  687. {
  688. *hAsyncHandle = (long)*dpAsync;
  689. SAFE_DELETE(dpAsync);
  690. }
  691. if ((hr != DPNERR_PENDING) && FAILED(hr))
  692. return hr;
  693. }
  694. __except(EXCEPTION_EXECUTE_HANDLER)
  695. {
  696. return E_FAIL;
  697. }
  698. return S_OK;
  699. }
  700. HRESULT C_dxj_DirectPlayPeerObject::GetGroupInfo(long idGroup,long lFlags, DPN_GROUP_INFO_CDESC *layerInfo)
  701. {
  702. HRESULT hr;
  703. DPN_GROUP_INFO *PlayerInfo = NULL;
  704. DWORD dwInfoSize = 0;
  705. __try {
  706. DPF(1,"-----Entering (DplayPeer) GetGroupInfo call...\n");
  707. hr = m__dxj_DirectPlayPeer->GetGroupInfo( (DPNID) idGroup, NULL, &dwInfoSize, (DWORD) lFlags );
  708. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  709. return hr;
  710. PlayerInfo = (DPN_GROUP_INFO*) new BYTE[ dwInfoSize ];
  711. if (!PlayerInfo)
  712. return E_OUTOFMEMORY;
  713. ZeroMemory( PlayerInfo, dwInfoSize );
  714. PlayerInfo->dwSize = sizeof(DPN_GROUP_INFO);
  715. hr = m__dxj_DirectPlayPeer->GetGroupInfo( (DPNID) idGroup, PlayerInfo, &dwInfoSize, (DWORD)lFlags );
  716. if( FAILED(hr) )
  717. return hr;
  718. layerInfo->lSize = sizeof(DPN_GROUP_INFO_CDESC);
  719. layerInfo->lInfoFlags = PlayerInfo->dwInfoFlags;
  720. layerInfo->Name = SysAllocString(PlayerInfo->pwszName);
  721. layerInfo->lGroupFlags = PlayerInfo->dwGroupFlags;
  722. }
  723. __except(EXCEPTION_EXECUTE_HANDLER)
  724. {
  725. return E_FAIL;
  726. }
  727. return S_OK;
  728. }
  729. HRESULT C_dxj_DirectPlayPeerObject::SetPeerInfo(DPN_PLAYER_INFO_CDESC *PlayerInfo,long lFlags, long *hAsyncHandle)
  730. {
  731. HRESULT hr;
  732. DPN_PLAYER_INFO dpInfo;
  733. DPNHANDLE *dpAsync = NULL;
  734. __try {
  735. if (!(lFlags & DPNSEND_SYNC))
  736. {
  737. dpAsync = new DPNHANDLE;
  738. if (!dpAsync)
  739. return E_OUTOFMEMORY;
  740. }
  741. DPF(1,"-----Entering (DplayPeer) SetPeerInfo call...\n");
  742. ZeroMemory(&dpInfo, sizeof(DPN_PLAYER_INFO) );
  743. dpInfo.dwSize = sizeof(DPN_PLAYER_INFO);
  744. dpInfo.dwInfoFlags = PlayerInfo->lInfoFlags;
  745. dpInfo.pwszName = PlayerInfo->Name;
  746. dpInfo.dwPlayerFlags = PlayerInfo->lPlayerFlags;
  747. hr = m__dxj_DirectPlayPeer->SetPeerInfo(&dpInfo, NULL, dpAsync, (DWORD) lFlags);
  748. if (dpAsync)
  749. {
  750. *hAsyncHandle = (long)*dpAsync;
  751. SAFE_DELETE(dpAsync);
  752. }
  753. if ((hr != DPNERR_PENDING) && FAILED(hr))
  754. return hr;
  755. }
  756. __except(EXCEPTION_EXECUTE_HANDLER)
  757. {
  758. return E_FAIL;
  759. }
  760. return S_OK;
  761. }
  762. HRESULT C_dxj_DirectPlayPeerObject::GetPeerInfo(long idPeer,long lFlags, DPN_PLAYER_INFO_CDESC *layerInfo)
  763. {
  764. HRESULT hr;
  765. DWORD dwSize = 0;
  766. DPN_PLAYER_INFO *PlayerInfo = NULL;
  767. DPF(1,"-----Entering (DplayPeer) GetPeerInfo call...\n");
  768. __try
  769. {
  770. hr = m__dxj_DirectPlayPeer->GetPeerInfo( (DPNID) idPeer, NULL, &dwSize, (DWORD) lFlags );
  771. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  772. return hr;
  773. PlayerInfo = (DPN_PLAYER_INFO*) new BYTE[ dwSize ];
  774. if (!PlayerInfo)
  775. return E_OUTOFMEMORY;
  776. ZeroMemory( PlayerInfo, dwSize );
  777. PlayerInfo->dwSize = sizeof(DPN_PLAYER_INFO);
  778. hr = m__dxj_DirectPlayPeer->GetPeerInfo( (DPNID) idPeer, PlayerInfo, &dwSize, (DWORD) lFlags );
  779. if( FAILED(hr) )
  780. return hr;
  781. layerInfo->lSize = sizeof(DPN_PLAYER_INFO_CDESC);
  782. layerInfo->lInfoFlags = PlayerInfo->dwInfoFlags;
  783. layerInfo->Name = SysAllocString(PlayerInfo->pwszName);
  784. layerInfo->lPlayerFlags = PlayerInfo->dwPlayerFlags;
  785. // We no longer need the playerinfo we got.. get rid of it..
  786. SAFE_DELETE(PlayerInfo);
  787. return S_OK;
  788. }
  789. __except(EXCEPTION_EXECUTE_HANDLER)
  790. {
  791. DPF(1,"***** GetPeerInfo ERROR...\n");
  792. return E_FAIL;
  793. }
  794. }
  795. HRESULT C_dxj_DirectPlayPeerObject::GetCountServiceProviders(long lFlags, long *ret)
  796. {
  797. HRESULT hr;
  798. __try {
  799. DPF(1,"-----Entering (DplayPeer) GetCountSP call...\n");
  800. if (!m_SPInfo)
  801. if (FAILED (hr=GetSP(lFlags) ) )
  802. return hr;
  803. *ret = (long)m_dwSPCount;
  804. }
  805. __except(EXCEPTION_EXECUTE_HANDLER)
  806. {
  807. return E_FAIL;
  808. }
  809. return S_OK;
  810. }
  811. HRESULT C_dxj_DirectPlayPeerObject::GetServiceProvider(long lIndex, DPN_SERVICE_PROVIDER_INFO_CDESC *ret)
  812. {
  813. HRESULT hr;
  814. GUID *guidSP = NULL;
  815. __try {
  816. DPF(1,"-----Entering (DplayPeer) GetSP call...\n");
  817. if (!m_SPInfo)
  818. if (FAILED (hr=GetSP(0) ) )
  819. return hr;
  820. if ((lIndex < 1 ) || ((DWORD)lIndex > m_dwSPCount))
  821. return E_INVALIDARG;
  822. // Fill out our structure
  823. ret->lFlags = (long) m_SPInfo[lIndex-1].dwFlags;
  824. ret->Name = SysAllocString(m_SPInfo[lIndex-1].pwszName);
  825. guidSP = new GUID;
  826. if (!guidSP)
  827. return E_OUTOFMEMORY;
  828. memcpy(guidSP,&m_SPInfo[lIndex-1].guid,sizeof(GUID));
  829. ret->Guid = GUIDtoBSTR(guidSP);
  830. }
  831. __except(EXCEPTION_EXECUTE_HANDLER)
  832. {
  833. return E_FAIL;
  834. }
  835. return S_OK;
  836. }
  837. HRESULT C_dxj_DirectPlayPeerObject::GetSP(long lFlags)
  838. {
  839. // Enumerate all DirectPlay sevice providers
  840. HRESULT hr;
  841. DWORD dwSize=0;
  842. DWORD dwItems=0;
  843. __try {
  844. SAFE_DELETE(m_SPInfo);
  845. hr = m__dxj_DirectPlayPeer->EnumServiceProviders( NULL, NULL, m_SPInfo, &dwSize,
  846. &dwItems, (DWORD) lFlags );
  847. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  848. return hr;
  849. m_SPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  850. if (!m_SPInfo)
  851. return E_OUTOFMEMORY;
  852. ZeroMemory(m_SPInfo, dwSize);
  853. if( FAILED( hr = m__dxj_DirectPlayPeer->EnumServiceProviders( NULL, NULL, m_SPInfo, &dwSize,
  854. &dwItems, (DWORD) lFlags ) ) )
  855. return hr;
  856. m_dwSPCount = dwItems;
  857. }
  858. __except(EXCEPTION_EXECUTE_HANDLER)
  859. {
  860. return E_FAIL;
  861. }
  862. return S_OK;
  863. }
  864. HRESULT C_dxj_DirectPlayPeerObject::GetClientsAndGroups(long lFlags)
  865. {
  866. // Enumerate all DirectPlay clients and groups
  867. HRESULT hr;
  868. DWORD dwSize=0;
  869. __try {
  870. SAFE_DELETE(m_ClientsGroups);
  871. hr = m__dxj_DirectPlayPeer->EnumPlayersAndGroups(NULL, &dwSize, (DWORD) lFlags);
  872. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  873. return hr;
  874. m_ClientsGroups = (DPNID*) new BYTE[dwSize * sizeof(DPNID)];
  875. if (!m_ClientsGroups)
  876. return E_OUTOFMEMORY;
  877. if( FAILED( hr = m__dxj_DirectPlayPeer->EnumPlayersAndGroups(m_ClientsGroups, &dwSize, (DWORD) lFlags) ) )
  878. return hr;
  879. m_dwClientCount = dwSize;// sizeof(DPNID);
  880. }
  881. __except(EXCEPTION_EXECUTE_HANDLER)
  882. {
  883. return E_FAIL;
  884. }
  885. return S_OK;
  886. }
  887. HRESULT C_dxj_DirectPlayPeerObject::GetGroupMembers(long lFlags, DPNID dpGroupID)
  888. {
  889. // Enumerate all DirectPlay group members for this group
  890. HRESULT hr;
  891. DWORD dwSize=0;
  892. __try {
  893. SAFE_DELETE(m_GroupMembers);
  894. hr = m__dxj_DirectPlayPeer->EnumGroupMembers (dpGroupID, NULL, &dwSize, (DWORD) lFlags);
  895. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  896. return hr;
  897. m_GroupMembers = (DPNID*) new BYTE[dwSize * sizeof(DPNID)];
  898. if (!m_GroupMembers)
  899. return E_OUTOFMEMORY;
  900. if( FAILED( hr = m__dxj_DirectPlayPeer->EnumGroupMembers (dpGroupID, m_GroupMembers, &dwSize, (DWORD) lFlags) ) )
  901. return hr;
  902. m_dwGroupMemberCount = dwSize;
  903. m_dwGroupID = dpGroupID;
  904. }
  905. __except(EXCEPTION_EXECUTE_HANDLER)
  906. {
  907. return E_FAIL;
  908. }
  909. return S_OK;
  910. }
  911. HRESULT C_dxj_DirectPlayPeerObject::RegisterLobby(long dpnHandle, I_dxj_DirectPlayLobbiedApplication *LobbyApp, long lFlags)
  912. {
  913. HRESULT hr;
  914. __try {
  915. DPF(1,"-----Entering (DplayPeer) RegisterLobby call...\n");
  916. DO_GETOBJECT_NOTNULL( IDirectPlay8LobbiedApplication*, lpLobby, LobbyApp);
  917. if (FAILED( hr = m__dxj_DirectPlayPeer->RegisterLobby((DPNHANDLE) dpnHandle, lpLobby,(DWORD) lFlags) ) )
  918. return hr;
  919. }
  920. __except(EXCEPTION_EXECUTE_HANDLER)
  921. {
  922. return E_FAIL;
  923. }
  924. return S_OK;
  925. }
  926. HRESULT C_dxj_DirectPlayPeerObject::GetConnectionInfo(long idPlayer, long lFlags, DPN_CONNECTION_INFO_CDESC *pdpConnectionInfo)
  927. {
  928. HRESULT hr;
  929. __try {
  930. DPF(1,"-----Entering (DplayPeer) GetConnectionInfo call...\n");
  931. pdpConnectionInfo->lSize = sizeof(DPN_CONNECTION_INFO);
  932. if (FAILED( hr = m__dxj_DirectPlayPeer->GetConnectionInfo((DPNID) idPlayer, (DPN_CONNECTION_INFO*)pdpConnectionInfo, lFlags) ) )
  933. return hr;
  934. }
  935. __except(EXCEPTION_EXECUTE_HANDLER)
  936. {
  937. return E_FAIL;
  938. }
  939. return S_OK;
  940. }
  941. HRESULT C_dxj_DirectPlayPeerObject::GetPeerAddress(long idPlayer,long lFlags, I_dxj_DirectPlayAddress **pAddress)
  942. {
  943. IDirectPlay8Address *lpAdd = NULL;
  944. HRESULT hr;
  945. __try {
  946. DPF(1,"-----Entering (DplayPeer) GetPeerAddress call...\n");
  947. if (FAILED (hr = m__dxj_DirectPlayPeer->GetPeerAddress( (DPNID) idPlayer, &lpAdd, (DWORD) lFlags) ) )
  948. return hr;
  949. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayAddress,lpAdd, pAddress);
  950. }
  951. __except(EXCEPTION_EXECUTE_HANDLER)
  952. {
  953. return E_FAIL;
  954. }
  955. return S_OK;
  956. }
  957. HRESULT C_dxj_DirectPlayPeerObject::GetLocalHostAddress(long lFlags, I_dxj_DirectPlayAddress **pAddress)
  958. {
  959. IDirectPlay8Address *lpAdd = NULL;
  960. HRESULT hr;
  961. DWORD dwItems = 0;
  962. __try {
  963. DPF(1,"-----Entering (DplayPeer) GetLocalHostAddress call...\n");
  964. hr = m__dxj_DirectPlayPeer->GetLocalHostAddresses( &lpAdd,&dwItems, (DWORD) lFlags);
  965. if (FAILED (hr) && hr != DPNERR_BUFFERTOOSMALL)
  966. return hr;
  967. if (dwItems>1)
  968. return E_INVALIDARG;
  969. if ( FAILED (hr = CoCreateInstance( CLSID_DirectPlay8Address, NULL,CLSCTX_INPROC_SERVER,
  970. IID_IDirectPlay8Address, (LPVOID*) &lpAdd ) ) )
  971. return hr;
  972. hr = m__dxj_DirectPlayPeer->GetLocalHostAddresses( &lpAdd,&dwItems, (DWORD) lFlags);
  973. if (FAILED (hr))
  974. return hr;
  975. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayAddress,lpAdd, pAddress);
  976. }
  977. __except(EXCEPTION_EXECUTE_HANDLER)
  978. {
  979. return E_FAIL;
  980. }
  981. return S_OK;
  982. }
  983. HRESULT C_dxj_DirectPlayPeerObject::SetSPCaps(BSTR guidSP, DPN_SP_CAPS_CDESC *spCaps, long lFlags)
  984. {
  985. HRESULT hr;
  986. GUID guidServiceProvider;
  987. __try {
  988. DPF(1,"-----Entering (DplayPeer) SetSPCaps call...\n");
  989. if (FAILED(hr = DPLAYBSTRtoGUID(&guidServiceProvider, guidSP) ) )
  990. return hr;
  991. spCaps->lSize = sizeof(DPN_SP_CAPS);
  992. //
  993. // MiNara: Added 0 for dwFlags parameter
  994. //
  995. if (FAILED(hr = m__dxj_DirectPlayPeer->SetSPCaps(&guidServiceProvider,(DPN_SP_CAPS*)spCaps,(DWORD) lFlags) ) )
  996. return hr;
  997. }
  998. __except(EXCEPTION_EXECUTE_HANDLER)
  999. {
  1000. return E_FAIL;
  1001. }
  1002. return S_OK;
  1003. }
  1004. HRESULT C_dxj_DirectPlayPeerObject::GetSPCaps(BSTR guidSP, long lFlags, DPN_SP_CAPS_CDESC *spCaps)
  1005. {
  1006. HRESULT hr;
  1007. GUID guidServiceProvider;
  1008. __try {
  1009. DPF(1,"-----Entering (DplayPeer) GetSPCaps call...\n");
  1010. spCaps->lSize = sizeof(DPN_SP_CAPS);
  1011. if (FAILED(hr = DPLAYBSTRtoGUID(&guidServiceProvider, guidSP) ) )
  1012. return hr;
  1013. if (FAILED(hr = m__dxj_DirectPlayPeer->GetSPCaps(&guidServiceProvider,(DPN_SP_CAPS*)spCaps, (DWORD) lFlags) ) )
  1014. return hr;
  1015. }
  1016. __except(EXCEPTION_EXECUTE_HANDLER)
  1017. {
  1018. return E_FAIL;
  1019. }
  1020. return S_OK;
  1021. }
  1022. HRESULT C_dxj_DirectPlayPeerObject::TerminateSession(long lFlags, void *UserData, long UserDataSize)
  1023. {
  1024. HRESULT hr;
  1025. __try {
  1026. DPF(1,"-----Entering (DplayPeer) TerminateSession call...\n");
  1027. if (FAILED (hr = m__dxj_DirectPlayPeer->TerminateSession(UserData,UserDataSize,(DWORD) lFlags)))
  1028. return hr;
  1029. }
  1030. __except(EXCEPTION_EXECUTE_HANDLER)
  1031. {
  1032. return E_FAIL;
  1033. }
  1034. return S_OK;
  1035. }
  1036. HRESULT WINAPI DirectPlayMessageHandler( PVOID pvUserContext,
  1037. DWORD dwMessageId,
  1038. PVOID pMsgBuffer )
  1039. {
  1040. HRESULT hr = S_OK;
  1041. LPUNKNOWN lpUnk = NULL;
  1042. BOOL fCallCoUninit = FALSE;
  1043. VARIANT_BOOL fRejectMsg = VARIANT_FALSE;
  1044. // User context for the message handler is a pointer to our class module.
  1045. C_dxj_DirectPlayPeerObject *lpPeer = (C_dxj_DirectPlayPeerObject*)pvUserContext;
  1046. if (!lpPeer)
  1047. return S_OK; //Object must be gone
  1048. DPF2(1,"-----Entering (DplayPeer) MessageHandler call... (Current msg count=%d) MSGID = %d\n", lpPeer->m_dwMsgCount, dwMessageId );
  1049. //Increment the msg count
  1050. InterlockedIncrement(&lpPeer->m_dwMsgCount);
  1051. if (!lpPeer->m_fHandleEvents)
  1052. {
  1053. DPF(1,"-----Leaving (DplayPeer) MessageHandler call (*Not Handling Events*)...\n");
  1054. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1055. return S_OK;
  1056. }
  1057. if (!lpPeer->m_pEventStream)
  1058. {
  1059. DPF(1,"-----Leaving (DplayPeer) MessageHandler call (Stream Not Present)...\n");
  1060. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1061. return S_OK;
  1062. }
  1063. // First we need to set our stream seek back to the beginning
  1064. // We will do this every time we enter this function since we don't know if
  1065. // we are on the same thread or not...
  1066. I_dxj_DirectPlayEvent *lpEvent = NULL;
  1067. __try {
  1068. LARGE_INTEGER l;
  1069. l.QuadPart = 0;
  1070. lpPeer->m_pEventStream->Seek(l, STREAM_SEEK_SET, NULL);
  1071. hr = CoUnmarshalInterface(lpPeer->m_pEventStream, IID_I_dxj_DirectPlayEvent, (void**)&lpEvent);
  1072. if (hr == CO_E_NOTINITIALIZED) // Call CoInit so we can unmarshal
  1073. {
  1074. DPF1(1,"-----Calling CoInitEx... HR = %d\n", hr);
  1075. CoInitializeEx(NULL,COINIT_MULTITHREADED);
  1076. hr = CoUnmarshalInterface(lpPeer->m_pEventStream, IID_I_dxj_DirectPlayEvent, (void**)&lpEvent);
  1077. fCallCoUninit = TRUE;
  1078. }
  1079. if (!lpEvent)
  1080. {
  1081. DPF1(1,"-----Leaving (DplayPeer) MessageHandler call (No event interface)... HR = %d\n", hr);
  1082. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1083. return hr;
  1084. }
  1085. }
  1086. __except(EXCEPTION_EXECUTE_HANDLER)
  1087. {
  1088. lpPeer->m_fHandleEvents = FALSE;
  1089. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1090. DPF(1,"-----Leaving (DplayPeer) MessageHandler call (Stream Gone)...\n");
  1091. return S_OK;
  1092. }
  1093. switch( dwMessageId )
  1094. {
  1095. //Receive
  1096. case DPN_MSGID_RECEIVE:
  1097. {
  1098. DPF(1,"-----DirectPlayPeer8 Callback Receive\n");
  1099. DPNMSG_RECEIVE *pMsgReceive = (DPNMSG_RECEIVE*)pMsgBuffer;
  1100. DPNMSG_RECEIVE_CDESC m_dpReceive;
  1101. SAFEARRAY *lpData = NULL;
  1102. SAFEARRAYBOUND rgsabound[1];
  1103. BYTE *lpTemp = NULL;
  1104. ZeroMemory(&m_dpReceive, sizeof(DPNMSG_RECEIVE_CDESC));
  1105. m_dpReceive.idSender = pMsgReceive->dpnidSender;
  1106. // Let's load our SafeArray
  1107. if (pMsgReceive->dwReceiveDataSize)
  1108. {
  1109. rgsabound[0].lLbound = 0;
  1110. rgsabound[0].cElements = pMsgReceive->dwReceiveDataSize;
  1111. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  1112. lpTemp = (BYTE*)lpData->pvData;
  1113. lpData->pvData = pMsgReceive->pReceiveData;
  1114. m_dpReceive.lDataSize = pMsgReceive->dwReceiveDataSize;
  1115. m_dpReceive.ReceivedData = lpData;
  1116. }
  1117. lpEvent->Receive(&m_dpReceive, &fRejectMsg);
  1118. if (lpData) //Get rid of the safearray
  1119. {
  1120. lpData->pvData = lpTemp;
  1121. SafeArrayDestroy(lpData);
  1122. }
  1123. break;
  1124. }
  1125. //Send complete
  1126. case DPN_MSGID_SEND_COMPLETE:
  1127. {
  1128. DPF(1,"-----DirectPlayPeer8 Callback SendComplete\n");
  1129. DPNMSG_SEND_COMPLETE *msg = (DPNMSG_SEND_COMPLETE*)pMsgBuffer;
  1130. DPNMSG_SEND_COMPLETE_CDESC m_dpSend;
  1131. ZeroMemory(&m_dpSend, sizeof(DPNMSG_SEND_COMPLETE_CDESC));
  1132. m_dpSend.AsyncOpHandle = (long)msg->hAsyncOp;
  1133. m_dpSend.hResultCode = (long)msg->hResultCode;
  1134. m_dpSend.lSendTime = (long)msg->dwSendTime;
  1135. lpEvent->SendComplete(&m_dpSend, &fRejectMsg);
  1136. break;
  1137. }
  1138. //Async Op complete
  1139. case DPN_MSGID_ASYNC_OP_COMPLETE:
  1140. {
  1141. DPF(1,"-----DirectPlayPeer8 Callback AsyncOpComplete\n");
  1142. DPNMSG_ASYNC_OP_COMPLETE *msg = (DPNMSG_ASYNC_OP_COMPLETE*)pMsgBuffer;
  1143. DPNMSG_ASYNC_OP_COMPLETE_CDESC m_dpAsynOp;
  1144. ZeroMemory(&m_dpAsynOp, sizeof(DPNMSG_ASYNC_OP_COMPLETE_CDESC));
  1145. m_dpAsynOp.AsyncOpHandle = (long) msg->hAsyncOp;
  1146. m_dpAsynOp.hResultCode = (long) msg->hResultCode;
  1147. lpEvent->AsyncOpComplete(&m_dpAsynOp, &fRejectMsg);
  1148. break;
  1149. }
  1150. // Add/Remove players from groups
  1151. case DPN_MSGID_ADD_PLAYER_TO_GROUP:
  1152. case DPN_MSGID_REMOVE_PLAYER_FROM_GROUP:
  1153. {
  1154. DPF(1,"-----DirectPlayPeer8 Callback Add/Remove Group\n");
  1155. DPNMSG_ADD_PLAYER_TO_GROUP *msg = (DPNMSG_ADD_PLAYER_TO_GROUP*)pMsgBuffer;
  1156. DPNID m_dpnidAddRemoveGroupID = 0;
  1157. DPNID m_dpnidAddRemovePlayerID = 0;
  1158. m_dpnidAddRemoveGroupID = msg->dpnidGroup;
  1159. m_dpnidAddRemovePlayerID = msg->dpnidPlayer;
  1160. lpEvent->AddRemovePlayerGroup(dwMessageId, m_dpnidAddRemovePlayerID, m_dpnidAddRemoveGroupID, &fRejectMsg);
  1161. break;
  1162. }
  1163. // App Desc
  1164. case DPN_MSGID_APPLICATION_DESC:
  1165. {
  1166. DPF(1,"-----DirectPlayPeer8 Callback App desc\n");
  1167. lpEvent->AppDesc(&fRejectMsg);
  1168. break;
  1169. }
  1170. // Indicate Connect
  1171. case DPN_MSGID_INDICATE_CONNECT:
  1172. {
  1173. DPF(1,"-----DirectPlayPeer8 Callback Indicate Connect\n");
  1174. DPNMSG_INDICATE_CONNECT *msg = (DPNMSG_INDICATE_CONNECT*)pMsgBuffer;
  1175. DPNMSG_INDICATE_CONNECT_CDESC m_dpIndConnect;
  1176. WCHAR wszAddress[MAX_PATH];
  1177. WCHAR wszDevice[MAX_PATH];
  1178. DWORD dwNumChars = 0;
  1179. ZeroMemory(&m_dpIndConnect, sizeof(DPNMSG_INDICATE_CONNECT_CDESC));
  1180. lpPeer->m_pUserData = msg->pvUserConnectData;
  1181. lpPeer->m_dwUserDataSize = msg->dwUserConnectDataSize;
  1182. __try {
  1183. if (msg->pAddressPlayer)
  1184. {
  1185. hr = msg->pAddressPlayer->GetURLW(NULL, &dwNumChars);
  1186. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1187. {
  1188. DPF1(1,"-----Failed... hr = %d\n",hr);
  1189. }
  1190. else
  1191. {
  1192. if (FAILED (hr = msg->pAddressPlayer->GetURLW(&wszAddress[0],&dwNumChars) ) )
  1193. {
  1194. DPF1(1,"-----Failed... hr = %d\n",hr);
  1195. }
  1196. else
  1197. {
  1198. m_dpIndConnect.AddressPlayerUrl = SysAllocString(wszAddress);
  1199. }
  1200. }
  1201. }
  1202. }
  1203. __except(EXCEPTION_EXECUTE_HANDLER)
  1204. {
  1205. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1206. DPF(1,"-----Exception (Indicate Connect - Part1)...\n");
  1207. }
  1208. __try {
  1209. dwNumChars = 0;
  1210. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  1211. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1212. {
  1213. DPF1(1,"-----Failed... hr = %d\n",hr);
  1214. }
  1215. else
  1216. {
  1217. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  1218. {
  1219. DPF1(1,"-----Failed... hr = %d\n",hr);
  1220. }
  1221. else
  1222. {
  1223. m_dpIndConnect.AddressDeviceUrl = SysAllocString(wszDevice);
  1224. }
  1225. }
  1226. }
  1227. __except(EXCEPTION_EXECUTE_HANDLER)
  1228. {
  1229. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1230. DPF(1,"-----Exception (Indicate Connect - Part2)...\n");
  1231. }
  1232. lpEvent->IndicateConnect(&m_dpIndConnect, &fRejectMsg);
  1233. msg->pvReplyData = lpPeer->m_pReplyData;
  1234. msg->dwReplyDataSize = lpPeer->m_dwReplyDataSize;
  1235. // Get rid of these addresses
  1236. if (m_dpIndConnect.AddressPlayerUrl)
  1237. SysFreeString(m_dpIndConnect.AddressPlayerUrl);
  1238. if (m_dpIndConnect.AddressDeviceUrl)
  1239. SysFreeString(m_dpIndConnect.AddressDeviceUrl);
  1240. break;
  1241. }
  1242. // Connect complete
  1243. case DPN_MSGID_CONNECT_COMPLETE:
  1244. {
  1245. DPF(1,"-----DirectPlayPeer8 Callback ConnectComplete\n");
  1246. DPNMSG_CONNECT_COMPLETE *msg = (DPNMSG_CONNECT_COMPLETE*)pMsgBuffer;
  1247. DPNMSG_CONNECT_COMPLETE_CDESC m_dpConnectComp;
  1248. SAFEARRAY *lpData = NULL;
  1249. SAFEARRAYBOUND rgsabound[1];
  1250. BYTE *lpTemp = NULL;
  1251. ZeroMemory(&m_dpConnectComp, sizeof(DPNMSG_CONNECT_COMPLETE_CDESC));
  1252. m_dpConnectComp.hResultCode = (long) msg->hResultCode;
  1253. m_dpConnectComp.AsyncOpHandle =(long) msg->hAsyncOp;
  1254. // Let's load our SafeArray
  1255. if (msg->dwApplicationReplyDataSize)
  1256. {
  1257. rgsabound[0].lLbound = 0;
  1258. rgsabound[0].cElements = msg->dwApplicationReplyDataSize;
  1259. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  1260. lpTemp = (BYTE*)lpData->pvData;
  1261. lpData->pvData = msg->pvApplicationReplyData;
  1262. m_dpConnectComp.ReplyData = lpData;
  1263. }
  1264. lpEvent->ConnectComplete(&m_dpConnectComp, &fRejectMsg);
  1265. if (lpData) //Get rid of the safearray
  1266. {
  1267. lpData->pvData = lpTemp;
  1268. SafeArrayDestroy(lpData);
  1269. }
  1270. break;
  1271. }
  1272. // Host migrated
  1273. case DPN_MSGID_HOST_MIGRATE:
  1274. {
  1275. DPF(1,"-----DirectPlayPeer8 Callback HostMigrate\n");
  1276. DPNMSG_HOST_MIGRATE *msg = (DPNMSG_HOST_MIGRATE*)pMsgBuffer;
  1277. DPNID m_dpnidNewHostID = 0;
  1278. m_dpnidNewHostID = msg->dpnidNewHost;
  1279. lpEvent->HostMigrate(m_dpnidNewHostID, &fRejectMsg);
  1280. break;
  1281. }
  1282. // Terminate Session
  1283. case DPN_MSGID_TERMINATE_SESSION:
  1284. {
  1285. DPF(1,"-----DirectPlayPeer8 Callback TerminateSession\n");
  1286. DPNMSG_TERMINATE_SESSION *msg = (DPNMSG_TERMINATE_SESSION*)pMsgBuffer;
  1287. DPNMSG_TERMINATE_SESSION_CDESC m_dpTerm;
  1288. SAFEARRAY *lpData = NULL;
  1289. SAFEARRAYBOUND rgsabound[1];
  1290. BYTE *lpTemp = NULL;
  1291. ZeroMemory(&m_dpTerm, sizeof(DPNMSG_TERMINATE_SESSION_CDESC));
  1292. m_dpTerm.hResultCode = msg->hResultCode;
  1293. // Let's load our SafeArray
  1294. if (msg->dwTerminateDataSize)
  1295. {
  1296. rgsabound[0].lLbound = 0;
  1297. rgsabound[0].cElements = msg->dwTerminateDataSize;
  1298. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  1299. lpTemp = (BYTE*)lpData->pvData;
  1300. lpData->pvData = msg->pvTerminateData;
  1301. m_dpTerm.TerminateData = lpData;
  1302. }
  1303. lpEvent->TerminateSession(&m_dpTerm,&fRejectMsg);
  1304. if (lpData) //Get rid of the safearray
  1305. {
  1306. lpData->pvData = lpTemp;
  1307. SafeArrayDestroy(lpData);
  1308. }
  1309. break;
  1310. }
  1311. // Enum Host query
  1312. case DPN_MSGID_ENUM_HOSTS_QUERY:
  1313. {
  1314. DPF(1,"-----DirectPlayPeer8 Callback EnumHostQuery\n");
  1315. DPNMSG_ENUM_HOSTS_QUERY *msg = (DPNMSG_ENUM_HOSTS_QUERY*)pMsgBuffer;
  1316. DPNMSG_ENUM_HOSTS_QUERY_CDESC m_dpEnumHostQuery;
  1317. WCHAR wszAddress[MAX_PATH];
  1318. WCHAR wszDevice[MAX_PATH];
  1319. DWORD dwNumChars = 0;
  1320. ZeroMemory(&m_dpEnumHostQuery, sizeof(DPNMSG_ENUM_HOSTS_QUERY_CDESC));
  1321. __try {
  1322. hr = msg->pAddressSender->GetURLW(NULL, &dwNumChars);
  1323. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1324. {
  1325. DPF1(1,"-----Failed... hr = %d\n",hr);
  1326. }
  1327. else
  1328. {
  1329. if (FAILED (hr = msg->pAddressSender->GetURLW(&wszAddress[0],&dwNumChars) ) )
  1330. {
  1331. DPF1(1,"-----Failed... hr = %d\n",hr);
  1332. }
  1333. else
  1334. {
  1335. m_dpEnumHostQuery.AddressSenderUrl = SysAllocString(wszAddress);
  1336. }
  1337. }
  1338. }
  1339. __except(EXCEPTION_EXECUTE_HANDLER)
  1340. {
  1341. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1342. DPF(1,"-----Exception (EnumQuery Connect - Part1)...\n");
  1343. }
  1344. __try {
  1345. dwNumChars = 0;
  1346. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  1347. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1348. {
  1349. DPF1(1,"-----Failed... hr = %d\n",hr);
  1350. }
  1351. else
  1352. {
  1353. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  1354. {
  1355. DPF1(1,"-----Failed... hr = %d\n",hr);
  1356. }
  1357. else
  1358. {
  1359. m_dpEnumHostQuery.AddressDeviceUrl = SysAllocString(wszDevice);
  1360. }
  1361. }
  1362. }
  1363. __except(EXCEPTION_EXECUTE_HANDLER)
  1364. {
  1365. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1366. DPF(1,"-----Exception (EnumQuery Connect - Part2)...\n");
  1367. }
  1368. lpEvent->EnumHostsQuery(&m_dpEnumHostQuery, &fRejectMsg);
  1369. // Get rid of these addresses
  1370. if (m_dpEnumHostQuery.AddressSenderUrl)
  1371. SysFreeString(m_dpEnumHostQuery.AddressSenderUrl);
  1372. if (m_dpEnumHostQuery.AddressDeviceUrl)
  1373. SysFreeString(m_dpEnumHostQuery.AddressDeviceUrl);
  1374. break;
  1375. }
  1376. // Create Player
  1377. case DPN_MSGID_CREATE_PLAYER:
  1378. {
  1379. DPF(1,"-----DirectPlayPeer8 Callback CreatePlayer\n");
  1380. DPNMSG_CREATE_PLAYER *msg = (DPNMSG_CREATE_PLAYER*)pMsgBuffer;
  1381. DPNID m_dpnidPlayerID = 0;
  1382. m_dpnidPlayerID = msg->dpnidPlayer;
  1383. lpEvent->CreatePlayer(m_dpnidPlayerID, &fRejectMsg);
  1384. break;
  1385. }
  1386. // Destroy Player
  1387. case DPN_MSGID_DESTROY_PLAYER:
  1388. {
  1389. DPF(1,"-----DirectPlayPeer8 Callback DestroyPlayer\n");
  1390. DPNMSG_DESTROY_PLAYER *msg = (DPNMSG_DESTROY_PLAYER*)pMsgBuffer;
  1391. DPNID m_dpnidPlayerID = 0;
  1392. DWORD m_dwReason = 0;
  1393. m_dpnidPlayerID = msg->dpnidPlayer;
  1394. m_dwReason = msg->dwReason;
  1395. lpEvent->DestroyPlayer(m_dpnidPlayerID, m_dwReason, &fRejectMsg);
  1396. break;
  1397. }
  1398. // Create Group
  1399. case DPN_MSGID_CREATE_GROUP:
  1400. {
  1401. DPF(1,"-----DirectPlayPeer8 Callback CreateGroup\n");
  1402. DPNMSG_CREATE_GROUP *msg = (DPNMSG_CREATE_GROUP*)pMsgBuffer;
  1403. DPNID m_dpnidPlayerID = 0;
  1404. DPNID m_dpnidOwnerID = 0;
  1405. m_dpnidPlayerID = msg->dpnidGroup;
  1406. m_dpnidOwnerID = msg->dpnidOwner;
  1407. lpEvent->CreateGroup(m_dpnidPlayerID, m_dpnidOwnerID, &fRejectMsg);
  1408. break;
  1409. }
  1410. //Destroy Group
  1411. case DPN_MSGID_DESTROY_GROUP:
  1412. {
  1413. DPF(1,"-----DirectPlayPeer8 Callback DestroyGroup\n");
  1414. DPNMSG_DESTROY_GROUP *msg = (DPNMSG_DESTROY_GROUP*)pMsgBuffer;
  1415. DPNID m_dpnidPlayerID = 0;
  1416. DWORD m_dwReason = 0;
  1417. m_dpnidPlayerID = msg->dpnidGroup;
  1418. m_dwReason = msg->dwReason;
  1419. lpEvent->DestroyGroup(m_dpnidPlayerID, m_dwReason, &fRejectMsg);
  1420. break;
  1421. }
  1422. // Info
  1423. case DPN_MSGID_PEER_INFO:
  1424. case DPN_MSGID_CLIENT_INFO:
  1425. case DPN_MSGID_SERVER_INFO:
  1426. case DPN_MSGID_GROUP_INFO:
  1427. {
  1428. DPF(1,"-----DirectPlayPeer8 Callback Info\n");
  1429. DPNMSG_PEER_INFO *msg = (DPNMSG_PEER_INFO*)pMsgBuffer;
  1430. DPNID m_dpnidInfoID = 0;
  1431. m_dpnidInfoID = msg->dpnidPeer;
  1432. lpEvent->InfoNotify(dwMessageId, m_dpnidInfoID, &fRejectMsg);
  1433. break;
  1434. }
  1435. // EnumHostRes
  1436. case DPN_MSGID_ENUM_HOSTS_RESPONSE:
  1437. {
  1438. DPF(1,"-----DirectPlayPeer8 Callback EnumHostResponse\n");
  1439. DPNMSG_ENUM_HOSTS_RESPONSE *msg = (DPNMSG_ENUM_HOSTS_RESPONSE*)pMsgBuffer;
  1440. DPNMSG_ENUM_HOSTS_RESPONSE_CDESC m_dpEnumHostRes;
  1441. DWORD dwNumChars = 0;
  1442. WCHAR wszAddress[MAX_PATH];
  1443. WCHAR wszDevice[MAX_PATH];
  1444. ZeroMemory(&m_dpEnumHostRes, sizeof(DPNMSG_ENUM_HOSTS_RESPONSE_CDESC));
  1445. m_dpEnumHostRes.ApplicationDescription.lSize = (long)msg->pApplicationDescription->dwSize;
  1446. m_dpEnumHostRes.ApplicationDescription.lFlags = msg->pApplicationDescription->dwFlags;
  1447. m_dpEnumHostRes.ApplicationDescription.guidInstance = GUIDtoBSTR((GUID*)&msg->pApplicationDescription->guidInstance);
  1448. m_dpEnumHostRes.ApplicationDescription.guidApplication = GUIDtoBSTR((GUID*)&msg->pApplicationDescription->guidApplication);
  1449. m_dpEnumHostRes.ApplicationDescription.lMaxPlayers = (long)msg->pApplicationDescription->dwMaxPlayers;
  1450. m_dpEnumHostRes.ApplicationDescription.lCurrentPlayers = (long)msg->pApplicationDescription->dwCurrentPlayers;
  1451. m_dpEnumHostRes.ApplicationDescription.SessionName = SysAllocString(msg->pApplicationDescription->pwszSessionName);
  1452. m_dpEnumHostRes.ApplicationDescription.Password = SysAllocString(msg->pApplicationDescription->pwszPassword);
  1453. m_dpEnumHostRes.lRoundTripLatencyMS = (long) msg->dwRoundTripLatencyMS;
  1454. __try {
  1455. if (msg->pAddressSender)
  1456. {
  1457. DPF(1,"-----About to get AdressSender...\n");
  1458. hr = msg->pAddressSender->GetURLW(NULL, &dwNumChars);
  1459. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1460. {
  1461. DPF1(1,"-----Failed... hr = %d\n",hr);
  1462. }
  1463. else
  1464. {
  1465. DPF1(1,"--- About to call GetURLW, NumChars= %d\n",dwNumChars);
  1466. if (FAILED (hr = msg->pAddressSender->GetURLW(&wszAddress[0],&dwNumChars) ) )
  1467. {
  1468. DPF1(1,"-----Failed... hr = %d\n",hr);
  1469. }
  1470. else
  1471. {
  1472. m_dpEnumHostRes.AddressSenderUrl = SysAllocString(wszAddress);
  1473. }
  1474. }
  1475. }
  1476. }
  1477. __except(EXCEPTION_EXECUTE_HANDLER)
  1478. {
  1479. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1480. DPF(1,"-----Exception (EnumRes Connect - Part1)...\n");
  1481. }
  1482. __try {
  1483. dwNumChars = 0;
  1484. if (msg->pAddressDevice)
  1485. {
  1486. DPF(1,"-----About to get AdressDevice...\n");
  1487. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  1488. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1489. {
  1490. DPF1(1,"-----Failed... hr = %d\n",hr);
  1491. }
  1492. else {
  1493. DPF1(1,"--- About to call GetURLW, NumChars= %d\n",dwNumChars);
  1494. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  1495. {
  1496. DPF1(1,"-----Failed... hr = %d\n",hr);
  1497. }
  1498. else
  1499. {
  1500. m_dpEnumHostRes.AddressDeviceUrl = SysAllocString(wszDevice);
  1501. }
  1502. }
  1503. }
  1504. }
  1505. __except(EXCEPTION_EXECUTE_HANDLER)
  1506. {
  1507. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1508. DPF(1,"-----Exception (EnumRes Connect - Part1)...\n");
  1509. }
  1510. lpEvent->EnumHostsResponse(&m_dpEnumHostRes, &fRejectMsg);
  1511. if (m_dpEnumHostRes.AddressSenderUrl)
  1512. SysFreeString(m_dpEnumHostRes.AddressSenderUrl);
  1513. if (m_dpEnumHostRes.AddressDeviceUrl)
  1514. SysFreeString(m_dpEnumHostRes.AddressDeviceUrl);
  1515. break;
  1516. }
  1517. // Indicate Connect
  1518. case DPN_MSGID_INDICATED_CONNECT_ABORTED:
  1519. {
  1520. DPF(1,"-----DirectPlayServer8 Callback Indicated Connect Abort\n");
  1521. lpEvent->IndicatedConnectAborted(&fRejectMsg);
  1522. break;
  1523. }
  1524. }
  1525. __try {
  1526. if (lpPeer->m_pEventStream)
  1527. // clean up marshaled packet
  1528. CoReleaseMarshalData(lpPeer->m_pEventStream);
  1529. }
  1530. __except(EXCEPTION_EXECUTE_HANDLER)
  1531. {
  1532. lpPeer->m_fHandleEvents = FALSE;
  1533. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1534. DPF(1,"-----Leaving (DplayPeer) MessageHandler call (Stream Gone)...\n");
  1535. return S_OK;
  1536. }
  1537. if (fCallCoUninit)
  1538. CoUninitialize();
  1539. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  1540. DPF(1,"-----Leaving (DplayPeer) MessageHandler call...\n");
  1541. if (fRejectMsg != VARIANT_FALSE)
  1542. return E_FAIL;
  1543. return S_OK;
  1544. }
  1545. HRESULT C_dxj_DirectPlayPeerObject::RegisterMessageHandler(I_dxj_DirectPlayEvent *event)
  1546. {
  1547. HRESULT hr=S_OK;
  1548. LPSTREAM pStm=NULL;
  1549. if (!event) return E_INVALIDARG;
  1550. if (!m_fHandleEvents)
  1551. {
  1552. DPF(1,"-----Entering (DplayPeer) RegisterMessageHandler call...\n");
  1553. SAFE_RELEASE(m_pEventStream);
  1554. // Create a global stream. The stream needs to be global so we can
  1555. // marshal once, and unmarshal as many times as necessary
  1556. hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
  1557. if FAILED(hr) return hr;
  1558. // Now we can marshal our IUnknown interface. We use MSHLFLAGS_TABLEWEAK
  1559. // so we can unmarshal any number of times
  1560. hr = CoMarshalInterface(pStm, IID_I_dxj_DirectPlayEvent, event, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
  1561. if FAILED(hr) return hr;
  1562. // Now we need to set the seek location of the stream to the beginning
  1563. LARGE_INTEGER l;
  1564. l.QuadPart = 0;
  1565. pStm->Seek(l, STREAM_SEEK_SET, NULL);
  1566. m_pEventStream=pStm;
  1567. if (!m_fInit)
  1568. {
  1569. if (FAILED ( hr = m__dxj_DirectPlayPeer->Initialize( this, DirectPlayMessageHandler, 0 ) ) )
  1570. return hr;
  1571. m_fInit = TRUE;
  1572. }
  1573. m_fHandleEvents = TRUE;
  1574. }
  1575. else
  1576. return DPNERR_ALREADYINITIALIZED;
  1577. return hr;
  1578. }
  1579. HRESULT C_dxj_DirectPlayPeerObject::UnRegisterMessageHandler()
  1580. {
  1581. DPF(1,"-----Entering (DplayPeer) UnregisterMessageHandler call...\n");
  1582. m_fHandleEvents = FALSE;
  1583. //Clear out the messages currently waiting
  1584. FlushBuffer(0);
  1585. return S_OK;
  1586. }
  1587. HRESULT C_dxj_DirectPlayPeerObject::FlushBuffer(LONG dwNumMessagesLeft)
  1588. {
  1589. DWORD dwTime = GetTickCount();
  1590. DPF(1,"-----Entering (DplayPeer) FlushBuffer call...\n");
  1591. //Clear out the messages currently waiting
  1592. while (m_dwMsgCount > dwNumMessagesLeft)
  1593. {
  1594. if (GetTickCount() - dwTime > 1000)
  1595. {
  1596. // Don't let FlushBuffer wait more than 5 seconds
  1597. DPF1(1,"-----Leaving (DplayPeer) FlushBuffer call (All messages *not* flushed - %d remained)...\n", m_dwMsgCount);
  1598. return S_OK;
  1599. }
  1600. Sleep(0);
  1601. }
  1602. DPF(1,"-----Leaving (DplayPeer) FlushBuffer call (All messages flushed)...\n");
  1603. return S_OK;
  1604. }
  1605. DWORD WINAPI ClosePeerThreadProc(void* lpParam)
  1606. {
  1607. // User context for the message handler is a pointer to our class module.
  1608. IDirectPlay8Peer *lpPeer = (IDirectPlay8Peer*)lpParam;
  1609. DPF(1,"-----Entering (DplayPeer) ClosePeerThreadProc call...\n");
  1610. lpPeer->Close(0);
  1611. DPF(1,"-----Leaving (DplayPeer) ClosePeerThreadProc call ...\n");
  1612. return 0;
  1613. }