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

/*==========================================================================
*
* Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
*
* File: addtcp.cpp
* Content: DirectPlay8Address TCP interface file
*@@BEGIN_MSINTERNAL
* History:
* Date By Reason
* ==== == ======
* 02/04/2000 rmt Created
* 02/12/2000 rmt Completed first implementation
* 02/17/2000 rmt Parameter validation work
* 02/20/2000 rmt Changed ports to USHORTs
* 02/21/2000 rmt Updated to make core Unicode and remove ANSI calls
* 02/23/2000 rmt Further parameter validation
* 03/21/2000 rmt Renamed all DirectPlayAddress8's to DirectPlay8Addresses
* 03/24/2000 rmt Added IsEqual function
* 05/04/00 mjn Fixed leak in DP8ATCP_GetSockAddress()
* 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
* 08/03/2000 rmt Bug #41246 - Remove IP versions of Duplicate, SetEqual, IsEqual, BuildURL
*@@END_MSINTERNAL
*
***************************************************************************/
#include "dnaddri.h"
#ifndef DPNBUILD_NOADDRESSIPINTERFACE
typedef STDMETHODIMP TCPQueryInterface( IDirectPlay8AddressIP *pInterface, DPNAREFIID riid, LPVOID *ppvObj );
typedef STDMETHODIMP_(ULONG) TCPAddRef( IDirectPlay8AddressIP *pInterface );
typedef STDMETHODIMP_(ULONG) TCPRelease( IDirectPlay8AddressIP *pInterface );
//
// VTable for client interface
//
IDirectPlay8AddressIPVtbl DP8A_IPVtbl =
{
(TCPQueryInterface*) DP8A_QueryInterface,
(TCPAddRef*) DP8A_AddRef,
(TCPRelease*) DP8A_Release,
DP8ATCP_BuildFromSockAddr,
DP8ATCP_BuildAddressW,
DP8ATCP_BuildLocalAddress,
DP8ATCP_GetSockAddress,
DP8ATCP_GetLocalAddress,
DP8ATCP_GetAddressW,
};
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_BuildLocalAddress"
STDMETHODIMP DP8ATCP_BuildLocalAddress( IDirectPlay8AddressIP *pInterface, const GUID * const pguidAdapter, const USHORT usPort )
{
HRESULT hr;
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pguidAdapter == NULL ||
!DNVALID_READPTR( pguidAdapter, sizeof( GUID ) ) )
{
DPFX(DPFPREP, 0, "Invalid pointer" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
#endif // !DPNBUILD_NOPARAMVAL
DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pguidAdapter: 0x%p usPort: %u", pguidAdapter, (DWORD)usPort );
hr = pdp8Address->Clear();
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed to clear current address hr=0x%x", hr );
DP8A_RETURN( hr );
}
#ifndef DPNBUILD_ONLYONESP
hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONESP
#ifndef DPNBUILD_ONLYONEADAPTER
hr = pdp8Address->SetDevice( pguidAdapter );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting device hr=0x%x", hr );
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONEADAPTER
DWORD dwTmpPort = usPort;
hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof( DWORD ), DPNA_DATATYPE_DWORD );
if( FAILED( hr ) )
{
DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
DP8A_RETURN( hr );
}
DP8A_RETURN( hr );
}
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_BuildFromSockAddr"
STDMETHODIMP DP8ATCP_BuildFromSockAddr( IDirectPlay8AddressIP *pInterface, const SOCKADDR * const pSockAddr )
{
HRESULT hr;
DWORD dwTmpPort;
WCHAR wszHostName[16]; // Should be xxx.xxx.xxx.xxx + null
sockaddr_in *saIPAddress;
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pSockAddr == NULL ||
!DNVALID_READPTR( pSockAddr, sizeof( SOCKADDR ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer to sockaddr" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
if( pSockAddr->sa_family != AF_INET )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Only IPv4 addresses are supported" );
DP8A_RETURN( DPNERR_INVALIDPARAM );
}
#endif // !DPNBUILD_NOPARAMVAL
DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pSockAddr: 0x%p", pSockAddr );
saIPAddress = (sockaddr_in * ) pSockAddr;
hr = pdp8Address->Clear();
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed clearing object hr=0x%x", hr );
goto BUILDFROMSOCKADDR_ERROR;
}
#ifndef DPNBUILD_ONLYONESP
hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONESP
// Sockaddr is in network byte order, convert to host order
dwTmpPort = ntohs(saIPAddress->sin_port);
DNinet_ntow(saIPAddress->sin_addr, wszHostName);
DNASSERT(wcslen(wszHostName) < 16);
hr = pdp8Address->SetElement( DPNA_KEY_HOSTNAME, wszHostName, 16 * sizeof(WCHAR), DPNA_DATATYPE_STRING );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Failed to set hostname hr=0x%x", hr );
DP8A_RETURN( hr );
}
hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof(DWORD), DPNA_DATATYPE_DWORD );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Failed setting port hr=0x%x", hr );
DP8A_RETURN( hr );
}
DP8A_RETURN( DPN_OK );
BUILDFROMSOCKADDR_ERROR:
DP8A_RETURN( hr );
}
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_BuildAddressW"
STDMETHODIMP DP8ATCP_BuildAddressW( IDirectPlay8AddressIP *pInterface, const WCHAR * const pwszAddress, const USHORT usPort )
{
HRESULT hr;
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pwszAddress == NULL )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer to address" );
DP8A_RETURN( E_POINTER );
}
if( !DNVALID_STRING_W( pwszAddress ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid string for address" );
DP8A_RETURN( DPNERR_INVALIDSTRING );
}
#endif // !DPNBUILD_NOPARAMVAL
DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pwszAddress: 0x%p, usPort = %u", pwszAddress, (DWORD)usPort );
hr = pdp8Address->Clear();
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error clearing current address hr=0x%x", hr );
DP8A_RETURN( hr );
}
#ifndef DPNBUILD_ONLYONESP
hr = pdp8Address->SetSP( &CLSID_DP8SP_TCPIP );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error setting service provider hr=0x%x", hr );
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONESP
hr = pdp8Address->SetElement( DPNA_KEY_HOSTNAME, pwszAddress, (wcslen(pwszAddress)+1)*sizeof(WCHAR), DPNA_DATATYPE_STRING );
if( FAILED( hr ) )
{
DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
DP8A_RETURN( hr );
}
DWORD dwTmpPort = usPort;
hr = pdp8Address->SetElement( DPNA_KEY_PORT, &dwTmpPort, sizeof( DWORD ), DPNA_DATATYPE_DWORD );
if( FAILED( hr ) )
{
DPFX(DPFPREP, 0, "Adding SP element failed hr=0x%x", hr );
DP8A_RETURN( hr );
}
DP8A_RETURN( hr );
}
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_GetSockAddress"
STDMETHODIMP DP8ATCP_GetSockAddress( IDirectPlay8AddressIP *pInterface, SOCKADDR *pSockAddr, PDWORD pdwBufferSize )
{
HRESULT hr;
WCHAR *swzAddress = NULL; // Unicode version of hostname
CHAR *szAddress = NULL; // ANSI version of hostname
DWORD dwAddressSize = 0;
USHORT usPort;
in_addr iaTmp;
DWORD dwRequiredSize;
sockaddr_in *psinCurAddress;
#ifndef _XBOX
LPHOSTENT lpHostEntry;
in_addr *piaTmp;
DWORD dwNumElements;
DWORD dwIndex;
SOCKADDR *pCurLoc;
#endif // ! _XBOX
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pdwBufferSize == NULL ||
!DNVALID_WRITEPTR( pdwBufferSize, sizeof( DWORD ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pdwBufferSize" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
if( *pdwBufferSize > 0 &&
(pSockAddr == NULL || !DNVALID_WRITEPTR( pSockAddr, *pdwBufferSize ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for sockaddress" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
#endif // !DPNBUILD_NOPARAMVAL
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pSockAddr = 0x%p, pdwBufferSize = 0x%p (%d)", pSockAddr, pdwBufferSize, *pdwBufferSize );
hr = DP8ATCP_GetAddressW( pInterface, swzAddress, &dwAddressSize, &usPort );
if( hr != DPNERR_BUFFERTOOSMALL )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve size required hr=0x%x", hr );
goto GETSOCKADDRESS_ERROR;
}
swzAddress = (WCHAR*) DNMalloc(dwAddressSize * sizeof(WCHAR));
if( swzAddress == NULL )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error allocating memory hr=0x%x", hr );
hr = DPNERR_OUTOFMEMORY;
goto GETSOCKADDRESS_ERROR;
}
hr = DP8ATCP_GetAddressW( pInterface, swzAddress, &dwAddressSize, &usPort );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve address hr=0x%x", hr );
goto GETSOCKADDRESS_ERROR;
}
szAddress = (CHAR*) DNMalloc(dwAddressSize * sizeof(CHAR));
if( szAddress == NULL )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error allocating memory hr=0x%x", hr );
hr = DPNERR_OUTOFMEMORY;
goto GETSOCKADDRESS_ERROR;
}
if( FAILED( hr = STR_jkWideToAnsi( szAddress, swzAddress, dwAddressSize ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Error converting address to ANSI hr=0x%x", hr );
hr = DPNERR_CONVERSION;
goto GETSOCKADDRESS_ERROR;
}
iaTmp.s_addr = inet_addr( szAddress );
if( iaTmp.s_addr != INADDR_NONE || strcmp( szAddress, "255.255.255.255" ) == 0 )
{
dwRequiredSize = sizeof( SOCKADDR );
if( *pdwBufferSize < dwRequiredSize )
{
*pdwBufferSize = dwRequiredSize;
DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small" );
hr = DPNERR_BUFFERTOOSMALL;
goto GETSOCKADDRESS_ERROR;
}
memset( pSockAddr, 0x00, sizeof( SOCKADDR ) );
psinCurAddress = (sockaddr_in *) pSockAddr;
psinCurAddress->sin_family = AF_INET;
psinCurAddress->sin_port = htons(usPort);
psinCurAddress->sin_addr = iaTmp;
hr = DPN_OK;
goto GETSOCKADDRESS_ERROR;
}
#ifdef _XBOX
#pragma TODO(vanceo, "Use Xbox specific name lookup if available")
DPFX(DPFPREP, 0, "Unable to resolve IP address \"%hs\"!", szAddress);
hr = DPNERR_INVALIDHOSTADDRESS;
goto GETSOCKADDRESS_ERROR;
#else // ! _XBOX
lpHostEntry = gethostbyname( szAddress );
if( lpHostEntry == NULL )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid host specified hr=0x%x" , hr );
hr = DPNERR_INVALIDHOSTADDRESS;
goto GETSOCKADDRESS_ERROR;
}
// Count addresses
for( dwNumElements = 0; ; dwNumElements++ )
{
piaTmp = ((LPIN_ADDR)lpHostEntry->h_addr_list[dwNumElements]);
if( piaTmp == NULL )
break;
}
dwRequiredSize = dwNumElements * sizeof( SOCKADDR );
if( *pdwBufferSize < dwRequiredSize )
{
*pdwBufferSize = dwRequiredSize;
DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small" );
hr = DPNERR_BUFFERTOOSMALL;
goto GETSOCKADDRESS_ERROR;
}
*pdwBufferSize = dwRequiredSize;
pCurLoc = pSockAddr;
memset( pCurLoc, 0x00, *pdwBufferSize );
// Build addresses and copy them to the buffer
for( dwIndex = 0; dwIndex < dwNumElements; dwIndex++ )
{
psinCurAddress = (sockaddr_in *) pCurLoc;
psinCurAddress->sin_family = AF_INET;
psinCurAddress->sin_port = htons(usPort);
psinCurAddress->sin_addr = *((LPIN_ADDR)lpHostEntry->h_addr_list[dwIndex]);
pCurLoc++;
}
DNFree(swzAddress);
DNFree(szAddress);
DP8A_RETURN( DPN_OK );
#endif // ! _XBOX
GETSOCKADDRESS_ERROR:
if( swzAddress != NULL )
DNFree(swzAddress);
if( szAddress != NULL )
DNFree(szAddress);
DP8A_RETURN( hr );
}
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_GetLocalAddress"
STDMETHODIMP DP8ATCP_GetLocalAddress( IDirectPlay8AddressIP *pInterface, GUID * pguidAdapter, PUSHORT pusPort )
{
HRESULT hr;
#ifndef DPNBUILD_ONLYONEADAPTER
GUID guidDevice;
#endif // ! DPNBUILD_ONLYONEADAPTER
DWORD dwPort;
DWORD dwType;
DWORD dwSize;
#ifndef DPNBUILD_ONLYONESP
GUID guidSP;
#endif // ! DPNBUILD_ONLYONESP
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pguidAdapter == NULL ||
!DNVALID_WRITEPTR( pguidAdapter, sizeof( GUID ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for adapter" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
if( pusPort == NULL ||
!DNVALID_WRITEPTR( pusPort, sizeof( USHORT ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for port" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
#endif // !DPNBUILD_NOPARAMVAL
DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pguidAdapter = 0x%p pusPort = 0x%p",
pguidAdapter, pusPort );
#ifndef DPNBUILD_ONLYONESP
hr = pdp8Address->GetSP( &guidSP );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "No provider SP specified hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( guidSP != CLSID_DP8SP_TCPIP )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Not an IP address" );
hr = DPNERR_INVALIDADDRESSFORMAT;
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONESP
#ifndef DPNBUILD_ONLYONEADAPTER
hr = pdp8Address->GetElementType( DPNA_KEY_DEVICE, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "This device element doesn't exist hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( dwType != DPNA_DATATYPE_GUID )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The device is not a GUID hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONEADAPTER
hr = pdp8Address->GetElementType( DPNA_KEY_PORT, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a port element hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( dwType != DPNA_DATATYPE_DWORD )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The port is not a dword hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
dwSize = sizeof(DWORD);
hr = pdp8Address->GetElement( DPNA_KEY_PORT, &dwPort, &dwSize, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve port element hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
#ifdef DPNBUILD_ONLYONEADAPTER
// Just return GUID_NULL
memset(pguidAdapter, 0, sizeof(GUID));
#else // ! DPNBUILD_ONLYONEADAPTER
dwSize = sizeof(GUID);
hr = pdp8Address->GetElement( DPNA_KEY_DEVICE, &guidDevice, &dwSize, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve device element hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
*pguidAdapter = guidDevice;
#endif // ! DPNBUILD_ONLYONEADAPTER
*pusPort = (USHORT) dwPort;
DP8A_RETURN( DPN_OK );
}
#undef DPF_MODNAME
#define DPF_MODNAME "DP8ATCP_GetAddressW"
STDMETHODIMP DP8ATCP_GetAddressW( IDirectPlay8AddressIP *pInterface, WCHAR * pwszAddress, PDWORD pdwAddressLength, PUSHORT pusPort )
{
HRESULT hr;
DWORD dwPort;
DWORD dwType;
DWORD dwSize;
#ifndef DPNBUILD_ONLYONESP
GUID guidSP;
#endif // ! DPNBUILD_ONLYONESP
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Enter" );
#ifndef DPNBUILD_NOPARAMVAL
if( pInterface == NULL ||
!DP8A_VALID( pInterface ) )
{
DPFX(DPFPREP, DP8A_ENTERLEVEL, "Invalid object" );
DP8A_RETURN( DPNERR_INVALIDOBJECT );
}
if( pdwAddressLength == NULL ||
!DNVALID_WRITEPTR( pdwAddressLength, sizeof( DWORD ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pdwAddressLength" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
if( *pdwAddressLength > 0 &&
(pwszAddress == NULL || !DNVALID_WRITEPTR( pwszAddress, (*pdwAddressLength)*sizeof(WCHAR) ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for pwszAddress" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
if( pusPort == NULL ||
!DNVALID_WRITEPTR( pusPort, sizeof( USHORT ) ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid pointer for port" );
DP8A_RETURN( DPNERR_INVALIDPOINTER );
}
#endif // !DPNBUILD_NOPARAMVAL
DP8ADDRESSOBJECT *pdp8Address = (DP8ADDRESSOBJECT *) GET_OBJECT_FROM_INTERFACE( pInterface );
DPFX(DPFPREP, DP8A_PARAMLEVEL, "pwszAddress = 0x%p pdwAddressLength = 0x%p (%u) pusPort = 0x%p (%u)",
pwszAddress, pdwAddressLength, *pdwAddressLength, pusPort, (DWORD)*pusPort );
#ifndef DPNBUILD_ONLYONESP
hr = pdp8Address->GetSP( &guidSP );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "No provider SP specified hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( guidSP != CLSID_DP8SP_TCPIP )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Not an IP address" );
hr = DPNERR_INVALIDADDRESSFORMAT;
DP8A_RETURN( hr );
}
#endif // ! DPNBUILD_ONLYONESP
hr = pdp8Address->GetElementType( DPNA_KEY_HOSTNAME, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a hostname element hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( dwType != DPNA_DATATYPE_STRING )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The host name is not a string hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
hr = pdp8Address->GetElementType( DPNA_KEY_PORT, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "This address does not have a port element hr=0x%x", hr );
hr = DPNERR_INCOMPLETEADDRESS;
DP8A_RETURN( hr );
}
if( dwType != DPNA_DATATYPE_DWORD )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Invalid Address: The port is not a dword hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
dwSize = sizeof(DWORD);
hr = pdp8Address->GetElement( DPNA_KEY_PORT, &dwPort, &dwSize, &dwType );
if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve port element hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
*pdwAddressLength *= 2;
hr = pdp8Address->GetElement( DPNA_KEY_HOSTNAME, pwszAddress, pdwAddressLength, &dwType );
*pdwAddressLength /= 2;
if( hr == DPNERR_BUFFERTOOSMALL )
{
DPFX(DPFPREP, DP8A_WARNINGLEVEL, "Buffer too small hr=0x%x", hr );
DP8A_RETURN( hr );
}
else if( FAILED( hr ) )
{
DPFX(DPFPREP, DP8A_ERRORLEVEL, "Unable to retrieve hostname element hr=0x%x", hr );
hr = DPNERR_GENERIC;
DP8A_RETURN( hr );
}
*pusPort = (USHORT) dwPort;
DP8A_RETURN( DPN_OK );
}
#endif // ! DPNBUILD_NOADDRESSIPINTERFACE