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.

642 lines
21 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Client.cpp
  6. * Content: DNET client interface routines
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/21/99 mjn Created
  12. * 01/06/99 mjn Moved NameTable stuff to NameTable.h
  13. * 01/28/00 mjn Implemented ReturnBuffer in API
  14. * 02/01/00 mjn Implemented GetCaps and SetCaps in API
  15. * 02/15/00 mjn Implement INFO flags in SetClientInfo
  16. * 02/18/00 mjn Converted DNADDRESS to IDirectPlayAddress8
  17. * 03/17/00 rmt Added new caps functions
  18. * 04/06/00 mjn Added GetServerAddress to API
  19. * 04/16/00 mjn DNSendMessage uses CAsyncOp
  20. * 04/17/00 rmt Added more param validation
  21. * rmt Removed required for connection from Get/SetInfo / GetAddress
  22. * 04/19/00 mjn Send API call accepts a range of DPN_BUFFER_DESCs and a count
  23. * 04/20/00 mjn DN_Send() calls DN_SendTo() with DPNID=0
  24. * 04/24/00 mjn Updated Group and Info operations to use CAsyncOp's
  25. * 04/28/00 mjn Updated DN_GetHostSendQueueInfo() to use CAsyncOp's
  26. * 05/03/00 mjn Use GetHostPlayerRef() rather than GetHostPlayer()
  27. * 05/31/00 mjn Added operation specific SYNC flags
  28. * 06/23/00 mjn Removed dwPriority from Send() API call
  29. * 06/27/00 mjn Allow priorities to be specified to GetSendQueueInfo() API call
  30. * 06/27/00 mjn Added DN_ClientConnect() (without pvPlayerContext)
  31. * mjn Allow mix-n-match of priorities in GetSendQueueInfo() API call
  32. * 07/09/00 mjn Cleaned up DN_SetClientInfo()
  33. * 07/09/00 rmt Bug #38323 - RegisterLobby needs a DPNHANDLE parameter.
  34. * 07/21/2000 RichGr IA64: Use %p format specifier for 32/64-bit pointers.
  35. * 10/11/00 mjn Take locks for CNameTableEntry::PackInfo()
  36. * 01/22/01 mjn Check for closing instead of disconnecting in DN_GetServerInfo()
  37. * 07/24/01 mjn Added DPNBUILD_NOPARAMVAL compile flag
  38. *@@END_MSINTERNAL
  39. *
  40. ***************************************************************************/
  41. #include "dncorei.h"
  42. //**********************************************************************
  43. // Constant definitions
  44. //**********************************************************************
  45. //**********************************************************************
  46. // Macro definitions
  47. //**********************************************************************
  48. //**********************************************************************
  49. // Structure definitions
  50. //**********************************************************************
  51. //**********************************************************************
  52. // Variable definitions
  53. //**********************************************************************
  54. //
  55. // define appropriate types since these interface functions take 'void*' arguments!!
  56. //
  57. typedef STDMETHODIMP ClientQueryInterface( IDirectPlay8Client *pInterface, DP8REFIID riid, LPVOID *ppvObj );
  58. typedef STDMETHODIMP_(ULONG) ClientAddRef( IDirectPlay8Client *pInterface );
  59. typedef STDMETHODIMP_(ULONG) ClientRelease( IDirectPlay8Client *pInterface );
  60. typedef STDMETHODIMP ClientInitialize( IDirectPlay8Client *pInterface, LPVOID const lpvUserContext, const PFNDPNMESSAGEHANDLER lpfn, const DWORD dwFlags );
  61. typedef STDMETHODIMP ClientEnumServiceProviders( IDirectPlay8Client *pInterface,const GUID *const pguidServiceProvider,const GUID *const pguidApplication,DPN_SERVICE_PROVIDER_INFO *const pSPInfoBuffer,DWORD *const pcbEnumData,DWORD *const pcReturned,const DWORD dwFlags );
  62. typedef STDMETHODIMP ClientCancelAsyncOperation( IDirectPlay8Client *pInterface, const DPNHANDLE hAsyncHandle, const DWORD dwFlags );
  63. typedef STDMETHODIMP ClientConnect( IDirectPlay8Client *pInterface,const DPN_APPLICATION_DESC *const pdnAppDesc,IDirectPlay8Address *const pHostAddr,IDirectPlay8Address *const pDeviceInfo,const DPN_SECURITY_DESC *const pdnSecurity,const DPN_SECURITY_CREDENTIALS *const pdnCredentials,const void *const pvUserConnectData,const DWORD dwUserConnectDataSize,void *const pvAsyncContext,DPNHANDLE *const phAsyncHandle,const DWORD dwFlags);
  64. typedef STDMETHODIMP ClientGetApplicationDesc( IDirectPlay8Client *pInterface,DPN_APPLICATION_DESC *const pAppDescBuffer,DWORD *const lpcbDataSize,const DWORD dwFlags );
  65. typedef STDMETHODIMP ClientClose(IDirectPlay8Client *pInterface,const DWORD dwFlags);
  66. typedef STDMETHODIMP ClientEnumHosts( IDirectPlay8Client *pInterface,DPN_APPLICATION_DESC *const pApplicationDesc,IDirectPlay8Address *const dnaddrHost,IDirectPlay8Address *const dnaddrDeviceInfo,PVOID const pUserEnumData,const DWORD dwUserEnumDataSize,const DWORD dwRetryCount,const DWORD dwRetryInterval,const DWORD dwTimeOut,PVOID const pvUserContext,DPNHANDLE *const pAsyncHandle,const DWORD dwFlags );
  67. typedef STDMETHODIMP ClientReturnBuffer( IDirectPlay8Client *pInterface, const DPNHANDLE hBufferHandle,const DWORD dwFlags);
  68. typedef STDMETHODIMP ClientGetCaps(IDirectPlay8Client *pInterface,DPN_CAPS *const pdnCaps,const DWORD dwFlags);
  69. typedef STDMETHODIMP ClientSetCaps(IDirectPlay8Client *pInterface,const DPN_CAPS *const pdnCaps,const DWORD dwFlags);
  70. typedef STDMETHODIMP ClientSetSPCaps(IDirectPlay8Client *pInterface,const GUID * const pguidSP, const DPN_SP_CAPS *const pdpspCaps, const DWORD dwFlags );
  71. typedef STDMETHODIMP ClientGetSPCaps(IDirectPlay8Client *pInterface,const GUID * const pguidSP, DPN_SP_CAPS *const pdpspCaps,const DWORD dwFlags);
  72. typedef STDMETHODIMP ClientGetConnectionInfo(IDirectPlay8Client *pInterface,DPN_CONNECTION_INFO *const pdpConnectionInfo,const DWORD dwFlags);
  73. typedef STDMETHODIMP ClientRegisterLobby(IDirectPlay8Client *pInterface,const DPNHANDLE dpnHandle,IDirectPlay8LobbiedApplication *const pIDP8LobbiedApplication,const DWORD dwFlags);
  74. //
  75. // VTable for client interface
  76. //
  77. IDirectPlay8ClientVtbl DN_ClientVtbl =
  78. {
  79. (ClientQueryInterface*) DN_QueryInterface,
  80. (ClientAddRef*) DN_AddRef,
  81. (ClientRelease*) DN_Release,
  82. (ClientInitialize*) DN_Initialize,
  83. (ClientEnumServiceProviders*) DN_EnumServiceProviders,
  84. (ClientEnumHosts*) DN_EnumHosts,
  85. (ClientCancelAsyncOperation*) DN_CancelAsyncOperation,
  86. /*(ClientConnect*)*/ DN_ClientConnect,
  87. DN_Send,
  88. /*(ClientGetSendQueueInfo*)*/ DN_GetHostSendQueueInfo,
  89. (ClientGetApplicationDesc*) DN_GetApplicationDesc,
  90. DN_SetClientInfo,
  91. DN_GetServerInfo,
  92. DN_GetServerAddress,
  93. (ClientClose*) DN_Close,
  94. (ClientReturnBuffer*) DN_ReturnBuffer,
  95. (ClientGetCaps*) DN_GetCaps,
  96. (ClientSetCaps*) DN_SetCaps,
  97. (ClientSetSPCaps*) DN_SetSPCaps,
  98. (ClientGetSPCaps*) DN_GetSPCaps,
  99. (ClientGetConnectionInfo*) DN_GetServerConnectionInfo,
  100. (ClientRegisterLobby*) DN_RegisterLobby
  101. };
  102. //**********************************************************************
  103. // Function prototypes
  104. //**********************************************************************
  105. //**********************************************************************
  106. // Function definitions
  107. //**********************************************************************
  108. #undef DPF_MODNAME
  109. #define DPF_MODNAME "DN_Send"
  110. STDMETHODIMP DN_Send( IDirectPlay8Client *pInterface,
  111. const DPN_BUFFER_DESC *const prgBufferDesc,
  112. const DWORD cBufferDesc,
  113. const DWORD dwTimeOut,
  114. const PVOID pvAsyncContext,
  115. DPNHANDLE *const phAsyncHandle,
  116. const DWORD dwFlags)
  117. {
  118. return( DN_SendTo( pInterface,
  119. 0, // DN_SendTo should translate this call to the Host player
  120. prgBufferDesc,
  121. cBufferDesc,
  122. dwTimeOut,
  123. pvAsyncContext,
  124. phAsyncHandle,
  125. dwFlags ) );
  126. }
  127. // DN_ClientConnect
  128. //
  129. // Call DN_Connect, but with no PlayerContext
  130. STDMETHODIMP DN_ClientConnect(IDirectPlay8Client *pInterface,
  131. const DPN_APPLICATION_DESC *const pdnAppDesc,
  132. IDirectPlay8Address *const pHostAddr,
  133. IDirectPlay8Address *const pDeviceInfo,
  134. const DPN_SECURITY_DESC *const pdnSecurity,
  135. const DPN_SECURITY_CREDENTIALS *const pdnCredentials,
  136. const void *const pvUserConnectData,
  137. const DWORD dwUserConnectDataSize,
  138. void *const pvAsyncContext,
  139. DPNHANDLE *const phAsyncHandle,
  140. const DWORD dwFlags)
  141. {
  142. return( DN_Connect( pInterface,
  143. pdnAppDesc,
  144. pHostAddr,
  145. pDeviceInfo,
  146. pdnSecurity,
  147. pdnCredentials,
  148. pvUserConnectData,
  149. dwUserConnectDataSize,
  150. NULL,
  151. pvAsyncContext,
  152. phAsyncHandle,
  153. dwFlags ) );
  154. }
  155. // DN_SetClientInfo
  156. //
  157. // Set the info for the client player and propagate to server
  158. #undef DPF_MODNAME
  159. #define DPF_MODNAME "DN_SetClientInfo"
  160. STDMETHODIMP DN_SetClientInfo(IDirectPlay8Client *pInterface,
  161. const DPN_PLAYER_INFO *const pdpnPlayerInfo,
  162. const PVOID pvAsyncContext,
  163. DPNHANDLE *const phAsyncHandle,
  164. const DWORD dwFlags)
  165. {
  166. DIRECTNETOBJECT *pdnObject;
  167. HRESULT hResultCode;
  168. DPNHANDLE hAsyncOp;
  169. PWSTR pwszName;
  170. DWORD dwNameSize;
  171. PVOID pvData;
  172. DWORD dwDataSize;
  173. CNameTableEntry *pLocalPlayer;
  174. BOOL fConnected;
  175. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p], pdpnPlayerInfo [0x%p], pvAsyncContext [0x%p], phAsyncHandle [0x%p], dwFlags [0x%lx]",
  176. pInterface,pdpnPlayerInfo,pvAsyncContext,phAsyncHandle,dwFlags);
  177. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  178. DNASSERT(pdnObject != NULL);
  179. #ifndef DPNBUILD_NOPARAMVAL
  180. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  181. {
  182. if( FAILED( hResultCode = DN_ValidateSetClientInfo( pInterface , pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags ) ) )
  183. {
  184. DPFX(DPFPREP, 0, "Error validating setclientinfo params hr=[0x%lx]", hResultCode );
  185. DPF_RETURN( hResultCode );
  186. }
  187. }
  188. #endif // !DPNBUILD_NOPARAMVAL
  189. // Check to ensure message handler registered
  190. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  191. {
  192. DPFERR( "Object is not initialized" );
  193. DPF_RETURN(DPNERR_UNINITIALIZED);
  194. }
  195. pLocalPlayer = NULL;
  196. if ((pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) && (pdpnPlayerInfo->pwszName))
  197. {
  198. pwszName = pdpnPlayerInfo->pwszName;
  199. dwNameSize = (wcslen(pwszName) + 1) * sizeof(WCHAR);
  200. }
  201. else
  202. {
  203. pwszName = NULL;
  204. dwNameSize = 0;
  205. }
  206. if ((pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) && (pdpnPlayerInfo->pvData) && (pdpnPlayerInfo->dwDataSize))
  207. {
  208. pvData = pdpnPlayerInfo->pvData;
  209. dwDataSize = pdpnPlayerInfo->dwDataSize;
  210. }
  211. else
  212. {
  213. pvData = NULL;
  214. dwDataSize = 0;
  215. }
  216. //
  217. // If we are connected, we will request the Host to update us.
  218. // Otherwise, we will just update the DefaultPlayer.
  219. //
  220. DNEnterCriticalSection(&pdnObject->csDirectNetObject);
  221. if (pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTED)
  222. {
  223. fConnected = TRUE;
  224. }
  225. else
  226. {
  227. fConnected = FALSE;
  228. }
  229. DNLeaveCriticalSection(&pdnObject->csDirectNetObject);
  230. if (fConnected)
  231. {
  232. if ((hResultCode = pdnObject->NameTable.GetLocalPlayerRef( &pLocalPlayer )) != DPN_OK)
  233. {
  234. DPFERR( "Could not get local player reference" );
  235. DisplayDNError(0,hResultCode);
  236. goto Failure;
  237. }
  238. DPFX(DPFPREP, 3,"Request host to update client info");
  239. hResultCode = DNRequestUpdateInfo( pdnObject,
  240. pLocalPlayer->GetDPNID(),
  241. pwszName,
  242. dwNameSize,
  243. pvData,
  244. dwDataSize,
  245. pdpnPlayerInfo->dwInfoFlags,
  246. pvAsyncContext,
  247. &hAsyncOp,
  248. dwFlags);
  249. if (hResultCode != DPN_OK && hResultCode != DPNERR_PENDING)
  250. {
  251. DPFERR("Could not request host to update client info");
  252. }
  253. else
  254. {
  255. if (!(dwFlags & DPNSETCLIENTINFO_SYNC))
  256. {
  257. DPFX(DPFPREP, 3,"Async Handle [0x%lx]",hAsyncOp);
  258. *phAsyncHandle = hAsyncOp;
  259. }
  260. }
  261. pLocalPlayer->Release();
  262. pLocalPlayer = NULL;
  263. }
  264. else
  265. {
  266. DNASSERT(pdnObject->NameTable.GetDefaultPlayer() != NULL);
  267. // This function takes the lock internally
  268. pdnObject->NameTable.GetDefaultPlayer()->UpdateEntryInfo(pwszName,dwNameSize,pvData,dwDataSize,pdpnPlayerInfo->dwInfoFlags, FALSE);
  269. hResultCode = DPN_OK;
  270. }
  271. Exit:
  272. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  273. return(hResultCode);
  274. Failure:
  275. if (pLocalPlayer)
  276. {
  277. pLocalPlayer->Release();
  278. pLocalPlayer = NULL;
  279. }
  280. goto Exit;
  281. }
  282. // DN_GetServerInfo
  283. //
  284. // Retrieve server info from the local nametable.
  285. #undef DPF_MODNAME
  286. #define DPF_MODNAME "DN_GetServerInfo"
  287. STDMETHODIMP DN_GetServerInfo(IDirectPlay8Client *pInterface,
  288. DPN_PLAYER_INFO *const pdpnPlayerInfo,
  289. DWORD *const pdwSize,
  290. const DWORD dwFlags)
  291. {
  292. DIRECTNETOBJECT *pdnObject;
  293. HRESULT hResultCode;
  294. CPackedBuffer packedBuffer;
  295. CNameTableEntry *pHostPlayer;
  296. DPFX(DPFPREP, 3,"Parameters: pInterface [0x%p], pdpnPlayerInfo [0x%p], pdwSize [%p], dwFlags [0x%lx]",
  297. pInterface,pdpnPlayerInfo,pdwSize,dwFlags);
  298. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  299. DNASSERT(pdnObject != NULL);
  300. #ifndef DPNBUILD_NOPARAMVAL
  301. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  302. {
  303. if( FAILED( hResultCode = DN_ValidateGetServerInfo( pInterface , pdpnPlayerInfo, pdwSize, dwFlags ) ) )
  304. {
  305. DPFX(DPFPREP, 0, "Error validating get server info hr=[0x%lx]", hResultCode );
  306. DPF_RETURN( hResultCode );
  307. }
  308. }
  309. #endif // !DPNBUILD_NOPARAMVAL
  310. // Check to ensure message handler registered
  311. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  312. {
  313. DPFERR( "Object is not initialized" );
  314. DPF_RETURN(DPNERR_UNINITIALIZED);
  315. }
  316. if( pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING )
  317. {
  318. DPFERR("Object is connecting / starting to host" );
  319. DPF_RETURN(DPNERR_CONNECTING);
  320. }
  321. if ( !(pdnObject->dwFlags & (DN_OBJECT_FLAG_CONNECTED | DN_OBJECT_FLAG_CLOSING | DN_OBJECT_FLAG_DISCONNECTING) ) )
  322. {
  323. DPFERR("You must be connected / disconnecting to use this function" );
  324. DPF_RETURN(DPNERR_NOCONNECTION);
  325. }
  326. pHostPlayer = NULL;
  327. if ((hResultCode = pdnObject->NameTable.GetHostPlayerRef(&pHostPlayer)) != DPN_OK)
  328. {
  329. DPFERR("Could not find Host player");
  330. DisplayDNError(0,hResultCode);
  331. goto Failure;
  332. }
  333. packedBuffer.Initialize(pdpnPlayerInfo,*pdwSize);
  334. pHostPlayer->Lock();
  335. hResultCode = pHostPlayer->PackInfo(&packedBuffer);
  336. pHostPlayer->Unlock();
  337. pHostPlayer->Release();
  338. pHostPlayer = NULL;
  339. if ((hResultCode == DPN_OK) || (hResultCode == DPNERR_BUFFERTOOSMALL))
  340. {
  341. *pdwSize = packedBuffer.GetSizeRequired();
  342. }
  343. Exit:
  344. DPF_RETURN(hResultCode);
  345. Failure:
  346. if (pHostPlayer)
  347. {
  348. pHostPlayer->Release();
  349. pHostPlayer = NULL;
  350. }
  351. goto Exit;
  352. }
  353. #undef DPF_MODNAME
  354. #define DPF_MODNAME "DN_GetHostSendQueueInfo"
  355. STDMETHODIMP DN_GetHostSendQueueInfo(IDirectPlay8Client *pInterface,
  356. DWORD *const pdwNumMsgs,
  357. DWORD *const pdwNumBytes,
  358. const DWORD dwFlags )
  359. {
  360. DIRECTNETOBJECT *pdnObject;
  361. DWORD dwQueueFlags;
  362. DWORD dwNumMsgs;
  363. DWORD dwNumBytes;
  364. CNameTableEntry *pNTEntry;
  365. CConnection *pConnection;
  366. HRESULT hResultCode;
  367. DPFX(DPFPREP, 3,"Parameters : pInterface [0x%p], pdwNumMsgs [0x%p], pdwNumBytes [0x%p], dwFlags [0x%lx]",
  368. pInterface,pdwNumMsgs,pdwNumBytes,dwFlags);
  369. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  370. DNASSERT(pdnObject != NULL);
  371. #ifndef DPNBUILD_NOPARAMVAL
  372. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  373. {
  374. if( FAILED( hResultCode = DN_ValidateGetHostSendQueueInfo( pInterface , pdwNumMsgs, pdwNumBytes, dwFlags ) ) )
  375. {
  376. DPFX(DPFPREP, 0, "Error validating get server info hr=[0x%lx]", hResultCode );
  377. DPF_RETURN( hResultCode );
  378. }
  379. }
  380. #endif // !DPNBUILD_NOPARAMVAL
  381. // Check to ensure message handler registered
  382. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  383. {
  384. DPFERR( "Object is not initialized" );
  385. DPF_RETURN(DPNERR_UNINITIALIZED);
  386. }
  387. if( pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING )
  388. {
  389. DPFERR( "Object has not yet completed connecting / hosting" );
  390. DPF_RETURN(DPNERR_CONNECTING);
  391. }
  392. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTED) )
  393. {
  394. DPFERR("Object is not connected or hosting" );
  395. DPF_RETURN(DPNERR_NOCONNECTION);
  396. }
  397. pNTEntry = NULL;
  398. pConnection = NULL;
  399. //
  400. // Get CConnection object
  401. //
  402. #ifndef DPNBUILD_NOMULTICAST
  403. if (pdnObject->dwFlags & DN_OBJECT_FLAG_MULTICAST)
  404. {
  405. DNEnterCriticalSection(&pdnObject->csDirectNetObject);
  406. if (pdnObject->pMulticastSend != NULL)
  407. {
  408. pdnObject->pMulticastSend->AddRef();
  409. pConnection = pdnObject->pMulticastSend;
  410. }
  411. else
  412. {
  413. pConnection = NULL;
  414. }
  415. DNLeaveCriticalSection(&pdnObject->csDirectNetObject);
  416. if (pConnection == NULL)
  417. {
  418. DPFERR( "Couldn't retrieve multicast send connection" );
  419. hResultCode = DPNERR_INVALIDGROUP;
  420. goto Failure;
  421. }
  422. }
  423. else
  424. #endif // ! DPNBUILD_NOMULTICAST
  425. {
  426. if ((hResultCode = pdnObject->NameTable.GetHostPlayerRef( &pNTEntry )) != DPN_OK)
  427. {
  428. DPFX(DPFPREP, 0,"Could not find Host Player in NameTable");
  429. hResultCode = DPNERR_CONNECTIONLOST;
  430. goto Failure;
  431. }
  432. if ((hResultCode = pNTEntry->GetConnectionRef( &pConnection )) != DPN_OK)
  433. {
  434. hResultCode = DPNERR_CONNECTIONLOST;
  435. goto Failure;
  436. }
  437. pNTEntry->Release();
  438. pNTEntry = NULL;
  439. }
  440. //
  441. // Determine required queues
  442. //
  443. dwQueueFlags = dwFlags & (DPNGETSENDQUEUEINFO_PRIORITY_HIGH | DPNGETSENDQUEUEINFO_PRIORITY_NORMAL | DPNGETSENDQUEUEINFO_PRIORITY_LOW);
  444. if (dwQueueFlags == 0)
  445. {
  446. dwQueueFlags = (DPNGETSENDQUEUEINFO_PRIORITY_HIGH | DPNGETSENDQUEUEINFO_PRIORITY_NORMAL | DPNGETSENDQUEUEINFO_PRIORITY_LOW);
  447. }
  448. //
  449. // Extract required info
  450. //
  451. dwNumMsgs = 0;
  452. dwNumBytes = 0;
  453. pConnection->Lock();
  454. if (dwQueueFlags & DPNGETSENDQUEUEINFO_PRIORITY_HIGH)
  455. {
  456. dwNumMsgs += pConnection->GetHighQueueNum();
  457. dwNumBytes += pConnection->GetHighQueueBytes();
  458. }
  459. if (dwQueueFlags & DPNGETSENDQUEUEINFO_PRIORITY_NORMAL)
  460. {
  461. dwNumMsgs += pConnection->GetNormalQueueNum();
  462. dwNumBytes += pConnection->GetNormalQueueBytes();
  463. }
  464. if (dwQueueFlags & DPNGETSENDQUEUEINFO_PRIORITY_LOW)
  465. {
  466. dwNumMsgs += pConnection->GetLowQueueNum();
  467. dwNumBytes += pConnection->GetLowQueueBytes();
  468. }
  469. pConnection->Unlock();
  470. pConnection->Release();
  471. pConnection = NULL;
  472. if (pdwNumMsgs)
  473. {
  474. *pdwNumMsgs = dwNumMsgs;
  475. DPFX(DPFPREP, 3,"Setting: *pdwNumMsgs [%ld]",dwNumMsgs);
  476. }
  477. if (pdwNumBytes)
  478. {
  479. *pdwNumBytes = dwNumBytes;
  480. DPFX(DPFPREP, 3,"Setting: *pdwNumBytes [%ld]",dwNumBytes);
  481. }
  482. hResultCode = DPN_OK;
  483. Exit:
  484. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  485. return(hResultCode);
  486. Failure:
  487. if (pNTEntry)
  488. {
  489. pNTEntry->Release();
  490. pNTEntry = NULL;
  491. }
  492. if (pConnection)
  493. {
  494. pConnection->Release();
  495. pConnection = NULL;
  496. }
  497. goto Exit;
  498. }
  499. #undef DPF_MODNAME
  500. #define DPF_MODNAME "DN_GetServerAddress"
  501. STDMETHODIMP DN_GetServerAddress(IDirectPlay8Client *pInterface,
  502. IDirectPlay8Address **const ppAddress,
  503. const DWORD dwFlags)
  504. {
  505. DIRECTNETOBJECT *pdnObject;
  506. IDirectPlay8Address *pAddress;
  507. HRESULT hResultCode;
  508. CNameTableEntry *pHostPlayer;
  509. DPFX(DPFPREP, 3,"Parameters : pInterface [0x%p], ppAddress [0x%p], dwFlags [0x%lx]",
  510. pInterface,ppAddress,dwFlags);
  511. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  512. DNASSERT(pdnObject != NULL);
  513. #ifndef DPNBUILD_NOPARAMVAL
  514. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  515. {
  516. if( FAILED( hResultCode = DN_ValidateGetServerAddress( pInterface,ppAddress,dwFlags ) ) )
  517. {
  518. DPFX(DPFPREP, 0, "Error validating get server info hr=[0x%lx]", hResultCode );
  519. DPF_RETURN( hResultCode );
  520. }
  521. }
  522. #endif // !DPNBUILD_NOPARAMVAL
  523. // Check to ensure message handler registered
  524. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  525. {
  526. DPFERR( "Object is not initialized" );
  527. DPF_RETURN(DPNERR_UNINITIALIZED);
  528. }
  529. if( pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING )
  530. {
  531. DPFERR("Object is connecting / starting to host" );
  532. DPF_RETURN(DPNERR_CONNECTING);
  533. }
  534. if ( !(pdnObject->dwFlags & (DN_OBJECT_FLAG_CONNECTED | DN_OBJECT_FLAG_CLOSING | DN_OBJECT_FLAG_DISCONNECTING) ) )
  535. {
  536. DPFERR("You must be connected / disconnecting to use this function" );
  537. DPF_RETURN(DPNERR_NOCONNECTION);
  538. }
  539. pHostPlayer = NULL;
  540. if ((hResultCode = pdnObject->NameTable.GetHostPlayerRef( &pHostPlayer )) != DPN_OK)
  541. {
  542. DPFERR("Could not find Host player");
  543. DisplayDNError(0,hResultCode);
  544. goto Failure;
  545. }
  546. pAddress = pHostPlayer->GetAddress();
  547. DNASSERT(pAddress != NULL);
  548. hResultCode = IDirectPlay8Address_Duplicate(pAddress,ppAddress);
  549. pHostPlayer->Release();
  550. pHostPlayer = NULL;
  551. Exit:
  552. DPF_RETURN(hResultCode);
  553. Failure:
  554. if (pHostPlayer)
  555. {
  556. pHostPlayer->Release();
  557. pHostPlayer = NULL;
  558. }
  559. goto Exit;
  560. }