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.

1419 lines
38 KiB

  1. #include "stdafx.h"
  2. #include "Direct.h"
  3. #include "dms.h"
  4. #include "DPlayClientObj.h"
  5. #include "DPlayAddressObj.h"
  6. extern void *g_dxj_DirectPlayAddress;
  7. extern void *g_dxj_DirectPlayClient;
  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,"--DirectPlayClient SafeRelease (RefCount = %d)\n",i); if (!i) { (p)=NULL;}} } __except(EXCEPTION_EXECUTE_HANDLER) { (p) = NULL;} }
  13. DWORD WINAPI CloseClientThreadProc(void* lpParam);
  14. ///////////////////////////////////////////////////////////////////
  15. // InternalAddRef
  16. ///////////////////////////////////////////////////////////////////
  17. DWORD C_dxj_DirectPlayClientObject::InternalAddRef(){
  18. DWORD i;
  19. i=CComObjectRoot::InternalAddRef();
  20. DPF1(1,"----- DXVB: DirectPlayClient8 AddRef %d \n",i);
  21. return i;
  22. }
  23. ///////////////////////////////////////////////////////////////////
  24. // InternalRelease
  25. ///////////////////////////////////////////////////////////////////
  26. DWORD C_dxj_DirectPlayClientObject::InternalRelease(){
  27. DWORD i;
  28. i=CComObjectRoot::InternalRelease();
  29. DPF1(1,"------ DXVB: DirectPlayClient8 Release %d \n",i);
  30. return i;
  31. }
  32. ///////////////////////////////////////////////////////////////////
  33. // C_dxj_DirectPlayClientObject
  34. ///////////////////////////////////////////////////////////////////
  35. C_dxj_DirectPlayClientObject::C_dxj_DirectPlayClientObject(){
  36. DPF(1,"---- DXVB: Constructor Creation DirectPlayClient8 Object\n ");
  37. m__dxj_DirectPlayClient = NULL;
  38. m_SPInfo = NULL;
  39. m_dwSPCount = 0;
  40. m_fInit = FALSE;
  41. m_fHandleEvents = FALSE;
  42. m_pUserData = NULL;
  43. m_dwUserDataSize = 0;
  44. m_pReplyData = NULL;
  45. m_dwReplyDataSize = 0;
  46. m_pEventStream=NULL;
  47. m_dwMsgCount = 0;
  48. }
  49. ///////////////////////////////////////////////////////////////////
  50. // ~C_dxj_DirectPlayClientObject
  51. ///////////////////////////////////////////////////////////////////
  52. C_dxj_DirectPlayClientObject::~C_dxj_DirectPlayClientObject()
  53. {
  54. DPF(1,"---- Entering ~C_dxj_DirectPlayClientObject destructor \n");
  55. //We still have messages to process get rid of them
  56. m_fHandleEvents = FALSE;
  57. FlushBuffer(0);
  58. SAFE_RELEASE(m__dxj_DirectPlayClient);
  59. SAFE_DELETE(m_SPInfo);
  60. m_fHandleEvents = FALSE;
  61. if (m_pEventStream)
  62. m_pEventStream->Release();
  63. }
  64. HRESULT C_dxj_DirectPlayClientObject::InternalGetObject(IUnknown **pUnk){
  65. *pUnk=(IUnknown*)m__dxj_DirectPlayClient;
  66. return S_OK;
  67. }
  68. HRESULT C_dxj_DirectPlayClientObject::InternalSetObject(IUnknown *pUnk){
  69. m__dxj_DirectPlayClient=(IDirectPlay8Client*)pUnk;
  70. return S_OK;
  71. }
  72. HRESULT WINAPI DirectPlayClientMessageHandler( PVOID pvUserContext,
  73. DWORD dwMessageId,
  74. PVOID pMsgBuffer )
  75. {
  76. HRESULT hr=S_OK;
  77. LPUNKNOWN lpUnk=NULL;
  78. BOOL fCallCoUninit = FALSE;
  79. VARIANT_BOOL fRejectMsg = VARIANT_FALSE;
  80. // User context for the message handler is a pointer to our class module.
  81. C_dxj_DirectPlayClientObject *lpPeer = (C_dxj_DirectPlayClientObject*)pvUserContext;
  82. if (!lpPeer)
  83. return S_OK; //Object must be gone
  84. DPF2(1,"-----Entering (DPlayClient) MessageHandler call... (Current msg count=%d) MSGID = %d\n", lpPeer->m_dwMsgCount, dwMessageId );
  85. //Increment the msg count
  86. InterlockedIncrement(&lpPeer->m_dwMsgCount);
  87. if (!lpPeer->m_fHandleEvents)
  88. {
  89. DPF(1,"-----Leaving (DPlayClient) MessageHandler call (*Not Handling Events*)...\n");
  90. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  91. return S_OK;
  92. }
  93. if (!lpPeer->m_pEventStream)
  94. {
  95. DPF(1,"-----Leaving (DPlayClient) MessageHandler call (Stream Not Present)...\n");
  96. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  97. return S_OK;
  98. }
  99. // First we need to set our stream seek back to the beginning
  100. // We will do this every time we enter this function since we don't know if
  101. // we are on the same thread or not...
  102. I_dxj_DirectPlayEvent *lpEvent = NULL;
  103. __try {
  104. LARGE_INTEGER l;
  105. l.QuadPart = 0;
  106. lpPeer->m_pEventStream->Seek(l, STREAM_SEEK_SET, NULL);
  107. hr = CoUnmarshalInterface(lpPeer->m_pEventStream, IID_I_dxj_DirectPlayEvent, (void**)&lpEvent);
  108. if (hr == CO_E_NOTINITIALIZED) // Call CoInit so we can unmarshal
  109. {
  110. CoInitializeEx(NULL,COINIT_MULTITHREADED);
  111. hr = CoUnmarshalInterface(lpPeer->m_pEventStream, IID_I_dxj_DirectPlayEvent, (void**)&lpEvent);
  112. fCallCoUninit = TRUE;
  113. }
  114. if (!lpEvent)
  115. {
  116. DPF1(1,"-----Leaving (DPlayClient) MessageHandler call (No event interface) - (Hresult) = %d...\n", hr);
  117. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  118. return hr;
  119. }
  120. }
  121. __except(EXCEPTION_EXECUTE_HANDLER)
  122. {
  123. lpPeer->m_fHandleEvents = FALSE;
  124. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  125. DPF(1,"-----Leaving (DPlayClient) MessageHandler call (Stream Gone)...\n");
  126. return S_OK;
  127. }
  128. switch( dwMessageId )
  129. {
  130. //Receive
  131. case DPN_MSGID_RECEIVE:
  132. {
  133. DPF(1,"-----DirectPlayClient8 Callback Receive\n");
  134. DPNMSG_RECEIVE *pMsgReceive = (DPNMSG_RECEIVE*)pMsgBuffer;
  135. DPNMSG_RECEIVE_CDESC m_dpReceive;
  136. SAFEARRAY *lpData = NULL;
  137. SAFEARRAYBOUND rgsabound[1];
  138. BYTE *lpTemp = NULL;
  139. ZeroMemory(&m_dpReceive, sizeof(DPNMSG_RECEIVE_CDESC));
  140. m_dpReceive.idSender = pMsgReceive->dpnidSender;
  141. // Let's load our SafeArray
  142. if (pMsgReceive->dwReceiveDataSize)
  143. {
  144. rgsabound[0].lLbound = 0;
  145. rgsabound[0].cElements = pMsgReceive->dwReceiveDataSize;
  146. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  147. lpTemp = (BYTE*)lpData->pvData;
  148. lpData->pvData = pMsgReceive->pReceiveData;
  149. m_dpReceive.lDataSize = pMsgReceive->dwReceiveDataSize;
  150. m_dpReceive.ReceivedData = lpData;
  151. }
  152. lpEvent->Receive(&m_dpReceive, &fRejectMsg);
  153. if (lpData) //Get rid of the safearray
  154. {
  155. lpData->pvData = lpTemp;
  156. SafeArrayDestroy(lpData);
  157. }
  158. break;
  159. }
  160. //Send complete
  161. case DPN_MSGID_SEND_COMPLETE:
  162. {
  163. DPF(1,"-----DirectPlayClient8 Callback SendComplete\n");
  164. DPNMSG_SEND_COMPLETE *msg = (DPNMSG_SEND_COMPLETE*)pMsgBuffer;
  165. DPNMSG_SEND_COMPLETE_CDESC m_dpSend;
  166. ZeroMemory(&m_dpSend, sizeof(DPNMSG_SEND_COMPLETE_CDESC));
  167. m_dpSend.AsyncOpHandle = (long)msg->hAsyncOp;
  168. m_dpSend.hResultCode = (long)msg->hResultCode;
  169. m_dpSend.lSendTime = (long)msg->dwSendTime;
  170. lpEvent->SendComplete(&m_dpSend, &fRejectMsg);
  171. break;
  172. }
  173. //Async Op complete
  174. case DPN_MSGID_ASYNC_OP_COMPLETE:
  175. {
  176. DPF(1,"-----DirectPlayClient8 Callback AsyncOpComplete\n");
  177. DPNMSG_ASYNC_OP_COMPLETE *msg = (DPNMSG_ASYNC_OP_COMPLETE*)pMsgBuffer;
  178. DPNMSG_ASYNC_OP_COMPLETE_CDESC m_dpAsynOp;
  179. ZeroMemory(&m_dpAsynOp, sizeof(DPNMSG_ASYNC_OP_COMPLETE_CDESC));
  180. m_dpAsynOp.AsyncOpHandle = (long) msg->hAsyncOp;
  181. m_dpAsynOp.hResultCode = (long) msg->hResultCode;
  182. lpEvent->AsyncOpComplete(&m_dpAsynOp, &fRejectMsg);
  183. break;
  184. }
  185. // Add/Remove players from groups
  186. case DPN_MSGID_ADD_PLAYER_TO_GROUP:
  187. case DPN_MSGID_REMOVE_PLAYER_FROM_GROUP:
  188. {
  189. DPF(1,"-----DirectPlayClient8 Callback Add/Remove Group\n");
  190. DPNMSG_ADD_PLAYER_TO_GROUP *msg = (DPNMSG_ADD_PLAYER_TO_GROUP*)pMsgBuffer;
  191. DPNID m_dpnidAddRemoveGroupID = 0;
  192. DPNID m_dpnidAddRemovePlayerID = 0;
  193. m_dpnidAddRemoveGroupID = msg->dpnidGroup;
  194. m_dpnidAddRemovePlayerID = msg->dpnidPlayer;
  195. lpEvent->AddRemovePlayerGroup(dwMessageId, m_dpnidAddRemovePlayerID, m_dpnidAddRemoveGroupID, &fRejectMsg);
  196. break;
  197. }
  198. // App Desc
  199. case DPN_MSGID_APPLICATION_DESC:
  200. {
  201. DPF(1,"-----DirectPlayClient8 Callback App desc\n");
  202. lpEvent->AppDesc(&fRejectMsg);
  203. break;
  204. }
  205. // Indicate Connect
  206. case DPN_MSGID_INDICATE_CONNECT:
  207. {
  208. DPF(1,"-----DirectPlayClient8 Callback Indicate Connect\n");
  209. DPNMSG_INDICATE_CONNECT *msg = (DPNMSG_INDICATE_CONNECT*)pMsgBuffer;
  210. DPNMSG_INDICATE_CONNECT_CDESC m_dpIndConnect;
  211. WCHAR wszAddress[MAX_PATH];
  212. WCHAR wszDevice[MAX_PATH];
  213. DWORD dwNumChars = 0;
  214. ZeroMemory(&m_dpIndConnect, sizeof(DPNMSG_INDICATE_CONNECT_CDESC));
  215. lpPeer->m_pUserData = msg->pvUserConnectData;
  216. lpPeer->m_dwUserDataSize = msg->dwUserConnectDataSize;
  217. __try {
  218. if (msg->pAddressPlayer)
  219. {
  220. hr = msg->pAddressPlayer->GetURLW(NULL, &dwNumChars);
  221. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  222. {
  223. DPF1(1,"-----Failed... hr = %d\n",hr);
  224. }
  225. else
  226. {
  227. if (FAILED (hr = msg->pAddressPlayer->GetURLW(&wszAddress[0],&dwNumChars) ) )
  228. {
  229. DPF1(1,"-----Failed... hr = %d\n",hr);
  230. }
  231. else
  232. {
  233. m_dpIndConnect.AddressPlayerUrl = SysAllocString(wszAddress);
  234. }
  235. }
  236. }
  237. }
  238. __except(EXCEPTION_EXECUTE_HANDLER)
  239. {
  240. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  241. DPF(1,"-----Exception (Indicate Connect - Part1)...\n");
  242. }
  243. __try {
  244. dwNumChars = 0;
  245. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  246. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  247. {
  248. DPF1(1,"-----Failed... hr = %d\n",hr);
  249. }
  250. else
  251. {
  252. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  253. {
  254. DPF1(1,"-----Failed... hr = %d\n",hr);
  255. }
  256. else
  257. {
  258. m_dpIndConnect.AddressDeviceUrl = SysAllocString(wszDevice);
  259. }
  260. }
  261. }
  262. __except(EXCEPTION_EXECUTE_HANDLER)
  263. {
  264. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  265. DPF(1,"-----Exception (Indicate Connect - Part2)...\n");
  266. }
  267. lpEvent->IndicateConnect(&m_dpIndConnect, &fRejectMsg);
  268. msg->pvReplyData = lpPeer->m_pReplyData;
  269. msg->dwReplyDataSize = lpPeer->m_dwReplyDataSize;
  270. // Get rid of these addresses
  271. if (m_dpIndConnect.AddressPlayerUrl)
  272. SysFreeString(m_dpIndConnect.AddressPlayerUrl);
  273. if (m_dpIndConnect.AddressDeviceUrl)
  274. SysFreeString(m_dpIndConnect.AddressDeviceUrl);
  275. break;
  276. }
  277. // Connect complete
  278. case DPN_MSGID_CONNECT_COMPLETE:
  279. {
  280. DPF(1,"-----DirectPlayClient8 Callback ConnectComplete\n");
  281. DPNMSG_CONNECT_COMPLETE *msg = (DPNMSG_CONNECT_COMPLETE*)pMsgBuffer;
  282. DPNMSG_CONNECT_COMPLETE_CDESC m_dpConnectComp;
  283. SAFEARRAY *lpData = NULL;
  284. SAFEARRAYBOUND rgsabound[1];
  285. BYTE *lpTemp = NULL;
  286. ZeroMemory(&m_dpConnectComp, sizeof(DPNMSG_CONNECT_COMPLETE_CDESC));
  287. m_dpConnectComp.hResultCode = (long) msg->hResultCode;
  288. m_dpConnectComp.AsyncOpHandle =(long) msg->hAsyncOp;
  289. // Let's load our SafeArray
  290. if (msg->dwApplicationReplyDataSize)
  291. {
  292. rgsabound[0].lLbound = 0;
  293. rgsabound[0].cElements = msg->dwApplicationReplyDataSize;
  294. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  295. lpTemp = (BYTE*)lpData->pvData;
  296. lpData->pvData = msg->pvApplicationReplyData;
  297. m_dpConnectComp.ReplyData = lpData;
  298. }
  299. lpEvent->ConnectComplete(&m_dpConnectComp, &fRejectMsg);
  300. if (lpData) //Get rid of the safearray
  301. {
  302. lpData->pvData = lpTemp;
  303. SafeArrayDestroy(lpData);
  304. }
  305. break;
  306. }
  307. // Host migrated
  308. case DPN_MSGID_HOST_MIGRATE:
  309. {
  310. DPF(1,"-----DirectPlayClient8 Callback HostMigrate\n");
  311. DPNMSG_HOST_MIGRATE *msg = (DPNMSG_HOST_MIGRATE*)pMsgBuffer;
  312. DPNID m_dpnidNewHostID = 0;
  313. m_dpnidNewHostID = msg->dpnidNewHost;
  314. lpEvent->HostMigrate(m_dpnidNewHostID, &fRejectMsg);
  315. break;
  316. }
  317. // Terminate Session
  318. case DPN_MSGID_TERMINATE_SESSION:
  319. {
  320. DPF(1,"-----DirectPlayClient8 Callback TerminateSession\n");
  321. DPNMSG_TERMINATE_SESSION *msg = (DPNMSG_TERMINATE_SESSION*)pMsgBuffer;
  322. DPNMSG_TERMINATE_SESSION_CDESC m_dpTerm;
  323. SAFEARRAY *lpData = NULL;
  324. SAFEARRAYBOUND rgsabound[1];
  325. BYTE *lpTemp = NULL;
  326. ZeroMemory(&m_dpTerm, sizeof(DPNMSG_TERMINATE_SESSION_CDESC));
  327. m_dpTerm.hResultCode = msg->hResultCode;
  328. // Let's load our SafeArray
  329. if (msg->dwTerminateDataSize)
  330. {
  331. rgsabound[0].lLbound = 0;
  332. rgsabound[0].cElements = msg->dwTerminateDataSize;
  333. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  334. lpTemp = (BYTE*)lpData->pvData;
  335. lpData->pvData = msg->pvTerminateData;
  336. m_dpTerm.TerminateData = lpData;
  337. }
  338. lpEvent->TerminateSession(&m_dpTerm,&fRejectMsg);
  339. if (lpData) //Get rid of the safearray
  340. {
  341. lpData->pvData = lpTemp;
  342. SafeArrayDestroy(lpData);
  343. }
  344. break;
  345. }
  346. // Enum Host query
  347. case DPN_MSGID_ENUM_HOSTS_QUERY:
  348. {
  349. DPF(1,"-----DirectPlayClient8 Callback EnumHostQuery\n");
  350. DPNMSG_ENUM_HOSTS_QUERY *msg = (DPNMSG_ENUM_HOSTS_QUERY*)pMsgBuffer;
  351. DPNMSG_ENUM_HOSTS_QUERY_CDESC m_dpEnumHostQuery;
  352. WCHAR wszAddress[MAX_PATH];
  353. WCHAR wszDevice[MAX_PATH];
  354. DWORD dwNumChars = 0;
  355. ZeroMemory(&m_dpEnumHostQuery, sizeof(DPNMSG_ENUM_HOSTS_QUERY_CDESC));
  356. __try {
  357. hr = msg->pAddressSender->GetURLW(NULL, &dwNumChars);
  358. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  359. {
  360. DPF1(1,"-----Failed... hr = %d\n",hr);
  361. }
  362. else
  363. {
  364. if (FAILED (hr = msg->pAddressSender->GetURLW(&wszAddress[0],&dwNumChars) ) )
  365. {
  366. DPF1(1,"-----Failed... hr = %d\n",hr);
  367. }
  368. else
  369. {
  370. m_dpEnumHostQuery.AddressSenderUrl = SysAllocString(wszAddress);
  371. }
  372. }
  373. }
  374. __except(EXCEPTION_EXECUTE_HANDLER)
  375. {
  376. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  377. DPF(1,"-----Exception (EnumQuery Connect - Part1)...\n");
  378. }
  379. __try {
  380. dwNumChars = 0;
  381. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  382. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  383. {
  384. DPF1(1,"-----Failed... hr = %d\n",hr);
  385. }
  386. else
  387. {
  388. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  389. {
  390. DPF1(1,"-----Failed... hr = %d\n",hr);
  391. }
  392. else
  393. {
  394. m_dpEnumHostQuery.AddressDeviceUrl = SysAllocString(wszDevice);
  395. }
  396. }
  397. }
  398. __except(EXCEPTION_EXECUTE_HANDLER)
  399. {
  400. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  401. DPF(1,"-----Exception (EnumQuery Connect - Part2)...\n");
  402. }
  403. lpEvent->EnumHostsQuery(&m_dpEnumHostQuery, &fRejectMsg);
  404. // Get rid of these addresses
  405. if (m_dpEnumHostQuery.AddressSenderUrl)
  406. SysFreeString(m_dpEnumHostQuery.AddressSenderUrl);
  407. if (m_dpEnumHostQuery.AddressDeviceUrl)
  408. SysFreeString(m_dpEnumHostQuery.AddressDeviceUrl);
  409. break;
  410. }
  411. // Create Player
  412. case DPN_MSGID_CREATE_PLAYER:
  413. {
  414. DPF(1,"-----DirectPlayClient8 Callback CreatePlayer\n");
  415. DPNMSG_CREATE_PLAYER *msg = (DPNMSG_CREATE_PLAYER*)pMsgBuffer;
  416. DPNID m_dpnidPlayerID = 0;
  417. m_dpnidPlayerID = msg->dpnidPlayer;
  418. lpEvent->CreatePlayer(m_dpnidPlayerID, &fRejectMsg);
  419. break;
  420. }
  421. // Destroy Player
  422. case DPN_MSGID_DESTROY_PLAYER:
  423. {
  424. DPF(1,"-----DirectPlayClient8 Callback DestroyPlayer\n");
  425. DPNMSG_DESTROY_PLAYER *msg = (DPNMSG_DESTROY_PLAYER*)pMsgBuffer;
  426. DPNID m_dpnidPlayerID = 0;
  427. DWORD m_dwReason = 0;
  428. m_dpnidPlayerID = msg->dpnidPlayer;
  429. m_dwReason = msg->dwReason;
  430. lpEvent->DestroyPlayer(m_dpnidPlayerID, m_dwReason, &fRejectMsg);
  431. break;
  432. }
  433. // Create Group
  434. case DPN_MSGID_CREATE_GROUP:
  435. {
  436. DPF(1,"-----DirectPlayClient8 Callback CreateGroup\n");
  437. DPNMSG_CREATE_GROUP *msg = (DPNMSG_CREATE_GROUP*)pMsgBuffer;
  438. DPNID m_dpnidPlayerID = 0;
  439. DPNID m_dpnidOwnerID = 0;
  440. m_dpnidPlayerID = msg->dpnidGroup;
  441. m_dpnidOwnerID = msg->dpnidOwner;
  442. lpEvent->CreateGroup(m_dpnidPlayerID, m_dpnidOwnerID, &fRejectMsg);
  443. break;
  444. }
  445. //Destroy Group
  446. case DPN_MSGID_DESTROY_GROUP:
  447. {
  448. DPF(1,"-----DirectPlayClient8 Callback DestroyGroup\n");
  449. DPNMSG_DESTROY_GROUP *msg = (DPNMSG_DESTROY_GROUP*)pMsgBuffer;
  450. DPNID m_dpnidPlayerID = 0;
  451. DWORD m_dwReason = 0;
  452. m_dpnidPlayerID = msg->dpnidGroup;
  453. m_dwReason = msg->dwReason;
  454. lpEvent->DestroyGroup(m_dpnidPlayerID, m_dwReason, &fRejectMsg);
  455. break;
  456. }
  457. // Info
  458. case DPN_MSGID_PEER_INFO:
  459. case DPN_MSGID_CLIENT_INFO:
  460. case DPN_MSGID_SERVER_INFO:
  461. case DPN_MSGID_GROUP_INFO:
  462. {
  463. DPF(1,"-----DirectPlayClient8 Callback Info\n");
  464. DPNMSG_PEER_INFO *msg = (DPNMSG_PEER_INFO*)pMsgBuffer;
  465. DPNID m_dpnidInfoID = 0;
  466. m_dpnidInfoID = msg->dpnidPeer;
  467. lpEvent->InfoNotify(dwMessageId, m_dpnidInfoID, &fRejectMsg);
  468. break;
  469. }
  470. // EnumHostRes
  471. case DPN_MSGID_ENUM_HOSTS_RESPONSE:
  472. {
  473. DPF(1,"-----DirectPlayClient8 Callback EnumHostResponse\n");
  474. DPNMSG_ENUM_HOSTS_RESPONSE *msg = (DPNMSG_ENUM_HOSTS_RESPONSE*)pMsgBuffer;
  475. DPNMSG_ENUM_HOSTS_RESPONSE_CDESC m_dpEnumHostRes;
  476. DWORD dwNumChars = 0;
  477. WCHAR wszAddress[MAX_PATH];
  478. WCHAR wszDevice[MAX_PATH];
  479. ZeroMemory(&m_dpEnumHostRes, sizeof(DPNMSG_ENUM_HOSTS_RESPONSE_CDESC));
  480. m_dpEnumHostRes.ApplicationDescription.lSize = (long)msg->pApplicationDescription->dwSize;
  481. m_dpEnumHostRes.ApplicationDescription.lFlags = msg->pApplicationDescription->dwFlags;
  482. m_dpEnumHostRes.ApplicationDescription.guidInstance = GUIDtoBSTR((GUID*)&msg->pApplicationDescription->guidInstance);
  483. m_dpEnumHostRes.ApplicationDescription.guidApplication = GUIDtoBSTR((GUID*)&msg->pApplicationDescription->guidApplication);
  484. m_dpEnumHostRes.ApplicationDescription.lMaxPlayers = (long)msg->pApplicationDescription->dwMaxPlayers;
  485. m_dpEnumHostRes.ApplicationDescription.lCurrentPlayers = (long)msg->pApplicationDescription->dwCurrentPlayers;
  486. m_dpEnumHostRes.ApplicationDescription.SessionName = SysAllocString(msg->pApplicationDescription->pwszSessionName);
  487. m_dpEnumHostRes.ApplicationDescription.Password = SysAllocString(msg->pApplicationDescription->pwszPassword);
  488. m_dpEnumHostRes.lRoundTripLatencyMS = (long) msg->dwRoundTripLatencyMS;
  489. __try {
  490. if (msg->pAddressSender)
  491. {
  492. DPF(1,"-----About to get AdressSender...\n");
  493. hr = msg->pAddressSender->GetURLW(NULL, &dwNumChars);
  494. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  495. {
  496. DPF1(1,"-----Failed... hr = %d\n",hr);
  497. }
  498. else
  499. {
  500. if (FAILED (hr = msg->pAddressSender->GetURLW(&wszAddress[0],&dwNumChars) ) )
  501. {
  502. DPF1(1,"-----Failed... hr = %d\n",hr);
  503. }
  504. else
  505. {
  506. m_dpEnumHostRes.AddressSenderUrl = SysAllocString(wszAddress);
  507. }
  508. }
  509. }
  510. }
  511. __except(EXCEPTION_EXECUTE_HANDLER)
  512. {
  513. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  514. DPF(1,"-----Exception (EnumRes Connect - Part1)...\n");
  515. }
  516. __try {
  517. dwNumChars = 0;
  518. if (msg->pAddressDevice)
  519. {
  520. DPF(1,"-----About to get AdressDevice...\n");
  521. hr = msg->pAddressDevice->GetURLW(NULL, &dwNumChars);
  522. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  523. {
  524. DPF1(1,"-----Failed... hr = %d\n",hr);
  525. }
  526. else {
  527. if (FAILED (hr = msg->pAddressDevice->GetURLW(&wszDevice[0],&dwNumChars) ) )
  528. {
  529. DPF1(1,"-----Failed... hr = %d\n",hr);
  530. }
  531. else
  532. {
  533. m_dpEnumHostRes.AddressDeviceUrl = SysAllocString(wszDevice);
  534. }
  535. }
  536. }
  537. }
  538. __except(EXCEPTION_EXECUTE_HANDLER)
  539. {
  540. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  541. DPF(1,"-----Exception (EnumRes Connect - Part1)...\n");
  542. }
  543. lpEvent->EnumHostsResponse(&m_dpEnumHostRes, &fRejectMsg);
  544. if (m_dpEnumHostRes.AddressSenderUrl)
  545. SysFreeString(m_dpEnumHostRes.AddressSenderUrl);
  546. if (m_dpEnumHostRes.AddressDeviceUrl)
  547. SysFreeString(m_dpEnumHostRes.AddressDeviceUrl);
  548. break;
  549. }
  550. // Indicate Connect
  551. case DPN_MSGID_INDICATED_CONNECT_ABORTED:
  552. {
  553. DPF(1,"-----DirectPlayServer8 Callback Indicated Connect Abort\n");
  554. lpEvent->IndicatedConnectAborted(&fRejectMsg);
  555. break;
  556. }
  557. }
  558. __try {
  559. if (lpPeer->m_pEventStream)
  560. // clean up marshaled packet
  561. CoReleaseMarshalData(lpPeer->m_pEventStream);
  562. }
  563. __except(EXCEPTION_EXECUTE_HANDLER)
  564. {
  565. lpPeer->m_fHandleEvents = FALSE;
  566. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  567. DPF(1,"-----Leaving (DPlayClient) MessageHandler call (Stream Gone)...\n");
  568. return S_OK;
  569. }
  570. if (fCallCoUninit)
  571. CoUninitialize();
  572. InterlockedDecrement(&lpPeer->m_dwMsgCount);
  573. DPF(1,"-----Leaving (DPlayClient) MessageHandler call...\n");
  574. if (fRejectMsg != VARIANT_FALSE)
  575. return E_FAIL;
  576. return S_OK;
  577. }
  578. HRESULT C_dxj_DirectPlayClientObject::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)
  579. {
  580. HRESULT hr;
  581. DPN_APPLICATION_DESC desc;
  582. GUID guidApp;
  583. GUID guidInst;
  584. WCHAR wszSessionName[MAX_PATH];
  585. WCHAR wszPassword[MAX_PATH];
  586. DPNHANDLE *dpAsync = NULL;
  587. __try {
  588. DPF(1,"-----Entering (DPlayClient) EnumHosts call...\n");
  589. if (!(lFlags & DPNSEND_SYNC))
  590. {
  591. dpAsync = new DPNHANDLE;
  592. if (!dpAsync)
  593. return E_OUTOFMEMORY;
  594. }
  595. if (!IsEmptyString(ApplicationDesc->SessionName)) wcscpy(wszSessionName,ApplicationDesc->SessionName);
  596. if (!IsEmptyString(ApplicationDesc->Password)) wcscpy(wszPassword,ApplicationDesc->Password);
  597. ZeroMemory(&desc, sizeof(desc));
  598. // Set up our Desc
  599. desc.dwSize = sizeof(DPN_APPLICATION_DESC);
  600. desc.dwFlags = ApplicationDesc->lFlags;
  601. desc.dwMaxPlayers = ApplicationDesc->lMaxPlayers;
  602. desc.dwCurrentPlayers = ApplicationDesc->lCurrentPlayers;
  603. if (!IsEmptyString(ApplicationDesc->SessionName))
  604. desc.pwszSessionName = wszSessionName;
  605. if (!IsEmptyString(ApplicationDesc->Password))
  606. desc.pwszPassword = wszPassword;
  607. if (ApplicationDesc->guidApplication)
  608. {
  609. if (FAILED(hr = DPLAYBSTRtoGUID(&guidApp, ApplicationDesc->guidApplication) ) )
  610. return hr;
  611. desc.guidApplication = guidApp;
  612. }
  613. if (ApplicationDesc->guidInstance)
  614. {
  615. if (FAILED(hr = DPLAYBSTRtoGUID(&guidInst, ApplicationDesc->guidInstance) ) )
  616. return hr;
  617. desc.guidInstance = guidInst;
  618. }
  619. // Get our host and device address
  620. IDirectPlay8Address *lpHost = NULL;
  621. IDirectPlay8Address *lpDevice = NULL;
  622. if(AddrHost) AddrHost->InternalGetObject((IUnknown **)(&lpHost));
  623. if(DeviceInfo) DeviceInfo->InternalGetObject((IUnknown **)(&lpDevice));
  624. hr = m__dxj_DirectPlayClient->EnumHosts(&desc, lpHost, lpDevice, UserData, UserDataSize, (DWORD) lRetryCount, (DWORD) lRetryInterval, (DWORD) lTimeOut, NULL, dpAsync, (DWORD) lFlags);
  625. // This should return E_PENDING
  626. if (dpAsync)
  627. {
  628. *lAsync = (long)*dpAsync;
  629. SAFE_DELETE(dpAsync);
  630. }
  631. if( hr != E_PENDING && FAILED(hr) )
  632. return hr;
  633. }
  634. __except(EXCEPTION_EXECUTE_HANDLER)
  635. {
  636. return E_FAIL;
  637. }
  638. return S_OK;
  639. }
  640. HRESULT C_dxj_DirectPlayClientObject::CancelAsyncOperation(long lAsyncHandle, long lFlags)
  641. {
  642. HRESULT hr;
  643. __try {
  644. DPF(1,"-----Entering (DPlayClient) CancelAsyncOperation call...\n");
  645. if (FAILED( hr= m__dxj_DirectPlayClient->CancelAsyncOperation((DPNHANDLE) lAsyncHandle, (DWORD) lFlags) ) )
  646. return hr;
  647. }
  648. __except(EXCEPTION_EXECUTE_HANDLER)
  649. {
  650. return E_FAIL;
  651. }
  652. return S_OK;
  653. }
  654. HRESULT C_dxj_DirectPlayClientObject::Connect(DPN_APPLICATION_DESC_CDESC *AppDesc,I_dxj_DirectPlayAddress *Address,I_dxj_DirectPlayAddress *DeviceInfo, long lFlags, void *UserData, long UserDataSize, long *hAsyncHandle)
  655. {
  656. HRESULT hr;
  657. DPN_APPLICATION_DESC desc;
  658. WCHAR wszSessionName[MAX_PATH];
  659. WCHAR wszPassword[MAX_PATH];
  660. DPNHANDLE *dpAsync = NULL;
  661. __try {
  662. if (!(lFlags & DPNSEND_SYNC))
  663. {
  664. dpAsync = new DPNHANDLE;
  665. if (!dpAsync)
  666. return E_OUTOFMEMORY;
  667. }
  668. DPF(1,"-----Entering (DPlayClient) Connect call...\n");
  669. if (!IsEmptyString(AppDesc->SessionName)) wcscpy(wszSessionName,AppDesc->SessionName);
  670. if (!IsEmptyString(AppDesc->Password)) wcscpy(wszPassword,AppDesc->Password);
  671. ZeroMemory(&desc, sizeof(desc));
  672. // Set up our Desc
  673. desc.dwSize = sizeof(DPN_APPLICATION_DESC);
  674. desc.dwFlags = AppDesc->lFlags;
  675. desc.dwMaxPlayers = AppDesc->lMaxPlayers;
  676. desc.dwCurrentPlayers = AppDesc->lCurrentPlayers;
  677. if (!IsEmptyString(AppDesc->SessionName))
  678. desc.pwszSessionName = wszSessionName;
  679. if (!IsEmptyString(AppDesc->Password))
  680. desc.pwszPassword = wszPassword;
  681. if (AppDesc->guidApplication)
  682. {
  683. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidApplication, AppDesc->guidApplication) ) )
  684. return hr;
  685. }
  686. if (AppDesc->guidInstance)
  687. {
  688. if (FAILED(hr = DPLAYBSTRtoGUID(&desc.guidInstance , AppDesc->guidInstance) ) )
  689. return hr;
  690. }
  691. // Get our host and device address
  692. IDirectPlay8Address *lpAddress = NULL;
  693. IDirectPlay8Address *lpDevice = NULL;
  694. if(Address)
  695. {
  696. IUnknown *lpTemp = NULL;
  697. Address->InternalGetObject((IUnknown **)(&lpTemp));
  698. lpTemp->QueryInterface(IID_IDirectPlay8Address, (void**)&lpAddress);
  699. lpTemp->Release();
  700. }
  701. if(DeviceInfo)
  702. {
  703. IUnknown *lpTemp = NULL;
  704. DeviceInfo->InternalGetObject((IUnknown **)(&lpTemp));
  705. lpTemp->QueryInterface(IID_IDirectPlay8Address, (void**)&lpDevice);
  706. lpTemp->Release();
  707. }
  708. // Time to connect
  709. hr = m__dxj_DirectPlayClient->Connect(&desc, lpAddress, lpDevice, NULL, NULL, UserData, (DWORD)UserDataSize, NULL, dpAsync, (DWORD) lFlags);
  710. if (dpAsync)
  711. {
  712. *hAsyncHandle = (long)*dpAsync;
  713. SAFE_DELETE(dpAsync);
  714. }
  715. if ((hr != DPNERR_PENDING) && FAILED(hr))
  716. return hr;
  717. }
  718. __except(EXCEPTION_EXECUTE_HANDLER)
  719. {
  720. return E_FAIL;
  721. }
  722. return S_OK;
  723. }
  724. HRESULT C_dxj_DirectPlayClientObject::Send(SAFEARRAY **Buffer, long lTimeOut,long lFlags, long *hAsyncHandle)
  725. {
  726. HRESULT hr;
  727. DPN_BUFFER_DESC lpBuf;
  728. DWORD dwBufSize = ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements;
  729. DPNHANDLE *dpAsync = NULL;
  730. __try {
  731. DPF(1,"-----Entering (DPlayClient) SendTo call...\n");
  732. if (!(lFlags & DPNSEND_SYNC))
  733. {
  734. dpAsync = new DPNHANDLE;
  735. if (!dpAsync)
  736. return E_OUTOFMEMORY;
  737. }
  738. lpBuf.dwBufferSize = dwBufSize;
  739. lpBuf.pBufferData = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  740. hr = m__dxj_DirectPlayClient->Send(&lpBuf, 1, (DWORD) lTimeOut, NULL, dpAsync, (DWORD) lFlags);
  741. if (dpAsync)
  742. {
  743. *hAsyncHandle = (long)*dpAsync;
  744. SAFE_DELETE(dpAsync);
  745. }
  746. if ((hr != DPNERR_PENDING) && FAILED(hr))
  747. return hr;
  748. }
  749. __except(EXCEPTION_EXECUTE_HANDLER)
  750. {
  751. return E_FAIL;
  752. }
  753. return S_OK;
  754. }
  755. HRESULT C_dxj_DirectPlayClientObject::GetSendQueueInfo(long *lNumMsgs, long *lNumBytes, long lFlags)
  756. {
  757. HRESULT hr;
  758. __try {
  759. DPF(1,"-----Entering (DPlayClient) GetSendQueueInfo call...\n");
  760. if (FAILED (hr = m__dxj_DirectPlayClient->GetSendQueueInfo((DWORD*)lNumMsgs, (DWORD*)lNumBytes, (DWORD) lFlags) ) )
  761. return hr;
  762. }
  763. __except(EXCEPTION_EXECUTE_HANDLER)
  764. {
  765. return E_FAIL;
  766. }
  767. return S_OK;
  768. }
  769. HRESULT C_dxj_DirectPlayClientObject::GetApplicationDesc(long lFlags, DPN_APPLICATION_DESC_CDESC *ret)
  770. {
  771. HRESULT hr;
  772. DWORD dwSize = 0;
  773. DPN_APPLICATION_DESC *desc = NULL;
  774. __try {
  775. DPF(1,"-----Entering (DPlayClient) GetApplicationDesc call...\n");
  776. hr= m__dxj_DirectPlayClient->GetApplicationDesc(NULL, &dwSize, (DWORD) lFlags);
  777. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  778. return hr;
  779. desc = (DPN_APPLICATION_DESC*)new BYTE[dwSize];
  780. if (!desc)
  781. return E_OUTOFMEMORY;
  782. if (!dwSize)
  783. return E_FAIL;
  784. desc->dwSize = sizeof(DPN_APPLICATION_DESC);
  785. hr= m__dxj_DirectPlayClient->GetApplicationDesc(desc, &dwSize, (DWORD) lFlags);
  786. if( FAILED(hr))
  787. return hr;
  788. // Now return the vals
  789. ret->lSize = dwSize;
  790. ret->lFlags = desc->dwFlags;
  791. ret->guidInstance = GUIDtoBSTR(&desc->guidInstance);
  792. ret->guidApplication = GUIDtoBSTR(&desc->guidApplication);
  793. ret->lMaxPlayers = desc->dwMaxPlayers;
  794. ret->lCurrentPlayers = desc->dwCurrentPlayers;
  795. ret->SessionName = SysAllocString(desc->pwszSessionName);
  796. ret->Password = SysAllocString(desc->pwszPassword);
  797. SAFE_DELETE(desc);
  798. }
  799. __except(EXCEPTION_EXECUTE_HANDLER)
  800. {
  801. return E_FAIL;
  802. }
  803. return S_OK;
  804. }
  805. HRESULT C_dxj_DirectPlayClientObject::SetClientInfo(DPN_PLAYER_INFO_CDESC *PlayerInfo,long lFlags, long *hAsyncHandle)
  806. {
  807. HRESULT hr;
  808. DPN_PLAYER_INFO dpInfo;
  809. DPNHANDLE *dpAsync = NULL;
  810. __try {
  811. if (!(lFlags & DPNSEND_SYNC))
  812. {
  813. dpAsync = new DPNHANDLE;
  814. if (!dpAsync)
  815. return E_OUTOFMEMORY;
  816. }
  817. DPF(1,"-----Entering (DPlayClient) SetClientInfo call...\n");
  818. ZeroMemory(&dpInfo, sizeof(DPN_PLAYER_INFO) );
  819. dpInfo.dwSize = sizeof(DPN_PLAYER_INFO);
  820. dpInfo.dwInfoFlags = PlayerInfo->lInfoFlags;
  821. dpInfo.pwszName = PlayerInfo->Name;
  822. dpInfo.dwPlayerFlags = PlayerInfo->lPlayerFlags;
  823. hr = m__dxj_DirectPlayClient->SetClientInfo(&dpInfo, NULL, dpAsync, (DWORD) lFlags);
  824. if (dpAsync)
  825. {
  826. *hAsyncHandle = (long)*dpAsync;
  827. SAFE_DELETE(dpAsync);
  828. }
  829. if ((hr != DPNERR_PENDING) && FAILED(hr))
  830. return hr;
  831. }
  832. __except(EXCEPTION_EXECUTE_HANDLER)
  833. {
  834. return E_FAIL;
  835. }
  836. return S_OK;
  837. }
  838. HRESULT C_dxj_DirectPlayClientObject::GetServerInfo(long lFlags, DPN_PLAYER_INFO_CDESC *layerInfo)
  839. {
  840. HRESULT hr;
  841. DWORD dwSize = 0;
  842. DPN_PLAYER_INFO *PlayerInfo = NULL;
  843. __try {
  844. DPF(1,"-----Entering (DPlayClient) GetServerInfo call...\n");
  845. hr = m__dxj_DirectPlayClient->GetServerInfo( NULL, &dwSize, (DWORD) lFlags );
  846. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  847. return hr;
  848. PlayerInfo = (DPN_PLAYER_INFO*) new BYTE[ dwSize ];
  849. if (!PlayerInfo)
  850. return E_OUTOFMEMORY;
  851. if (!dwSize)
  852. return E_FAIL;
  853. ZeroMemory( PlayerInfo, dwSize );
  854. PlayerInfo->dwSize = sizeof(DPN_PLAYER_INFO);
  855. hr = m__dxj_DirectPlayClient->GetServerInfo(PlayerInfo, &dwSize, (DWORD) lFlags );
  856. if( FAILED(hr) )
  857. return hr;
  858. layerInfo->lSize = sizeof(DPN_PLAYER_INFO_CDESC);
  859. layerInfo->lInfoFlags = PlayerInfo->dwInfoFlags;
  860. layerInfo->Name = SysAllocString(PlayerInfo->pwszName);
  861. layerInfo->lPlayerFlags = PlayerInfo->dwPlayerFlags;
  862. }
  863. __except(EXCEPTION_EXECUTE_HANDLER)
  864. {
  865. return E_FAIL;
  866. }
  867. return S_OK;
  868. }
  869. HRESULT C_dxj_DirectPlayClientObject::Close(long lFlags)
  870. {
  871. HRESULT hr;
  872. BOOL bGotMsg = FALSE;
  873. BOOL bWait = FALSE;
  874. DWORD dwObj = 0;
  875. int i=0;
  876. MSG msg;
  877. __try {
  878. DPF(1,"-----Entering (DPlayClient) Close call...\n");
  879. FlushBuffer(0);
  880. HANDLE hThread = NULL;
  881. DWORD dwThread = 0;
  882. hThread = CreateThread(NULL, 0, &CloseClientThreadProc, this->m__dxj_DirectPlayClient, 0, &dwThread);
  883. msg.message = WM_NULL;
  884. while ((WM_QUIT != msg.message) && (!bWait))
  885. {
  886. bGotMsg = PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE);
  887. i++;
  888. if ((!bGotMsg) || (i>10))
  889. {
  890. dwObj = WaitForSingleObject(hThread, 10);
  891. bWait = (dwObj == WAIT_OBJECT_0);
  892. i = 0;
  893. }
  894. if (bGotMsg)
  895. {
  896. TranslateMessage( &msg );
  897. DispatchMessage( &msg );
  898. }
  899. bGotMsg = FALSE;
  900. }
  901. }
  902. __except(EXCEPTION_EXECUTE_HANDLER)
  903. {
  904. return E_FAIL;
  905. }
  906. return S_OK;
  907. }
  908. HRESULT C_dxj_DirectPlayClientObject::ReturnBuffer(long lBufferHandle)
  909. {
  910. HRESULT hr;
  911. __try {
  912. DPF(1,"-----Entering (DPlayClient) ReturnBuffer call...\n");
  913. if (FAILED(hr = m__dxj_DirectPlayClient->ReturnBuffer( (DPNHANDLE) lBufferHandle, 0 ) ) )
  914. return hr;
  915. }
  916. __except(EXCEPTION_EXECUTE_HANDLER)
  917. {
  918. return E_FAIL;
  919. }
  920. return S_OK;
  921. }
  922. HRESULT C_dxj_DirectPlayClientObject::GetCaps(long lFlags, DPNCAPS_CDESC *ret)
  923. {
  924. HRESULT hr;
  925. __try {
  926. DPF(1,"-----Entering (DPlayClient) GetCaps call...\n");
  927. ret->lSize = sizeof(DPN_CAPS);
  928. if (FAILED (hr=m__dxj_DirectPlayClient->GetCaps( (DPN_CAPS*) ret, (DWORD) lFlags) ) )
  929. return hr;
  930. }
  931. __except(EXCEPTION_EXECUTE_HANDLER)
  932. {
  933. return E_FAIL;
  934. }
  935. return S_OK;
  936. }
  937. HRESULT C_dxj_DirectPlayClientObject::SetCaps(DPNCAPS_CDESC *Caps, long lFlags)
  938. {
  939. HRESULT hr;
  940. __try {
  941. DPF(1,"-----Entering (DPlayClient) SetCaps call...\n");
  942. if (FAILED( hr = m__dxj_DirectPlayClient->SetCaps((DPN_CAPS*)Caps, (DWORD)lFlags)))
  943. return hr;
  944. }
  945. __except(EXCEPTION_EXECUTE_HANDLER)
  946. {
  947. return E_FAIL;
  948. }
  949. return S_OK;
  950. }
  951. HRESULT C_dxj_DirectPlayClientObject::GetCountServiceProviders(long lFlags, long *ret)
  952. {
  953. HRESULT hr;
  954. __try {
  955. DPF(1,"-----Entering (DPlayClient) GetCountServiceProviders call...\n");
  956. if (!m_SPInfo)
  957. if (FAILED (hr=GetSP(lFlags) ) )
  958. return hr;
  959. *ret = (long)m_dwSPCount;
  960. }
  961. __except(EXCEPTION_EXECUTE_HANDLER)
  962. {
  963. return E_FAIL;
  964. }
  965. return S_OK;
  966. }
  967. HRESULT C_dxj_DirectPlayClientObject::GetServiceProvider(long lIndex, DPN_SERVICE_PROVIDER_INFO_CDESC *ret)
  968. {
  969. HRESULT hr;
  970. __try {
  971. DPF(1,"-----Entering (DPlayClient) GetServiceProvider call...\n");
  972. if (!m_SPInfo)
  973. if (FAILED (hr=GetSP(0) ) )
  974. return hr;
  975. if ((lIndex < 1 ) || ((DWORD)lIndex > m_dwSPCount))
  976. return E_INVALIDARG;
  977. // Fill out our structure
  978. ret->lFlags = (long) m_SPInfo[lIndex-1].dwFlags;
  979. ret->Name = SysAllocString(m_SPInfo[lIndex-1].pwszName);
  980. ret->Guid = GUIDtoBSTR(&m_SPInfo[lIndex-1].guid);
  981. }
  982. __except(EXCEPTION_EXECUTE_HANDLER)
  983. {
  984. return E_FAIL;
  985. }
  986. return S_OK;
  987. }
  988. HRESULT C_dxj_DirectPlayClientObject::GetSP(long lFlags)
  989. {
  990. // Enumerate all DirectPlay sevice providers
  991. HRESULT hr;
  992. DWORD dwSize=0;
  993. DWORD dwItems=0;
  994. __try {
  995. DPF(1,"-----Entering (DPlayClient) GetSP call...\n");
  996. SAFE_DELETE(m_SPInfo);
  997. hr = m__dxj_DirectPlayClient->EnumServiceProviders( NULL, NULL, m_SPInfo, &dwSize,
  998. &dwItems, (DWORD) lFlags );
  999. if( FAILED(hr) && hr != DPNERR_BUFFERTOOSMALL)
  1000. return hr;
  1001. m_SPInfo = (DPN_SERVICE_PROVIDER_INFO*) new BYTE[dwSize];
  1002. if (!m_SPInfo)
  1003. return E_OUTOFMEMORY;
  1004. if( FAILED( hr = m__dxj_DirectPlayClient->EnumServiceProviders( NULL, NULL, m_SPInfo, &dwSize,
  1005. &dwItems, (DWORD) lFlags) ) )
  1006. return hr;
  1007. m_dwSPCount = dwItems;
  1008. }
  1009. __except(EXCEPTION_EXECUTE_HANDLER)
  1010. {
  1011. return E_FAIL;
  1012. }
  1013. return S_OK;
  1014. }
  1015. HRESULT C_dxj_DirectPlayClientObject::RegisterLobby(long dpnHandle, I_dxj_DirectPlayLobbiedApplication *LobbyApp, long lFlags)
  1016. {
  1017. HRESULT hr;
  1018. __try {
  1019. DPF(1,"-----Entering (DPlayClient) RegisterLobby call...\n");
  1020. DO_GETOBJECT_NOTNULL( IDirectPlay8LobbiedApplication*, lpLobby, LobbyApp);
  1021. if (FAILED( hr = m__dxj_DirectPlayClient->RegisterLobby((DPNHANDLE) dpnHandle, lpLobby,(DWORD) lFlags) ) )
  1022. return hr;
  1023. }
  1024. __except(EXCEPTION_EXECUTE_HANDLER)
  1025. {
  1026. return E_FAIL;
  1027. }
  1028. return S_OK;
  1029. }
  1030. HRESULT C_dxj_DirectPlayClientObject::GetConnectionInfo(long lFlags, DPN_CONNECTION_INFO_CDESC *pdpConnectionInfo)
  1031. {
  1032. HRESULT hr;
  1033. __try {
  1034. DPF(1,"-----Entering (DPlayClient) GetConnectionInfo call...\n");
  1035. pdpConnectionInfo->lSize = sizeof(DPN_CONNECTION_INFO);
  1036. if (FAILED( hr = m__dxj_DirectPlayClient->GetConnectionInfo((DPN_CONNECTION_INFO*)pdpConnectionInfo, (DWORD) lFlags) ) )
  1037. return hr;
  1038. }
  1039. __except(EXCEPTION_EXECUTE_HANDLER)
  1040. {
  1041. return E_FAIL;
  1042. }
  1043. return S_OK;
  1044. }
  1045. HRESULT C_dxj_DirectPlayClientObject::GetServerAddress(long lFlags, I_dxj_DirectPlayAddress **pAddress)
  1046. {
  1047. IDirectPlay8Address *lpAdd = NULL;
  1048. HRESULT hr;
  1049. __try {
  1050. DPF(1,"-----Entering (DPlayClient) GetServerAddress call...\n");
  1051. if (FAILED (hr = m__dxj_DirectPlayClient->GetServerAddress( &lpAdd, (DWORD) lFlags) ) )
  1052. return hr;
  1053. INTERNAL_CREATE_ADDRESS(_dxj_DirectPlayAddress,lpAdd, pAddress);
  1054. }
  1055. __except(EXCEPTION_EXECUTE_HANDLER)
  1056. {
  1057. return E_FAIL;
  1058. }
  1059. return S_OK;
  1060. }
  1061. HRESULT C_dxj_DirectPlayClientObject::SetSPCaps(BSTR guidSP, DPN_SP_CAPS_CDESC *spCaps, long lFlags)
  1062. {
  1063. HRESULT hr;
  1064. GUID guidServiceProvider;
  1065. __try {
  1066. DPF(1,"-----Entering (DPlayClient) SetSPCaps call...\n");
  1067. if (FAILED(hr = DPLAYBSTRtoGUID(&guidServiceProvider, guidSP) ) )
  1068. return hr;
  1069. spCaps->lSize = sizeof(DPN_SP_CAPS);
  1070. //
  1071. // MiNara: Added 0 for dwFlags parameter
  1072. //
  1073. if (FAILED(hr = m__dxj_DirectPlayClient->SetSPCaps(&guidServiceProvider,(DPN_SP_CAPS*)spCaps,(DWORD) lFlags) ) )
  1074. return hr;
  1075. }
  1076. __except(EXCEPTION_EXECUTE_HANDLER)
  1077. {
  1078. return E_FAIL;
  1079. }
  1080. return S_OK;
  1081. }
  1082. HRESULT C_dxj_DirectPlayClientObject::GetSPCaps(BSTR guidSP, long lFlags, DPN_SP_CAPS_CDESC *spCaps)
  1083. {
  1084. HRESULT hr;
  1085. GUID guidServiceProvider;
  1086. __try {
  1087. DPF(1,"-----Entering (DPlayClient) GetSPCaps call...\n");
  1088. spCaps->lSize = sizeof(DPN_SP_CAPS);
  1089. if (FAILED(hr = DPLAYBSTRtoGUID(&guidServiceProvider, guidSP) ) )
  1090. return hr;
  1091. if (FAILED(hr = m__dxj_DirectPlayClient->GetSPCaps(&guidServiceProvider,(DPN_SP_CAPS*)spCaps, (DWORD) lFlags) ) )
  1092. return hr;
  1093. }
  1094. __except(EXCEPTION_EXECUTE_HANDLER)
  1095. {
  1096. return E_FAIL;
  1097. }
  1098. return S_OK;
  1099. }
  1100. HRESULT C_dxj_DirectPlayClientObject::RegisterMessageHandler(I_dxj_DirectPlayEvent *event)
  1101. {
  1102. HRESULT hr=S_OK;
  1103. LPSTREAM pStm=NULL;
  1104. DPF(1,"-----Entering (DPlayClient) RegisterMessageHandler call...\n");
  1105. if (!event) return E_INVALIDARG;
  1106. if (!m_fHandleEvents)
  1107. {
  1108. DPF(1,"-----(DPlayClient) RegisterMessageHandler call (We are not handling events currently)...\n");
  1109. if (m_pEventStream)
  1110. m_pEventStream->Release();
  1111. DPF(1,"-----(DPlayClient) RegisterMessageHandler call (CreateStream)...\n");
  1112. hr = CreateStreamOnHGlobal(NULL, TRUE, &pStm);
  1113. if FAILED(hr) return hr;
  1114. DPF(1,"-----(DPlayClient) RegisterMessageHandler call (Marshall VB Event interface)...\n");
  1115. hr = CoMarshalInterface(pStm, IID_I_dxj_DirectPlayEvent, event, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLEWEAK);
  1116. if FAILED(hr) return hr;
  1117. // Now we need to set the seek location of the stream to the beginning
  1118. LARGE_INTEGER l;
  1119. l.QuadPart = 0;
  1120. pStm->Seek(l, STREAM_SEEK_SET, NULL);
  1121. m_pEventStream=pStm;
  1122. DPF(1,"-----(DPlayClient) RegisterMessageHandler call (Call DPlayInit)...\n");
  1123. if (!m_fInit)
  1124. {
  1125. if (FAILED ( hr = m__dxj_DirectPlayClient->Initialize( this, DirectPlayClientMessageHandler, 0 ) ) )
  1126. return hr;
  1127. m_fInit = TRUE;
  1128. }
  1129. m_fHandleEvents = TRUE;
  1130. }
  1131. else
  1132. return DPNERR_ALREADYINITIALIZED;
  1133. return hr;
  1134. }
  1135. HRESULT C_dxj_DirectPlayClientObject::UnRegisterMessageHandler()
  1136. {
  1137. DPF(1,"-----Entering (DPlayClient) UnregisterMessageHandler call...\n");
  1138. m_fHandleEvents = FALSE;
  1139. //Clear out the messages currently waiting
  1140. FlushBuffer(0);
  1141. return S_OK;
  1142. }
  1143. HRESULT C_dxj_DirectPlayClientObject::FlushBuffer(LONG dwNumMessagesLeft)
  1144. {
  1145. DWORD dwTime = GetTickCount();
  1146. DPF(1,"-----Entering (DPlayClient) FlushBuffer call...\n");
  1147. //Clear out the messages currently waiting
  1148. while (m_dwMsgCount > dwNumMessagesLeft)
  1149. {
  1150. if (GetTickCount() - dwTime > 5000)
  1151. {
  1152. // Don't let FlushBuffer wait more than 5 seconds
  1153. DPF1(1,"-----Leaving (DPlayClient) FlushBuffer call (All messages *not* flushed - %d remained)...\n", m_dwMsgCount);
  1154. return S_OK;
  1155. }
  1156. }
  1157. DPF(1,"-----Leaving (DPlayClient) FlushBuffer call (All messages flushed)...\n");
  1158. return S_OK;
  1159. }
  1160. DWORD WINAPI CloseClientThreadProc(void* lpParam)
  1161. {
  1162. // User context for the message handler is a pointer to our class module.
  1163. IDirectPlay8Client *lpPeer = (IDirectPlay8Client*)lpParam;
  1164. DPF(1,"-----Entering (DplayPeer) CloseClientThreadProc call...\n");
  1165. lpPeer->Close(0);
  1166. DPF(1,"-----Leaving (DplayPeer) CloseClientThreadProc call ...\n");
  1167. return 0;
  1168. }