Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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