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.

708 lines
20 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: addtcp.cpp
  6. * Content: DirectPlay8Address TCP interface file
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 02/04/2000 rmt Created
  12. * 02/12/2000 rmt Completed first implementation
  13. * 02/17/2000 rmt Parameter validation work
  14. * 02/20/2000 rmt Changed ports to USHORTs
  15. * 02/21/2000 rmt Updated to make core Unicode and remove ANSI calls
  16. * 02/23/2000 rmt Further parameter validation
  17. * 03/21/2000 rmt Renamed all DirectPlayAddress8's to DirectPlay8Addresses
  18. * 03/24/2000 rmt Added IsEqual function
  19. * 05/04/00 mjn Fixed leak in DP8ATCP_GetSockAddress()
  20. * 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
  21. * 08/03/2000 rmt Bug #41246 - Remove IP versions of Duplicate, SetEqual, IsEqual, BuildURL
  22. *@@END_MSINTERNAL
  23. *
  24. ***************************************************************************/
  25. #include "dnaddri.h"
  26. #ifndef DPNBUILD_NOADDRESSIPINTERFACE
  27. typedef STDMETHODIMP TCPQueryInterface( IDirectPlay8AddressIP *pInterface, DPNAREFIID riid, LPVOID *ppvObj );
  28. typedef STDMETHODIMP_(ULONG) TCPAddRef( IDirectPlay8AddressIP *pInterface );
  29. typedef STDMETHODIMP_(ULONG) TCPRelease( IDirectPlay8AddressIP *pInterface );
  30. //
  31. // VTable for client interface
  32. //
  33. IDirectPlay8AddressIPVtbl DP8A_IPVtbl =
  34. {
  35. (TCPQueryInterface*) DP8A_QueryInterface,
  36. (TCPAddRef*) DP8A_AddRef,
  37. (TCPRelease*) DP8A_Release,
  38. DP8ATCP_BuildFromSockAddr,
  39. DP8ATCP_BuildAddressW,
  40. DP8ATCP_BuildLocalAddress,
  41. DP8ATCP_GetSockAddress,
  42. DP8ATCP_GetLocalAddress,
  43. DP8ATCP_GetAddressW,
  44. };
  45. #undef DPF_MODNAME
  46. #define DPF_MODNAME "DP8ATCP_BuildLocalAddress"
  47. STDMETHODIMP DP8ATCP_BuildLocalAddress( IDirectPlay8AddressIP *pInterface, const GUID * const pguidAdapter, const USHORT usPort )
  48. {
  49. HRESULT hr;
  50. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  51. #ifndef DPNBUILD_NOPARAMVAL
  52. if( pInterface == NULL ||
  53. !DP8A_VALID( pInterface ) )
  54. {
  55. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
  56. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  57. }
  58. if( pguidAdapter == NULL ||
  59. !DNVALID_READPTR( pguidAdapter, sizeof( GUID ) ) )
  60. {
  61. DPFX(DPFPREP, 0, "Invalid pointer" );
  62. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  63. }
  64. #endif // !DPNBUILD_NOPARAMVAL
  65. DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
  66. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pguidAdapter: 0x%p usPort: %u", pguidAdapter, (DWORD)usPort );
  67. hr = pdp8Address->Clear();
  68. if( FAILED( hr ) )
  69. {
  70. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed to clear current address hr=0x%x", hr );
  71. DP8A_RETURN( hr );
  72. }
  73. #ifndef DPNBUILD_ONLYONESP
  74. hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
  75. if( FAILED( hr ) )
  76. {
  77. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
  78. DP8A_RETURN( hr );
  79. }
  80. #endif // ! DPNBUILD_ONLYONESP
  81. #ifndef DPNBUILD_ONLYONEADAPTER
  82. hr = pdp8Address->SetDevice( pguidAdapter );
  83. if( FAILED( hr ) )
  84. {
  85. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting device hr=0x%x", hr );
  86. DP8A_RETURN( hr );
  87. }
  88. #endif // ! DPNBUILD_ONLYONEADAPTER
  89. DWORD dwTmpPort = usPort;
  90. hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof( DWORD ), DPNA_DATATYPE_DWORD );
  91. if( FAILED( hr ) )
  92. {
  93. DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
  94. DP8A_RETURN( hr );
  95. }
  96. DP8A_RETURN( hr );
  97. }
  98. #undef DPF_MODNAME
  99. #define DPF_MODNAME "DP8ATCP_BuildFromSockAddr"
  100. STDMETHODIMP DP8ATCP_BuildFromSockAddr( IDirectPlay8AddressIP *pInterface, const SOCKADDR * const pSockAddr )
  101. {
  102. HRESULT hr;
  103. DWORD dwTmpPort;
  104. WCHAR wszHostName[16]; // Should be xxx.xxx.xxx.xxx + null
  105. sockaddr_in *saIPAddress;
  106. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  107. #ifndef DPNBUILD_NOPARAMVAL
  108. if( pInterface == NULL ||
  109. !DP8A_VALID( pInterface ) )
  110. {
  111. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
  112. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  113. }
  114. if( pSockAddr == NULL ||
  115. !DNVALID_READPTR( pSockAddr, sizeof( SOCKADDR ) ) )
  116. {
  117. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer to sockaddr" );
  118. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  119. }
  120. if( pSockAddr->sa_family != AF_INET )
  121. {
  122. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Only IPv4 addresses are supported" );
  123. DP8A_RETURN( DPNERR_INVALIDPARAM );
  124. }
  125. #endif // !DPNBUILD_NOPARAMVAL
  126. DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
  127. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pSockAddr: 0x%p", pSockAddr );
  128. saIPAddress = (sockaddr_in * ) pSockAddr;
  129. hr = pdp8Address->Clear();
  130. if( FAILED( hr ) )
  131. {
  132. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed clearing object hr=0x%x", hr );
  133. goto BUILDFROMSOCKADDR_ERROR;
  134. }
  135. #ifndef DPNBUILD_ONLYONESP
  136. hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
  137. if( FAILED( hr ) )
  138. {
  139. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
  140. DP8A_RETURN( hr );
  141. }
  142. #endif // ! DPNBUILD_ONLYONESP
  143. // Sockaddr is in network byte order, convert to host order
  144. dwTmpPort = ntohs(saIPAddress->sin_port);
  145. DNinet_ntow(saIPAddress->sin_addr, wszHostName);
  146. DNASSERT(wcslen(wszHostName) < 16);
  147. hr = pdp8Address->SetElement( DPNA_KEY_HOSTNAME, wszHostName, 16 * sizeof(WCHAR), DPNA_DATATYPE_STRING );
  148. if( FAILED( hr ) )
  149. {
  150. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed to set hostname hr=0x%x", hr );
  151. DP8A_RETURN( hr );
  152. }
  153. hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof(DWORD), DPNA_DATATYPE_DWORD );
  154. if( FAILED( hr ) )
  155. {
  156. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Failed setting port hr=0x%x", hr );
  157. DP8A_RETURN( hr );
  158. }
  159. DP8A_RETURN( DPN_OK );
  160. BUILDFROMSOCKADDR_ERROR:
  161. DP8A_RETURN( hr );
  162. }
  163. #undef DPF_MODNAME
  164. #define DPF_MODNAME "DP8ATCP_BuildAddressW"
  165. STDMETHODIMP DP8ATCP_BuildAddressW( IDirectPlay8AddressIP *pInterface, const WCHAR * const pwszAddress, const USHORT usPort )
  166. {
  167. HRESULT hr;
  168. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  169. #ifndef DPNBUILD_NOPARAMVAL
  170. if( pInterface == NULL ||
  171. !DP8A_VALID( pInterface ) )
  172. {
  173. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
  174. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  175. }
  176. if( pwszAddress == NULL )
  177. {
  178. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer to address" );
  179. DP8A_RETURN( E_POINTER );
  180. }
  181. if( !DNVALID_STRING_W( pwszAddress ) )
  182. {
  183. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid string for address" );
  184. DP8A_RETURN( DPNERR_INVALIDSTRING );
  185. }
  186. #endif // !DPNBUILD_NOPARAMVAL
  187. DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
  188. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pwszAddress: 0x%p, usPort = %u", pwszAddress, (DWORD)usPort );
  189. hr = pdp8Address->Clear();
  190. if( FAILED( hr ) )
  191. {
  192. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error clearing current address hr=0x%x", hr );
  193. DP8A_RETURN( hr );
  194. }
  195. #ifndef DPNBUILD_ONLYONESP
  196. hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
  197. if( FAILED( hr ) )
  198. {
  199. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
  200. DP8A_RETURN( hr );
  201. }
  202. #endif // ! DPNBUILD_ONLYONESP
  203. hr = pdp8Address->SetElement( DPNA_KEY_HOSTNAME, pwszAddress, (wcslen(pwszAddress)+1)*sizeof(WCHAR), DPNA_DATATYPE_STRING );
  204. if( FAILED( hr ) )
  205. {
  206. DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
  207. DP8A_RETURN( hr );
  208. }
  209. DWORD dwTmpPort = usPort;
  210. hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof( DWORD ), DPNA_DATATYPE_DWORD );
  211. if( FAILED( hr ) )
  212. {
  213. DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
  214. DP8A_RETURN( hr );
  215. }
  216. DP8A_RETURN( hr );
  217. }
  218. #undef DPF_MODNAME
  219. #define DPF_MODNAME "DP8ATCP_GetSockAddress"
  220. STDMETHODIMP DP8ATCP_GetSockAddress( IDirectPlay8AddressIP *pInterface, SOCKADDR *pSockAddr, PDWORD pdwBufferSize )
  221. {
  222. HRESULT hr;
  223. WCHAR *swzAddress = NULL; // Unicode version of hostname
  224. CHAR *szAddress = NULL; // ANSI version of hostname
  225. DWORD dwAddressSize = 0;
  226. USHORT usPort;
  227. in_addr iaTmp;
  228. DWORD dwRequiredSize;
  229. sockaddr_in *psinCurAddress;
  230. #ifndef _XBOX
  231. LPHOSTENT lpHostEntry;
  232. in_addr *piaTmp;
  233. DWORD dwNumElements;
  234. DWORD dwIndex;
  235. SOCKADDR *pCurLoc;
  236. #endif // ! _XBOX
  237. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  238. #ifndef DPNBUILD_NOPARAMVAL
  239. if( pInterface == NULL ||
  240. !DP8A_VALID( pInterface ) )
  241. {
  242. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
  243. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  244. }
  245. if( pdwBufferSize == NULL ||
  246. !DNVALID_WRITEPTR( pdwBufferSize, sizeof( DWORD ) ) )
  247. {
  248. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pdwBufferSize" );
  249. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  250. }
  251. if( *pdwBufferSize > 0 &&
  252. (pSockAddr == NULL || !DNVALID_WRITEPTR( pSockAddr, *pdwBufferSize ) ) )
  253. {
  254. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for sockaddress" );
  255. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  256. }
  257. #endif // !DPNBUILD_NOPARAMVAL
  258. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pSockAddr = 0x%p, pdwBufferSize = 0x%p (%d)", pSockAddr, pdwBufferSize, *pdwBufferSize );
  259. hr = DP8ATCP_GetAddressW( pInterface, swzAddress, &dwAddressSize, &usPort );
  260. if( hr != DPNERR_BUFFERTOOSMALL )
  261. {
  262. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve size required hr=0x%x", hr );
  263. goto GETSOCKADDRESS_ERROR;
  264. }
  265. swzAddress = (WCHAR*) DNMalloc(dwAddressSize * sizeof(WCHAR));
  266. if( swzAddress == NULL )
  267. {
  268. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error allocating memory hr=0x%x", hr );
  269. hr = DPNERR_OUTOFMEMORY;
  270. goto GETSOCKADDRESS_ERROR;
  271. }
  272. hr = DP8ATCP_GetAddressW( pInterface, swzAddress, &dwAddressSize, &usPort );
  273. if( FAILED( hr ) )
  274. {
  275. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve address hr=0x%x", hr );
  276. goto GETSOCKADDRESS_ERROR;
  277. }
  278. szAddress = (CHAR*) DNMalloc(dwAddressSize * sizeof(CHAR));
  279. if( szAddress == NULL )
  280. {
  281. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error allocating memory hr=0x%x", hr );
  282. hr = DPNERR_OUTOFMEMORY;
  283. goto GETSOCKADDRESS_ERROR;
  284. }
  285. if( FAILED( hr = STR_jkWideToAnsi( szAddress, swzAddress, dwAddressSize ) ) )
  286. {
  287. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error converting address to ANSI hr=0x%x", hr );
  288. hr = DPNERR_CONVERSION;
  289. goto GETSOCKADDRESS_ERROR;
  290. }
  291. iaTmp.s_addr = inet_addr( szAddress );
  292. if( iaTmp.s_addr != INADDR_NONE || strcmp( szAddress, "255.255.255.255" ) == 0 )
  293. {
  294. dwRequiredSize = sizeof( SOCKADDR );
  295. if( *pdwBufferSize < dwRequiredSize )
  296. {
  297. *pdwBufferSize = dwRequiredSize;
  298. DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small" );
  299. hr = DPNERR_BUFFERTOOSMALL;
  300. goto GETSOCKADDRESS_ERROR;
  301. }
  302. memset( pSockAddr, 0x00, sizeof( SOCKADDR ) );
  303. psinCurAddress = (sockaddr_in *) pSockAddr;
  304. psinCurAddress->sin_family = AF_INET;
  305. psinCurAddress->sin_port = htons(usPort);
  306. psinCurAddress->sin_addr = iaTmp;
  307. hr = DPN_OK;
  308. goto GETSOCKADDRESS_ERROR;
  309. }
  310. #ifdef _XBOX
  311. #pragma TODO(vanceo, "Use Xbox specific name lookup if available")
  312. DPFX(DPFPREP, 0, "Unable to resolve IP address \"%hs\"!", szAddress);
  313. hr = DPNERR_INVALIDHOSTADDRESS;
  314. goto GETSOCKADDRESS_ERROR;
  315. #else // ! _XBOX
  316. lpHostEntry = gethostbyname( szAddress );
  317. if( lpHostEntry == NULL )
  318. {
  319. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid host specified hr=0x%x" , hr );
  320. hr = DPNERR_INVALIDHOSTADDRESS;
  321. goto GETSOCKADDRESS_ERROR;
  322. }
  323. // Count addresses
  324. for( dwNumElements = 0; ; dwNumElements++ )
  325. {
  326. piaTmp = ((LPIN_ADDR)lpHostEntry->h_addr_list[dwNumElements]);
  327. if( piaTmp == NULL )
  328. break;
  329. }
  330. dwRequiredSize = dwNumElements * sizeof( SOCKADDR );
  331. if( *pdwBufferSize < dwRequiredSize )
  332. {
  333. *pdwBufferSize = dwRequiredSize;
  334. DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small" );
  335. hr = DPNERR_BUFFERTOOSMALL;
  336. goto GETSOCKADDRESS_ERROR;
  337. }
  338. *pdwBufferSize = dwRequiredSize;
  339. pCurLoc = pSockAddr;
  340. memset( pCurLoc, 0x00, *pdwBufferSize );
  341. // Build addresses and copy them to the buffer
  342. for( dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
  343. {
  344. psinCurAddress = (sockaddr_in *) pCurLoc;
  345. psinCurAddress->sin_family = AF_INET;
  346. psinCurAddress->sin_port = htons(usPort);
  347. psinCurAddress->sin_addr = *((LPIN_ADDR)lpHostEntry->h_addr_list[dwIndex]);
  348. pCurLoc++;
  349. }
  350. DNFree(swzAddress);
  351. DNFree(szAddress);
  352. DP8A_RETURN( DPN_OK );
  353. #endif // ! _XBOX
  354. GETSOCKADDRESS_ERROR:
  355. if( swzAddress != NULL )
  356. DNFree(swzAddress);
  357. if( szAddress != NULL )
  358. DNFree(szAddress);
  359. DP8A_RETURN( hr );
  360. }
  361. #undef DPF_MODNAME
  362. #define DPF_MODNAME "DP8ATCP_GetLocalAddress"
  363. STDMETHODIMP DP8ATCP_GetLocalAddress( IDirectPlay8AddressIP *pInterface, GUID * pguidAdapter, PUSHORT pusPort )
  364. {
  365. HRESULT hr;
  366. #ifndef DPNBUILD_ONLYONEADAPTER
  367. GUID guidDevice;
  368. #endif // ! DPNBUILD_ONLYONEADAPTER
  369. DWORD dwPort;
  370. DWORD dwType;
  371. DWORD dwSize;
  372. #ifndef DPNBUILD_ONLYONESP
  373. GUID guidSP;
  374. #endif // ! DPNBUILD_ONLYONESP
  375. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  376. #ifndef DPNBUILD_NOPARAMVAL
  377. if( pInterface == NULL ||
  378. !DP8A_VALID( pInterface ) )
  379. {
  380. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
  381. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  382. }
  383. if( pguidAdapter == NULL ||
  384. !DNVALID_WRITEPTR( pguidAdapter, sizeof( GUID ) ) )
  385. {
  386. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for adapter" );
  387. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  388. }
  389. if( pusPort == NULL ||
  390. !DNVALID_WRITEPTR( pusPort, sizeof( USHORT ) ) )
  391. {
  392. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for port" );
  393. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  394. }
  395. #endif // !DPNBUILD_NOPARAMVAL
  396. DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
  397. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pguidAdapter = 0x%p pusPort = 0x%p",
  398. pguidAdapter, pusPort );
  399. #ifndef DPNBUILD_ONLYONESP
  400. hr = pdp8Address->GetSP( &guidSP );
  401. if( FAILED( hr ) )
  402. {
  403. DPFX(DPFPREP, DP8A_ERRORLEVEL, "No provider SP specified hr=0x%x", hr );
  404. hr = DPNERR_INCOMPLETEADDRESS;
  405. DP8A_RETURN( hr );
  406. }
  407. if( guidSP != CLSID_DP8SP_TCPIP )
  408. {
  409. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Not an IP address" );
  410. hr = DPNERR_INVALIDADDRESSFORMAT;
  411. DP8A_RETURN( hr );
  412. }
  413. #endif // ! DPNBUILD_ONLYONESP
  414. #ifndef DPNBUILD_ONLYONEADAPTER
  415. hr = pdp8Address->GetElementType( DPNA_KEY_DEVICE, &dwType );
  416. if( FAILED( hr ) )
  417. {
  418. DPFX(DPFPREP, DP8A_ERRORLEVEL, "This device element doesn't exist hr=0x%x", hr );
  419. hr = DPNERR_INCOMPLETEADDRESS;
  420. DP8A_RETURN( hr );
  421. }
  422. if( dwType != DPNA_DATATYPE_GUID )
  423. {
  424. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The device is not a GUID hr=0x%x", hr );
  425. hr = DPNERR_GENERIC;
  426. DP8A_RETURN( hr );
  427. }
  428. #endif // ! DPNBUILD_ONLYONEADAPTER
  429. hr = pdp8Address->GetElementType( DPNA_KEY_PORT, &dwType );
  430. if( FAILED( hr ) )
  431. {
  432. DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a port element hr=0x%x", hr );
  433. hr = DPNERR_INCOMPLETEADDRESS;
  434. DP8A_RETURN( hr );
  435. }
  436. if( dwType != DPNA_DATATYPE_DWORD )
  437. {
  438. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The port is not a dword hr=0x%x", hr );
  439. hr = DPNERR_GENERIC;
  440. DP8A_RETURN( hr );
  441. }
  442. dwSize = sizeof(DWORD);
  443. hr = pdp8Address->GetElement( DPNA_KEY_PORT, &dwPort, &dwSize, &dwType );
  444. if( FAILED( hr ) )
  445. {
  446. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve port element hr=0x%x", hr );
  447. hr = DPNERR_GENERIC;
  448. DP8A_RETURN( hr );
  449. }
  450. #ifdef DPNBUILD_ONLYONEADAPTER
  451. // Just return GUID_NULL
  452. memset(pguidAdapter, 0, sizeof(GUID));
  453. #else // ! DPNBUILD_ONLYONEADAPTER
  454. dwSize = sizeof(GUID);
  455. hr = pdp8Address->GetElement( DPNA_KEY_DEVICE, &guidDevice, &dwSize, &dwType );
  456. if( FAILED( hr ) )
  457. {
  458. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve device element hr=0x%x", hr );
  459. hr = DPNERR_GENERIC;
  460. DP8A_RETURN( hr );
  461. }
  462. *pguidAdapter = guidDevice;
  463. #endif // ! DPNBUILD_ONLYONEADAPTER
  464. *pusPort = (USHORT) dwPort;
  465. DP8A_RETURN( DPN_OK );
  466. }
  467. #undef DPF_MODNAME
  468. #define DPF_MODNAME "DP8ATCP_GetAddressW"
  469. STDMETHODIMP DP8ATCP_GetAddressW( IDirectPlay8AddressIP *pInterface, WCHAR * pwszAddress, PDWORD pdwAddressLength, PUSHORT pusPort )
  470. {
  471. HRESULT hr;
  472. DWORD dwPort;
  473. DWORD dwType;
  474. DWORD dwSize;
  475. #ifndef DPNBUILD_ONLYONESP
  476. GUID guidSP;
  477. #endif // ! DPNBUILD_ONLYONESP
  478. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
  479. #ifndef DPNBUILD_NOPARAMVAL
  480. if( pInterface == NULL ||
  481. !DP8A_VALID( pInterface ) )
  482. {
  483. DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
  484. DP8A_RETURN( DPNERR_INVALIDOBJECT );
  485. }
  486. if( pdwAddressLength == NULL ||
  487. !DNVALID_WRITEPTR( pdwAddressLength, sizeof( DWORD ) ) )
  488. {
  489. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pdwAddressLength" );
  490. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  491. }
  492. if( *pdwAddressLength > 0 &&
  493. (pwszAddress == NULL || !DNVALID_WRITEPTR( pwszAddress, (*pdwAddressLength)*sizeof(WCHAR) ) ) )
  494. {
  495. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pwszAddress" );
  496. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  497. }
  498. if( pusPort == NULL ||
  499. !DNVALID_WRITEPTR( pusPort, sizeof( USHORT ) ) )
  500. {
  501. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for port" );
  502. DP8A_RETURN( DPNERR_INVALIDPOINTER );
  503. }
  504. #endif // !DPNBUILD_NOPARAMVAL
  505. DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
  506. DPFX(DPFPREP, DP8A_PARAMLEVEL, "pwszAddress = 0x%p pdwAddressLength = 0x%p (%u) pusPort = 0x%p (%u)",
  507. pwszAddress, pdwAddressLength, *pdwAddressLength, pusPort, (DWORD)*pusPort );
  508. #ifndef DPNBUILD_ONLYONESP
  509. hr = pdp8Address->GetSP( &guidSP );
  510. if( FAILED( hr ) )
  511. {
  512. DPFX(DPFPREP, DP8A_ERRORLEVEL, "No provider SP specified hr=0x%x", hr );
  513. hr = DPNERR_INCOMPLETEADDRESS;
  514. DP8A_RETURN( hr );
  515. }
  516. if( guidSP != CLSID_DP8SP_TCPIP )
  517. {
  518. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Not an IP address" );
  519. hr = DPNERR_INVALIDADDRESSFORMAT;
  520. DP8A_RETURN( hr );
  521. }
  522. #endif // ! DPNBUILD_ONLYONESP
  523. hr = pdp8Address->GetElementType( DPNA_KEY_HOSTNAME, &dwType );
  524. if( FAILED( hr ) )
  525. {
  526. DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a hostname element hr=0x%x", hr );
  527. hr = DPNERR_INCOMPLETEADDRESS;
  528. DP8A_RETURN( hr );
  529. }
  530. if( dwType != DPNA_DATATYPE_STRING )
  531. {
  532. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The host name is not a string hr=0x%x", hr );
  533. hr = DPNERR_GENERIC;
  534. DP8A_RETURN( hr );
  535. }
  536. hr = pdp8Address->GetElementType( DPNA_KEY_PORT, &dwType );
  537. if( FAILED( hr ) )
  538. {
  539. DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a port element hr=0x%x", hr );
  540. hr = DPNERR_INCOMPLETEADDRESS;
  541. DP8A_RETURN( hr );
  542. }
  543. if( dwType != DPNA_DATATYPE_DWORD )
  544. {
  545. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The port is not a dword hr=0x%x", hr );
  546. hr = DPNERR_GENERIC;
  547. DP8A_RETURN( hr );
  548. }
  549. dwSize = sizeof(DWORD);
  550. hr = pdp8Address->GetElement( DPNA_KEY_PORT, &dwPort, &dwSize, &dwType );
  551. if( FAILED( hr ) )
  552. {
  553. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve port element hr=0x%x", hr );
  554. hr = DPNERR_GENERIC;
  555. DP8A_RETURN( hr );
  556. }
  557. *pdwAddressLength *= 2;
  558. hr = pdp8Address->GetElement( DPNA_KEY_HOSTNAME, pwszAddress, pdwAddressLength, &dwType );
  559. *pdwAddressLength /= 2;
  560. if( hr == DPNERR_BUFFERTOOSMALL )
  561. {
  562. DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small hr=0x%x", hr );
  563. DP8A_RETURN( hr );
  564. }
  565. else if( FAILED( hr ) )
  566. {
  567. DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve hostname element hr=0x%x", hr );
  568. hr = DPNERR_GENERIC;
  569. DP8A_RETURN( hr );
  570. }
  571. *pusPort = (USHORT) dwPort;
  572. DP8A_RETURN( DPN_OK );
  573. }
  574. #endif // ! DPNBUILD_NOADDRESSIPINTERFACE