Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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