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.

539 lines
21 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: Peer.cpp
  6. * Content: DNET peer interface routines
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 07/21/99 mjn Created
  12. * 12/23/99 mjn Hand all NameTable update sends from Host to worker thread
  13. * 12/28/99 mjn Disconnect handling happens when disconnect finishes instead of starts
  14. * 12/28/99 mjn Moved Async Op stuff to Async.h
  15. * 01/04/00 mjn Added code to allow outstanding ops to complete at host migration
  16. * 01/06/00 mjn Moved NameTable stuff to NameTable.h
  17. * 01/11/00 mjn Moved connect/disconnect stuff to Connect.h
  18. * 01/14/00 mjn Added pvUserContext to Host API call
  19. * 01/16/00 mjn Moved User callback stuff to User.h
  20. * 01/22/00 mjn Implemented DestroyClient in API
  21. * 01/28/00 mjn Implemented ReturnBuffer in API
  22. * 02/01/00 mjn Implemented GetCaps and SetCaps in API
  23. * 02/01/00 mjn Implement Player/Group context values
  24. * 02/15/00 mjn Implement INFO flags in SetInfo and return context in GetInfo
  25. * 02/17/00 mjn Implemented GetPlayerContext and GetGroupContext
  26. * 03/17/00 rmt Added new caps functions
  27. * 04/04/00 mjn Added TerminateSession to API
  28. * 04/05/00 mjn Modified DestroyClient
  29. * 04/06/00 mjn Added GetPeerAddress to API
  30. * mjn Added GetHostAddress to API
  31. * 04/17/00 rmt Added more parameter validation
  32. * rmt Removed required for connection from Get/SetInfo / GetAddress
  33. * 04/19/00 mjn SendTo API call accepts a range of DPN_BUFFER_DESCs and a count
  34. * 04/24/00 mjn Updated Group and Info operations to use CAsyncOp's
  35. * 05/31/00 mjn Added operation specific SYNC flags
  36. * 06/23/00 mjn Removed dwPriority from SendTo() API call
  37. * 07/09/00 mjn Cleaned up DN_SetPeerInfo()
  38. * 07/09/00 rmt Bug #38323 - RegisterLobby needs a DPNHANDLE parameter.
  39. * 07/21/00 RichGr IA64: Use %p format specifier for 32/64-bit pointers.
  40. * 08/03/00 rmt Bug #41244 - Wrong return codes -- part 2
  41. * 09/13/00 mjn Fixed return value from DN_GetPeerAddress() if peer not found
  42. * 10/11/00 mjn Take locks for CNameTableEntry::PackInfo()
  43. * mjn Check deleted list in DN_GetPeerInfo()
  44. * 01/22/01 mjn Check closing instead of disconnecting in DN_GetPeerInfo()
  45. * 07/24/01 mjn Added DPNBUILD_NOPARAMVAL compile flag
  46. *@@END_MSINTERNAL
  47. *
  48. ***************************************************************************/
  49. #include "dncorei.h"
  50. //**********************************************************************
  51. // Constant definitions
  52. //**********************************************************************
  53. //**********************************************************************
  54. // Macro definitions
  55. //**********************************************************************
  56. //**********************************************************************
  57. // Structure definitions
  58. //**********************************************************************
  59. //**********************************************************************
  60. // Variable definitions
  61. //**********************************************************************
  62. typedef STDMETHODIMP PeerQueryInterface( IDirectPlay8Peer *pInterface, DP8REFIID riid, LPVOID *ppvObj );
  63. typedef STDMETHODIMP_(ULONG) PeerAddRef( IDirectPlay8Peer *pInterface );
  64. typedef STDMETHODIMP_(ULONG) PeerRelease( IDirectPlay8Peer *pInterface );
  65. typedef STDMETHODIMP PeerInitialize( IDirectPlay8Peer *pInterface, LPVOID const lpvUserContext, const PFNDPNMESSAGEHANDLER lpfn, const DWORD dwFlags );
  66. typedef STDMETHODIMP PeerEnumServiceProviders( IDirectPlay8Peer *pInterface,const GUID *const pguidServiceProvider,const GUID *const pguidApplication,DPN_SERVICE_PROVIDER_INFO *const pSPInfoBuffer,DWORD *const pcbEnumData,DWORD *const pcReturned,const DWORD dwFlags);
  67. typedef STDMETHODIMP PeerCancelAsyncOperation( IDirectPlay8Peer *pInterface,const DPNHANDLE hAsyncHandle, const DWORD dwFlags );
  68. typedef STDMETHODIMP PeerConnect( IDirectPlay8Peer *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 pvPlayerContext,void *const pvAsyncContext,DPNHANDLE *const phAsyncHandle,const DWORD dwFlags);
  69. typedef STDMETHODIMP PeerGetSendQueueInfo( IDirectPlay8Peer *pInterface, const DPNID dpnid,DWORD *const lpdwNumMsgs, DWORD *const lpdwNumBytes, const DWORD dwFlags );
  70. typedef STDMETHODIMP PeerSendTo( IDirectPlay8Peer *pInterface, const DPNID dnid, const DPN_BUFFER_DESC *const prgBufferDesc,const DWORD cBufferDesc,const DWORD dwTimeOut, void *const pvAsyncContext, DPNHANDLE *const phAsyncHandle, const DWORD dwFlags);
  71. typedef STDMETHODIMP PeerGetApplicationDesc( IDirectPlay8Peer *pInterface,DPN_APPLICATION_DESC *const pAppDescBuffer,DWORD *const lpcbDataSize,const DWORD dwFlags );
  72. typedef STDMETHODIMP PeerGetHostAddress( IDirectPlay8Peer *pInterface, IDirectPlay8Address **const prgpAddress, DWORD *const pcAddress,const DWORD dwFlags);
  73. typedef STDMETHODIMP PeerHost( IDirectPlay8Peer *pInterface,const DPN_APPLICATION_DESC *const pdnAppDesc,IDirectPlay8Address **const prgpDeviceInfo,const DWORD cDeviceInfo,const DPN_SECURITY_DESC *const pdnSecurity,const DPN_SECURITY_CREDENTIALS *const pdnCredentials,void *const pvPlayerContext,const DWORD dwFlags);
  74. typedef STDMETHODIMP PeerSetApplicationDesc( IDirectPlay8Peer *pInterface, const DPN_APPLICATION_DESC *const lpad, const DWORD dwFlags );
  75. typedef STDMETHODIMP PeerCreateGroup( IDirectPlay8Peer *pInterface, const DPN_GROUP_INFO *const pdpnGroupInfo,void *const pvGroupContext,void *const pvAsyncContext,DPNHANDLE *const phAsyncHandle,const DWORD dwFlags);
  76. typedef STDMETHODIMP PeerDestroyGroup( IDirectPlay8Peer *pInterface, const DPNID idGroup ,PVOID const pvUserContext,DPNHANDLE *const lpAsyncHandle,const DWORD dwFlags);
  77. typedef STDMETHODIMP PeerAddClientToGroup( IDirectPlay8Peer *pInterface, const DPNID idGroup, const DPNID idClient ,PVOID const pvUserContext,DPNHANDLE *const lpAsyncHandle,const DWORD dwFlags);
  78. typedef STDMETHODIMP PeerRemoveClientFromGroup( IDirectPlay8Peer *pInterface, const DPNID idGroup, const DPNID idClient,PVOID const pvUserContext,DPNHANDLE *const lpAsyncHandle,const DWORD dwFlags);
  79. typedef STDMETHODIMP PeerSetGroupInfo(IDirectPlay8Peer *pInterface, const DPNID dpnid,DPN_GROUP_INFO *const pdpnGroupInfo,PVOID const pvAsyncContext,DPNHANDLE *const phAsyncHandle, const DWORD dwFlags);
  80. typedef STDMETHODIMP PeerGetGroupInfo(IDirectPlay8Peer *pInterface, const DPNID dpnid,DPN_GROUP_INFO *const pdpnGroupInfo,DWORD *const pdwSize,const DWORD dwFlags);
  81. typedef STDMETHODIMP PeerEnumClientsAndGroups( IDirectPlay8Peer *pInterface, DPNID *const lprgdnid, DWORD *const lpcdnid, const DWORD dwFlags );
  82. typedef STDMETHODIMP PeerEnumGroupMembers( IDirectPlay8Peer *pInterface, const DPNID dnid, DPNID *const lprgdnid, DWORD *const lpcdnid, const DWORD dwFlags );
  83. typedef STDMETHODIMP PeerClose( IDirectPlay8Peer *pInterface,const DWORD dwFlags);
  84. typedef STDMETHODIMP PeerEnumHosts( IDirectPlay8Peer *pInterface,PDPN_APPLICATION_DESC const pApplicationDesc,IDirectPlay8Address *const pAddrHost,IDirectPlay8Address *const pDeviceInfo,PVOID const pUserEnumData,const DWORD dwUserEnumDataSize,const DWORD dwRetryCount,const DWORD dwRetryInterval,const DWORD dwTimeOut,PVOID const pvUserContext,DPNHANDLE *const pAsyncHandle,const DWORD dwFlags);
  85. typedef STDMETHODIMP PeerDestroyClient( IDirectPlay8Peer *pInterface,const DPNID dnid,const void *const pvDestroyData,const DWORD dwDestroyDataSize,const DWORD dwFlags);
  86. typedef STDMETHODIMP PeerReturnBuffer( IDirectPlay8Peer *pInterface, const DPNHANDLE hBufferHandle,const DWORD dwFlags);
  87. typedef STDMETHODIMP PeerGetCaps(IDirectPlay8Peer *pInterface,DPN_CAPS *const pdnCaps,const DWORD dwFlags);
  88. typedef STDMETHODIMP PeerSetCaps(IDirectPlay8Peer *pInterface,const DPN_CAPS *const pdnCaps,const DWORD dwFlags);
  89. typedef STDMETHODIMP PeerGetPlayerContext(IDirectPlay8Peer *pInterface,const DPNID dpnid,PVOID *const ppvPlayerContext,const DWORD dwFlags);
  90. typedef STDMETHODIMP PeerGetGroupContext(IDirectPlay8Peer *pInterface,const DPNID dpnid,PVOID *const ppvGroupContext,const DWORD dwFlags);
  91. typedef STDMETHODIMP PeerSetSPCaps(IDirectPlay8Peer *pInterface,const GUID * const pguidSP, const DPN_SP_CAPS *const pdpspCaps, const DWORD dwFlags );
  92. typedef STDMETHODIMP PeerGetSPCaps(IDirectPlay8Peer *pInterface,const GUID * const pguidSP, DPN_SP_CAPS *const pdpspCaps,const DWORD dwFlags);
  93. typedef STDMETHODIMP PeerGetConnectionInfo(IDirectPlay8Peer *pInterface,const DPNID dpnid, DPN_CONNECTION_INFO *const pdpConnectionInfo,const DWORD dwFlags);
  94. typedef STDMETHODIMP PeerRegisterLobby(IDirectPlay8Peer *pInterface,const DPNHANDLE dpnHandle,IDirectPlay8LobbiedApplication *const pIDP8LobbiedApplication,const DWORD dwFlags);
  95. typedef STDMETHODIMP PeerTerminateSession(IDirectPlay8Peer *pInterface,void *const pvTerminateData,const DWORD dwTerminateDataSize,const DWORD dwFlags);
  96. IDirectPlay8PeerVtbl DN_PeerVtbl =
  97. {
  98. (PeerQueryInterface*) DN_QueryInterface,
  99. (PeerAddRef*) DN_AddRef,
  100. (PeerRelease*) DN_Release,
  101. (PeerInitialize*) DN_Initialize,
  102. (PeerEnumServiceProviders*) DN_EnumServiceProviders,
  103. (PeerCancelAsyncOperation*) DN_CancelAsyncOperation,
  104. (PeerConnect*) DN_Connect,
  105. (PeerSendTo*) DN_SendTo,
  106. (PeerGetSendQueueInfo*) DN_GetSendQueueInfo,
  107. (PeerHost*) DN_Host,
  108. (PeerGetApplicationDesc*) DN_GetApplicationDesc,
  109. (PeerSetApplicationDesc*) DN_SetApplicationDesc,
  110. (PeerCreateGroup*) DN_CreateGroup,
  111. (PeerDestroyGroup*) DN_DestroyGroup,
  112. (PeerAddClientToGroup*) DN_AddClientToGroup,
  113. (PeerRemoveClientFromGroup*) DN_RemoveClientFromGroup,
  114. (PeerSetGroupInfo*) DN_SetGroupInfo,
  115. (PeerGetGroupInfo*) DN_GetGroupInfo,
  116. (PeerEnumClientsAndGroups*) DN_EnumClientsAndGroups,
  117. (PeerEnumGroupMembers*) DN_EnumGroupMembers,
  118. DN_SetPeerInfo,
  119. DN_GetPeerInfo,
  120. DN_GetPeerAddress,
  121. (PeerGetHostAddress*) DN_GetHostAddress,
  122. (PeerClose*) DN_Close,
  123. (PeerEnumHosts*) DN_EnumHosts,
  124. (PeerDestroyClient*) DN_DestroyPlayer,
  125. (PeerReturnBuffer*) DN_ReturnBuffer,
  126. (PeerGetPlayerContext*) DN_GetPlayerContext,
  127. (PeerGetGroupContext*) DN_GetGroupContext,
  128. (PeerGetCaps*) DN_GetCaps,
  129. (PeerSetCaps*) DN_SetCaps,
  130. (PeerSetSPCaps*) DN_SetSPCaps,
  131. (PeerGetSPCaps*) DN_GetSPCaps,
  132. (PeerGetConnectionInfo*) DN_GetConnectionInfo,
  133. (PeerRegisterLobby*) DN_RegisterLobby,
  134. (PeerTerminateSession*) DN_TerminateSession
  135. };
  136. //**********************************************************************
  137. // Function prototypes
  138. //**********************************************************************
  139. //**********************************************************************
  140. // Function definitions
  141. //**********************************************************************
  142. // DN_SetPeerInfo
  143. //
  144. // Set the info for the local player (peer) and propagate to other players
  145. #undef DPF_MODNAME
  146. #define DPF_MODNAME "DN_SetPeerInfo"
  147. STDMETHODIMP DN_SetPeerInfo( IDirectPlay8Peer *pInterface,
  148. const DPN_PLAYER_INFO *const pdpnPlayerInfo,
  149. PVOID const pvAsyncContext,
  150. DPNHANDLE *const phAsyncHandle,
  151. const DWORD dwFlags)
  152. {
  153. DIRECTNETOBJECT *pdnObject;
  154. HRESULT hResultCode;
  155. DPNHANDLE hAsyncOp;
  156. PWSTR pwszName;
  157. DWORD dwNameSize;
  158. PVOID pvData;
  159. DWORD dwDataSize;
  160. CNameTableEntry *pLocalPlayer;
  161. BOOL fConnected;
  162. DPFX(DPFPREP, 2,"Parameters: pInterface [0x%p], pdpnPlayerInfo [0x%p], pvAsyncContext [0x%p], phAsyncHandle [%p], dwFlags [0x%lx]",
  163. pInterface,pdpnPlayerInfo,pvAsyncContext,phAsyncHandle,dwFlags);
  164. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  165. DNASSERT(pdnObject != NULL);
  166. #ifndef DPNBUILD_NOPARAMVAL
  167. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  168. {
  169. if( FAILED( hResultCode = DN_ValidateSetPeerInfo( pInterface , pdpnPlayerInfo, pvAsyncContext, phAsyncHandle, dwFlags ) ) )
  170. {
  171. DPFX(DPFPREP, 0, "Error validating get peer info hr=[0x%lx]", hResultCode );
  172. DPF_RETURN( hResultCode );
  173. }
  174. }
  175. #endif // !DPNBUILD_NOPARAMVAL
  176. // Check to ensure message handler registered
  177. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  178. {
  179. DPFERR( "Object is not initialized" );
  180. DPF_RETURN(DPNERR_UNINITIALIZED);
  181. }
  182. pLocalPlayer = NULL;
  183. if ((pdpnPlayerInfo->dwInfoFlags & DPNINFO_NAME) && (pdpnPlayerInfo->pwszName))
  184. {
  185. pwszName = pdpnPlayerInfo->pwszName;
  186. dwNameSize = (wcslen(pwszName) + 1) * sizeof(WCHAR);
  187. }
  188. else
  189. {
  190. pwszName = NULL;
  191. dwNameSize = 0;
  192. }
  193. if ((pdpnPlayerInfo->dwInfoFlags & DPNINFO_DATA) && (pdpnPlayerInfo->pvData) && (pdpnPlayerInfo->dwDataSize))
  194. {
  195. pvData = pdpnPlayerInfo->pvData;
  196. dwDataSize = pdpnPlayerInfo->dwDataSize;
  197. }
  198. else
  199. {
  200. pvData = NULL;
  201. dwDataSize = 0;
  202. }
  203. //
  204. // If we are connected, we will update our entry if we are the Host, or request the Host to update us.
  205. // Otherwise, we will just update the DefaultPlayer.
  206. //
  207. DNEnterCriticalSection(&pdnObject->csDirectNetObject);
  208. if (pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTED)
  209. {
  210. fConnected = TRUE;
  211. }
  212. else
  213. {
  214. fConnected = FALSE;
  215. }
  216. DNLeaveCriticalSection(&pdnObject->csDirectNetObject);
  217. if (fConnected)
  218. {
  219. if ((hResultCode = pdnObject->NameTable.GetLocalPlayerRef( &pLocalPlayer )) != DPN_OK)
  220. {
  221. DPFERR( "Could not get local player reference" );
  222. DisplayDNError(0,hResultCode);
  223. goto Failure;
  224. }
  225. if (pLocalPlayer->IsHost())
  226. {
  227. DPFX(DPFPREP, 3,"Host is updating peer info");
  228. hResultCode = DNHostUpdateInfo( pdnObject,
  229. pLocalPlayer->GetDPNID(),
  230. pwszName,
  231. dwNameSize,
  232. pvData,
  233. dwDataSize,
  234. pdpnPlayerInfo->dwInfoFlags,
  235. pvAsyncContext,
  236. pLocalPlayer->GetDPNID(),
  237. 0,
  238. &hAsyncOp,
  239. dwFlags );
  240. if ((hResultCode != DPN_OK) && (hResultCode != DPNERR_PENDING))
  241. {
  242. DPFERR("Could not request host to update group");
  243. }
  244. else
  245. {
  246. if (!(dwFlags & DPNSETPEERINFO_SYNC))
  247. {
  248. DPFX(DPFPREP, 3,"Async Handle [0x%lx]",hAsyncOp);
  249. *phAsyncHandle = hAsyncOp;
  250. //
  251. // Release Async HANDLE since this operation has already completed (!)
  252. //
  253. CAsyncOp* pAsyncOp;
  254. if (SUCCEEDED(pdnObject->HandleTable.Destroy( hAsyncOp, (PVOID*)&pAsyncOp )))
  255. {
  256. // Release the HandleTable reference
  257. pAsyncOp->Release();
  258. }
  259. hAsyncOp = 0;
  260. }
  261. }
  262. }
  263. else
  264. {
  265. DPFX(DPFPREP, 3,"Request host to update group info");
  266. hResultCode = DNRequestUpdateInfo( pdnObject,
  267. pLocalPlayer->GetDPNID(),
  268. pwszName,
  269. dwNameSize,
  270. pvData,
  271. dwDataSize,
  272. pdpnPlayerInfo->dwInfoFlags,
  273. pvAsyncContext,
  274. &hAsyncOp,
  275. dwFlags);
  276. if (hResultCode != DPN_OK && hResultCode != DPNERR_PENDING)
  277. {
  278. DPFERR("Could not request host to update group info");
  279. }
  280. else
  281. {
  282. if (!(dwFlags & DPNSETPEERINFO_SYNC))
  283. {
  284. DPFX(DPFPREP, 3,"Async Handle [0x%lx]",hAsyncOp);
  285. *phAsyncHandle = hAsyncOp;
  286. }
  287. }
  288. }
  289. pLocalPlayer->Release();
  290. pLocalPlayer = NULL;
  291. }
  292. else
  293. {
  294. DNASSERT(pdnObject->NameTable.GetDefaultPlayer() != NULL);
  295. // This function takes the lock internally
  296. pdnObject->NameTable.GetDefaultPlayer()->UpdateEntryInfo(pwszName,dwNameSize,pvData,dwDataSize,pdpnPlayerInfo->dwInfoFlags, FALSE);
  297. hResultCode = DPN_OK;
  298. }
  299. Exit:
  300. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  301. return(hResultCode);
  302. Failure:
  303. if (pLocalPlayer)
  304. {
  305. pLocalPlayer->Release();
  306. pLocalPlayer = NULL;
  307. }
  308. goto Exit;
  309. }
  310. // DN_GetPeerInfo
  311. //
  312. // Retrieve peer info from the local nametable.
  313. #undef DPF_MODNAME
  314. #define DPF_MODNAME "DN_GetPeerInfo"
  315. STDMETHODIMP DN_GetPeerInfo(IDirectPlay8Peer *pInterface,
  316. const DPNID dpnid,
  317. DPN_PLAYER_INFO *const pdpnPlayerInfo,
  318. DWORD *const pdwSize,
  319. const DWORD dwFlags)
  320. {
  321. DIRECTNETOBJECT *pdnObject;
  322. CNameTableEntry *pNTEntry;
  323. HRESULT hResultCode;
  324. CPackedBuffer packedBuffer;
  325. DPFX(DPFPREP, 2,"Parameters: dpnid [0x%lx], pdpnPlayerInfo [0x%p], dwFlags [0x%lx]",
  326. dpnid,pdpnPlayerInfo,dwFlags);
  327. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  328. DNASSERT(pdnObject != NULL);
  329. #ifndef DPNBUILD_NOPARAMVAL
  330. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  331. {
  332. if( FAILED( hResultCode = DN_ValidateGetPeerInfo( pInterface , dpnid, pdpnPlayerInfo, pdwSize, dwFlags ) ) )
  333. {
  334. DPFX(DPFPREP, 0, "Error validating get peer info hr=[0x%lx]", hResultCode );
  335. DPF_RETURN( hResultCode );
  336. }
  337. }
  338. #endif // !DPNBUILD_NOPARAMVAL
  339. // Check to ensure message handler registered
  340. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  341. {
  342. DPFERR( "Object is not initialized" );
  343. DPF_RETURN(DPNERR_UNINITIALIZED);
  344. }
  345. if( (pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING) && !(pdnObject->dwFlags & DN_OBJECT_FLAG_HOST_CONNECTED) )
  346. {
  347. DPFERR("Object is connecting / starting to host" );
  348. DPF_RETURN(DPNERR_CONNECTING);
  349. }
  350. if ( !(pdnObject->dwFlags & ( DN_OBJECT_FLAG_CONNECTING
  351. | DN_OBJECT_FLAG_CONNECTED
  352. | DN_OBJECT_FLAG_CLOSING
  353. | DN_OBJECT_FLAG_DISCONNECTING) ) )
  354. {
  355. DPFERR("You must be connected / disconnecting to use this function" );
  356. DPF_RETURN(DPNERR_NOCONNECTION);
  357. }
  358. pNTEntry = NULL;
  359. if ((hResultCode = pdnObject->NameTable.FindEntry(dpnid,&pNTEntry)) != DPN_OK)
  360. {
  361. DPFERR("Could not retrieve name table entry");
  362. DisplayDNError(0,hResultCode);
  363. //
  364. // Try deleted list
  365. //
  366. if ((hResultCode = pdnObject->NameTable.FindDeletedEntry(dpnid,&pNTEntry)) != DPN_OK)
  367. {
  368. DPFERR("Could not find player in deleted list either");
  369. DisplayDNError(0,hResultCode);
  370. hResultCode = DPNERR_INVALIDPLAYER;
  371. goto Failure;
  372. }
  373. }
  374. packedBuffer.Initialize(pdpnPlayerInfo,*pdwSize);
  375. pNTEntry->Lock();
  376. if (pNTEntry->IsGroup())
  377. {
  378. DPFERR( "Specified ID is invalid" );
  379. pNTEntry->Unlock();
  380. hResultCode = DPNERR_INVALIDPLAYER;
  381. goto Failure;
  382. }
  383. hResultCode = pNTEntry->PackInfo(&packedBuffer);
  384. pNTEntry->Unlock();
  385. pNTEntry->Release();
  386. pNTEntry = NULL;
  387. if ((hResultCode == DPN_OK) || (hResultCode == DPNERR_BUFFERTOOSMALL))
  388. {
  389. *pdwSize = packedBuffer.GetSizeRequired();
  390. }
  391. Exit:
  392. DPFX(DPFPREP, 2,"Returning: [0x%lx]",hResultCode);
  393. return(hResultCode);
  394. Failure:
  395. if (pNTEntry)
  396. {
  397. pNTEntry->Release();
  398. pNTEntry = NULL;
  399. }
  400. goto Exit;
  401. }
  402. #undef DPF_MODNAME
  403. #define DPF_MODNAME "DN_GetPeerAddress"
  404. STDMETHODIMP DN_GetPeerAddress(IDirectPlay8Peer *pInterface,
  405. const DPNID dpnid,
  406. IDirectPlay8Address **const ppAddress,
  407. const DWORD dwFlags)
  408. {
  409. DIRECTNETOBJECT *pdnObject;
  410. CNameTableEntry *pNTEntry;
  411. IDirectPlay8Address *pAddress;
  412. HRESULT hResultCode;
  413. DPFX(DPFPREP, 2,"Parameters : pInterface [0x%p], dpnid [0x%lx], ppAddress [0x%p], dwFlags [0x%lx]",
  414. pInterface,dpnid,ppAddress,dwFlags);
  415. pdnObject = (DIRECTNETOBJECT*) GET_OBJECT_FROM_INTERFACE(pInterface);
  416. DNASSERT(pdnObject != NULL);
  417. #ifndef DPNBUILD_NOPARAMVAL
  418. if( pdnObject->dwFlags & DN_OBJECT_FLAG_PARAMVALIDATION )
  419. {
  420. if( FAILED( hResultCode = DN_ValidateGetPeerAddress( pInterface , dpnid, ppAddress, dwFlags ) ) )
  421. {
  422. DPFX(DPFPREP, 0, "Error validating get peer address info hr=[0x%lx]", hResultCode );
  423. DPF_RETURN( hResultCode );
  424. }
  425. }
  426. #endif // !DPNBUILD_NOPARAMVAL
  427. // Check to ensure message handler registered
  428. if (!(pdnObject->dwFlags & DN_OBJECT_FLAG_INITIALIZED))
  429. {
  430. DPFERR( "Object is not initialized" );
  431. DPF_RETURN(DPNERR_UNINITIALIZED);
  432. }
  433. if( (pdnObject->dwFlags & DN_OBJECT_FLAG_CONNECTING) && !(pdnObject->dwFlags & DN_OBJECT_FLAG_HOST_CONNECTED) )
  434. {
  435. DPFERR("Object is connecting / starting to host" );
  436. DPF_RETURN(DPNERR_CONNECTING);
  437. }
  438. if ( !(pdnObject->dwFlags & ( DN_OBJECT_FLAG_CONNECTING
  439. | DN_OBJECT_FLAG_CONNECTED
  440. | DN_OBJECT_FLAG_CLOSING
  441. | DN_OBJECT_FLAG_DISCONNECTING) ) )
  442. {
  443. DPFERR("You must be connected / disconnecting to use this function" );
  444. DPF_RETURN(DPNERR_NOCONNECTION);
  445. }
  446. pNTEntry = NULL;
  447. pAddress = NULL;
  448. if ((hResultCode = pdnObject->NameTable.FindEntry(dpnid,&pNTEntry)) != DPN_OK)
  449. {
  450. DPFERR("Could not find NameTableEntry");
  451. DisplayDNError(0,hResultCode);
  452. hResultCode = DPNERR_INVALIDPLAYER;
  453. goto Failure;
  454. }
  455. if ((pNTEntry->GetAddress() == NULL) || (pNTEntry->IsGroup()) || !pNTEntry->IsAvailable())
  456. {
  457. DPFERR( "Invalid ID specified. Not a player" );
  458. hResultCode = DPNERR_INVALIDPLAYER;
  459. goto Failure;
  460. }
  461. hResultCode = IDirectPlay8Address_Duplicate(pNTEntry->GetAddress(),ppAddress);
  462. pNTEntry->Release();
  463. pNTEntry = NULL;
  464. Exit:
  465. DPF_RETURN(hResultCode);
  466. Failure:
  467. if (pNTEntry)
  468. {
  469. pNTEntry->Release();
  470. pNTEntry = NULL;
  471. }
  472. goto Exit;
  473. }