|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
lbcnfg.cxx
Abstract:
Classes to handle IIS load balancing configuration
Author:
Philippe Choquier (phillich)
--*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <mbstring.h>
#include <winsock2.h>
#include "lbxbf.hxx"
#include "lbcnfg.hxx"
#if defined(_NOISY_DEBUG)
#define DEBUG_BUFFER char achE[128]
#define DBG_PRINTF(a) wsprintf a; OutputDebugString( achE )
#define DBG_PUTS(a) OutputDebugString(a)
#else
#define DEBUG_BUFFER
#define DBG_PRINTF(a)
#define DBG_PUTS(a)
#endif
CIPMap::CIPMap( ) /*++
Routine Description:
CIPMap constructor
Arguments:
none
Return Value:
nothing
--*/ { }
CIPMap::~CIPMap( ) /*++
Routine Description:
CIPMap destructor
Arguments:
none
Return Value:
nothing
--*/ { Reset(); }
VOID CIPMap::Reset( ) /*++
Routine Description:
Reset a CIPMap to empty content
Arguments:
none
Return Value:
nothing
--*/ { UINT iComp;
for ( iComp = 0 ; iComp < m_Servers.GetNbPtr() ; ++iComp ) { delete (CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ); } m_Servers.Reset(); m_IpPublic.Reset(); m_Sticky.Reset(); m_Attr.Reset(); }
BOOL CIPMap::Serialize( CStoreXBF* pX ) /*++
Routine Description:
serialize a CIPMap to buffer
Arguments:
buffer where to serialize
Return Value:
TRUE if success, otherwise FALSE
--*/ { UINT iComp;
if ( !::Serialize( pX, (DWORD)IPLIST_VERSION ) ) { return FALSE; }
if ( !::Serialize( pX, (DWORD)m_Servers.GetNbPtr() ) ) { return FALSE; }
if ( !::Serialize( pX, (DWORD)m_IpPublic.GetNbEntry() ) ) { return FALSE; }
for ( iComp = 0 ; iComp < m_Servers.GetNbPtr() ; ++iComp ) { if ( !((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->Serialize( pX ) ) { return FALSE; } }
if ( !m_IpPublic.Serialize( pX ) || !m_Name.Serialize( pX ) || !m_Sticky.Serialize( pX ) || !m_Attr.Serialize( pX ) ) { return FALSE; }
return TRUE; }
BOOL CIPMap::Unserialize( CStoreXBF* pX ) /*++
Routine Description:
Unserialize a CIPMap
Arguments:
pX - ptr to buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { LPBYTE pb = pX->GetBuff(); DWORD dw = pX->GetUsed();
return Unserialize( &pb, &dw ); }
BOOL CIPMap::Unserialize( LPBYTE* ppb, LPDWORD pc ) /*++
Routine Description:
Unserialize IP Map
Arguments:
ppb - ptr to addr of buffer to unserialize from pc - ptr to count of bytes in buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { DWORD dwComp; UINT iComp; DWORD dwPublicIp; UINT iPublicIp; CComputerBalanceCnfg* pComp; DWORD dwVersion; DEBUG_BUFFER;
Reset();
if ( !::Unserialize( ppb, pc, &dwVersion ) ) { return FALSE; }
if ( !::Unserialize( ppb, pc, &dwComp ) || !::Unserialize( ppb, pc, &dwPublicIp ) ) { DBG_PRINTF(( achE, "CIPMap::Unserialize error 1, pb=%08x c=%d\n", *ppb, *pc)); return FALSE; }
for ( iComp = 0 ; iComp < dwComp ; ++iComp ) { if ( !(pComp = new CComputerBalanceCnfg) || m_Servers.AddPtr( pComp ) == INDEX_ERROR || !pComp->Unserialize( ppb, pc, dwPublicIp ) ) { DBG_PUTS("CIPMap::Unserialize error 2\n" ); return FALSE; } }
if ( !m_IpPublic.Unserialize( ppb, pc, dwPublicIp ) || !m_Name.Unserialize( ppb, pc, dwPublicIp ) || !m_Sticky.Unserialize( ppb, pc, dwPublicIp ) || !m_Attr.Unserialize( ppb, pc, dwPublicIp ) ) { DBG_PUTS("CIPMap::Unserialize error 3\n" ); return FALSE; }
return TRUE; }
BOOL LoadBlobFromReg( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue, CStoreXBF* pX ) /*++
Routine Description:
Load a buffer from registry
Arguments:
hKey - registry handle where to open key to read value pszRegKey - key where to read value pszRegValue - value name pX - ptr to buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { BOOL fSt = FALSE; HKEY hK; DWORD dwNeed; DWORD dwType; DWORD dwStatus; CHAR achE[128];
if ( (dwStatus = RegOpenKeyEx( hKey, pszRegKey, 0, KEY_READ, &hK )) == ERROR_SUCCESS ) { dwNeed = 0;
if ( (dwStatus = RegQueryValueEx( hK, pszRegValue, 0, &dwType, NULL, &dwNeed )) == ERROR_SUCCESS && dwType == REG_BINARY && pX->Need( dwNeed ) && (dwStatus = RegQueryValueEx( hK, pszRegValue, 0, &dwType, pX->GetBuff(), &dwNeed )) == ERROR_SUCCESS ) { pX->SetUsed( dwNeed ); fSt = TRUE; }
RegCloseKey( hK ); }
if ( !fSt ) { SetLastError( dwStatus ); DBG_PUTS( "Error LoadBlobFromReg\n" ); }
return fSt; }
BOOL CIPMap::Load( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue ) /*++
Routine Description:
Load a CIPMap from registry
Arguments:
hKey - registry handle where to open key to read value pszRegKey - key where to read value pszRegValue - value name
Return Value:
TRUE if success, otherwise FALSE
--*/ { CStoreXBF xbf;
return LoadBlobFromReg( hKey, pszRegKey, pszRegValue, &xbf ) && Unserialize( &xbf ); }
BOOL SaveBlobToReg( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue, CStoreXBF* pX ) /*++
Routine Description:
Save a buffer to registry
Arguments:
hKey - registry handle where to open key to write value pszRegKey - key where to write value pszRegValue - value name pX - ptr to buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { BOOL fSt = FALSE; HKEY hK; DWORD dwDisposition; DWORD dwStatus;
if ( (dwStatus = RegCreateKeyEx( hKey, pszRegKey, 0, "", REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hK, &dwDisposition )) == ERROR_SUCCESS ) { if ( (dwStatus = RegSetValueEx( hK, pszRegValue, 0, REG_BINARY, pX->GetBuff(), pX->GetUsed() )) == ERROR_SUCCESS ) { fSt = TRUE; }
RegCloseKey( hK ); }
if ( !fSt ) { SetLastError( dwStatus ); }
return fSt; }
BOOL CIPMap::Save( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue ) /*++
Routine Description:
Save a CIPMap to registry
Arguments:
hKey - registry handle where to open key to write value pszRegKey - key where to write value pszRegValue - value name
Return Value:
TRUE if success, otherwise FALSE
--*/ { CStoreXBF xbf;
return Serialize( &xbf ) && SaveBlobToReg( hKey, pszRegKey, pszRegValue, &xbf ); }
BOOL CIPMap::AddComputer( LPWSTR pszName ) /*++
Routine Description:
Add a computer in CIPMap
Arguments:
pszName - computer name to be added at the end of computer list
Return Value:
TRUE if success, otherwise FALSE
--*/ { CComputerBalanceCnfg* pComp; UINT iComp; LPWSTR pszCheckName;
for ( iComp = 0 ; iComp < m_Servers.GetNbPtr() ; ++iComp ) { if ( ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ))->GetName( &pszCheckName ) && !_wcsicmp( pszCheckName, pszName ) ) { SetLastError( ERROR_ALREADY_EXISTS ); return FALSE; } }
if ( (pComp = new CComputerBalanceCnfg) && m_Servers.AddPtr( (LPVOID)pComp ) != INDEX_ERROR && pComp->Init( pszName, m_IpPublic.GetNbEntry() ) ) { return TRUE; }
delete pComp;
return FALSE; }
BOOL CIPMap::EnumComputer( UINT iComp, LPWSTR* ppszName ) /*++
Routine Description:
Enumerate computers in CIPMap
Arguments:
iComp - computer index ( 0-based ) ppszName - updated with read-only computer name on success
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
--*/ { if ( iComp >= m_Servers.GetNbPtr() ) { SetLastError( ERROR_NO_MORE_ITEMS ); return FALSE; }
return ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ))->GetName( ppszName ); }
BOOL CIPMap::DeleteComputer( UINT iComp ) /*++
Routine Description:
Delete a computer in CIPMap
Arguments:
iComp - computer index ( 0-based )
Return Value:
TRUE if success, otherwise FALSE
--*/ { if ( iComp >= m_Servers.GetNbPtr() ) { return FALSE; }
delete ((CComputerBalanceCnfg*)m_Servers.GetPtr( iComp ));
return m_Servers.DeletePtr( iComp ); }
BOOL CIPMap::AddIpPublic( LPWSTR pszIpPublic, LPWSTR pszName, DWORD dwSticky, DWORD dwAttr ) /*++
Routine Description:
Add a public IP address in CIPMap
Arguments:
pszIpPublic - public IP address to be added at the end of public IP address list pszName - name associated with IP address dwSticky - sticky duration ( in seconds ) dwAttr - user defined param
Return Value:
TRUE if success, otherwise FALSE
--*/ { UINT iComp; UINT iIp;
for ( iIp = 0 ; iIp < m_IpPublic.GetNbPtr() ; ++iIp ) { if ( !_wcsicmp( m_IpPublic.GetEntry( iIp ), pszIpPublic ) ) { SetLastError( ERROR_ALREADY_EXISTS ); return FALSE; } }
if ( m_IpPublic.AddEntry( pszIpPublic ) == INDEX_ERROR || m_Name.AddEntry( pszName ) == INDEX_ERROR || m_Sticky.AddPtr( (LPVOID)dwSticky) == INDEX_ERROR || m_Attr.AddPtr( (LPVOID)dwAttr) == INDEX_ERROR ) { return FALSE; }
for ( iComp = 0 ; iComp < m_Servers.GetNbPtr() ; ++iComp ) { if ( ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->AddIpPublic() == INDEX_ERROR ) { return FALSE; } }
return TRUE; }
BOOL CIPMap::EnumIpPublic( UINT iIpPublic, LPWSTR* ppszIpPublic, LPWSTR* ppszName, LPDWORD pdwSticky, LPDWORD pdwAttr ) /*++
Routine Description:
Enumerate public IP addresses in CIPMap
Arguments:
iIpPublic - public IP address index ( 0-based ) ppszIpPublic - updated with read-only public IP address on success ppszName - associated name pdwSticky - associated sticky duration pdwAttr - associated user attr
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
--*/ { if ( iIpPublic >= m_IpPublic.GetNbEntry() ) { SetLastError( ERROR_NO_MORE_ITEMS ); return FALSE; }
*ppszIpPublic = m_IpPublic.GetEntry( iIpPublic ); *ppszName = m_Name.GetEntry( iIpPublic ); *pdwSticky = (DWORD)m_Sticky.GetPtr( iIpPublic ); // BUGBUG64
*pdwAttr = (DWORD)m_Attr.GetPtr( iIpPublic ); // BUGBUG64
return TRUE; }
BOOL CIPMap::DeleteIpPublic( UINT iIpPublic ) /*++
Routine Description:
Delete a public IP address in CIPMap
Arguments:
iIpPublic - public IP address index ( 0-based )
Return Value:
TRUE if success, otherwise FALSE
--*/ { UINT iComp;
if ( !m_IpPublic.DeleteEntry( iIpPublic ) || !m_Name.DeleteEntry( iIpPublic ) || !m_Sticky.DeletePtr( iIpPublic ) || !m_Attr.DeletePtr( iIpPublic ) ) { return FALSE; }
for ( iComp = 0 ; iComp < m_Servers.GetNbPtr() ; ++iComp ) { if ( !((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->DeleteIpPublic(iIpPublic) ) { return FALSE; } }
return TRUE; }
BOOL CIPMap::SetIpPrivate( UINT iComp, UINT iIpPublic, LPWSTR pszIpPrivate, LPWSTR pszName ) /*++
Routine Description:
Set a private IP address in CIPMap
Arguments:
iComp - computer index iIpPublic - public IP address index pszIpPrivate - private IP addresse to associate with iComp & iIpPublic pszName - name associated with private IP address
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_INVALID_PARAMETER if indexes out of range
--*/ { if ( iIpPublic >= m_IpPublic.GetNbEntry() || iComp >= m_Servers.GetNbPtr() ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
return ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))-> SetIpPrivate( iIpPublic, pszIpPrivate, pszName); }
BOOL CIPMap::GetIpPrivate( UINT iComp, UINT iIpPublic, LPWSTR* ppszIpPrivate, LPWSTR* ppszName ) /*++
Routine Description:
Get a private IP address in CIPMap
Arguments:
iComp - computer index iIpPublic - public IP address index ppszIpPrivate - updated with read-only private IP addresse associated with iComp & iIpPublic ppszName - updated with read-pnly name associated with iComp & iIpPublic
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_INVALID_PARAMETER if indexes out of range
--*/ { if ( iIpPublic >= m_IpPublic.GetNbEntry() || iComp >= m_Servers.GetNbPtr() ) { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; }
return ((CComputerBalanceCnfg*)m_Servers.GetPtr(iComp))->GetIpPrivate(iIpPublic,ppszIpPrivate,ppszName); }
BOOL CComputerBalanceCnfg::Init( LPWSTR pszName, UINT cIpPublic ) /*++
Routine Description:
Initialize a CComputerBalanceCnfg with computer name, creating cIpPublic entries in private IP addresses list
Arguments:
pszName - computer name cIpPublic - count of current public IP addresses
Return Value:
TRUE if success, otherwise FALSE
--*/ { if ( !m_ComputerName.Set( pszName ) ) { return FALSE; }
while ( cIpPublic-- ) { if ( m_IpPrivate.AddEntry(L"") == INDEX_ERROR || m_Name.AddEntry(L"") == INDEX_ERROR ) { return FALSE; } }
return TRUE; }
CComputerPerfCounters::CComputerPerfCounters() /*++
Routine Description:
CComputerPerfCounters constructor
Arguments:
none
Return Value:
nothing
--*/ { }
CComputerPerfCounters::~CComputerPerfCounters() /*++
Routine Description:
CComputerPerfCounters destructor
Arguments:
none
Return Value:
nothing
--*/ { Reset(); }
VOID CComputerPerfCounters::Reset( ) /*++
Routine Description:
Reset a CIPMap to empty content
Arguments:
none
Return Value:
nothing
--*/ { m_PerfCounters.Reset(); m_Weight.Reset(); }
BOOL CComputerPerfCounters::Serialize( CStoreXBF* pX ) /*++
Routine Description:
serialize a CComputerPerfCounters to buffer
Arguments:
buffer where to serialize
Return Value:
TRUE if success, otherwise FALSE
--*/ { if ( !::Serialize( pX, (DWORD)PERFLIST_VERSION ) ) { return FALSE; }
return ::Serialize( pX, (DWORD)m_PerfCounters.GetNbEntry() ) && m_PerfCounterServers.Serialize( pX ) && m_PerfCounters.Serialize( pX ) && m_Weight.Serialize( pX ); }
BOOL CComputerPerfCounters::Unserialize( CStoreXBF* pX ) /*++
Routine Description:
Unserialize a CComputerPerfCounters
Arguments:
pX - ptr to buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { LPBYTE pb = pX->GetBuff(); DWORD dw = pX->GetUsed();
return Unserialize( &pb, &dw ); }
BOOL CComputerPerfCounters::Unserialize( LPBYTE* ppb, LPDWORD pdw ) /*++
Routine Description:
Unserialize a CComputerPerfCounters
Arguments:
ppB - ptr to addr of buffer to unserialize from pC - ptr to count of bytes in buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { DWORD dwP; DWORD dwVersion;
if ( !::Unserialize( ppb, pdw, &dwVersion ) ) { return FALSE; }
return ::Unserialize( ppb, pdw, &dwP ) && m_PerfCounterServers.Unserialize( ppb, pdw, dwP ) && m_PerfCounters.Unserialize( ppb, pdw, dwP ) && m_Weight.Unserialize( ppb, pdw, dwP ); }
BOOL CComputerPerfCounters::Load( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue ) /*++
Routine Description:
Load a CComputerPerfCounters from registry
Arguments:
hKey - registry handle where to open key to read value pszRegKey - key where to read value pszRegValue - value name
Return Value:
TRUE if success, otherwise FALSE
--*/ { CStoreXBF xbf;
return LoadBlobFromReg( hKey, pszRegKey, pszRegValue, &xbf ) && Unserialize( &xbf ); }
BOOL CComputerPerfCounters::Save( HKEY hKey, LPSTR pszRegKey, LPSTR pszRegValue ) /*++
Routine Description:
Save a CComputerPerfCounters to registry
Arguments:
hKey - registry handle where to open key to write value pszRegKey - key where to write value pszRegValue - value name
Return Value:
TRUE if success, otherwise FALSE
--*/ { CStoreXBF xbf;
return Serialize( &xbf ) && SaveBlobToReg( hKey, pszRegKey, pszRegValue, &xbf ); }
BOOL CComputerPerfCounters::AddPerfCounter( LPWSTR pszServerName, LPWSTR pszPerfCounter, DWORD dwWeight ) /*++
Routine Description:
Add a performance counter in CIPMap
Arguments:
pszServerName - optional server name ( can be NULL ) pszIpPublic - performance counter to be added at the end of performance counter list dwWeight - weight associated with perf counter to add
Return Value:
TRUE if success, otherwise FALSE
--*/ { UINT iPerf;
//
// Check if specify normalized flag then to other counter exist.
// if not normalized then existing counter should not be normalized.
//
if ( dwWeight == LB_WEIGHT_NORMALIZED_FLAG && m_PerfCounterServers.GetNbEntry() ) { SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; } else if ( dwWeight != LB_WEIGHT_NORMALIZED_FLAG ) { for ( iPerf = 0 ; iPerf < m_PerfCounters.GetNbEntry() ; ++iPerf ) { if ( (DWORD)m_Weight.GetPtr( iPerf ) == LB_WEIGHT_NORMALIZED_FLAG ) // BUGBUG64
{ SetLastError( ERROR_INVALID_PARAMETER );
return FALSE; } } }
return m_PerfCounterServers.AddEntry( pszServerName ? pszServerName : L"") != INDEX_ERROR && m_PerfCounters.AddEntry( pszPerfCounter ) != INDEX_ERROR && m_Weight.AddPtr( (LPVOID)dwWeight ) != INDEX_ERROR; }
BOOL CComputerPerfCounters::EnumPerfCounter( UINT iPerfCounter, LPWSTR* ppszPerfCounterServer, LPWSTR* ppszPerfCounter, DWORD* pdwWeight ) /*++
Routine Description:
Enumerate performance counters in CComputerPerfCounters
Arguments:
iPerfCounter - public IP address index ( 0-based ) ppszServerName - updated with read-only server name ( can be NULL ) ppszPerfCounter - updated with read-only performance counter on success pdwWeight - updated with read-only perf counter weight on success
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
--*/ { if ( iPerfCounter >= m_PerfCounters.GetNbEntry() ) { SetLastError( ERROR_NO_MORE_ITEMS ); return FALSE; }
*ppszPerfCounterServer = *m_PerfCounterServers.GetEntry( iPerfCounter ) ? m_PerfCounterServers.GetEntry( iPerfCounter ) : NULL; *ppszPerfCounter = m_PerfCounters.GetEntry( iPerfCounter ); *pdwWeight = (DWORD)m_Weight.GetPtr( iPerfCounter ); // BUGBUG64
return TRUE; }
BOOL CComputerPerfCounters::DeletePerfCounter( UINT iPerfCounter ) /*++
Routine Description:
Delete a performance counter in CComputerPerfCounters
Arguments:
iPerfCounter - performance counter index ( 0-based )
Return Value:
TRUE if success, otherwise FALSE
--*/ { return m_PerfCounterServers.DeleteEntry( iPerfCounter ) && m_PerfCounters.DeleteEntry( iPerfCounter ) && m_Weight.DeletePtr( iPerfCounter ); }
BOOL CComputerPerfCounters::SetPerfCounterWeight( UINT iPerfCounter, DWORD dwWeight ) /*++
Routine Description:
Set a performance counter weight in CIPMap
Arguments:
iPerfCounter - performance counter index dwWeight - weight to associate with performance counter indexed by iPerfCounter
Return Value:
TRUE if success, otherwise FALSE
--*/ { return m_Weight.SetPtr( iPerfCounter, (LPVOID)dwWeight ); }
/////////////////
CIpEndpointList::CIpEndpointList( ) /*++
Routine Description:
CIpEndpointList constructor
Arguments:
none
Return Value:
nothing
--*/ { }
CIpEndpointList::~CIpEndpointList( ) /*++
Routine Description:
CIpEndpointList destructor
Arguments:
none
Return Value:
nothing
--*/ { Reset(); }
VOID CIpEndpointList::Reset( ) /*++
Routine Description:
Reset a CIpEndpointList to empty content
Arguments:
none
Return Value:
nothing
--*/ { UINT iComp;
m_IpEndpoint.Reset(); }
BOOL CIpEndpointList::Serialize( CStoreXBF* pX ) /*++
Routine Description:
serialize a CIpEndpointList to buffer
Arguments:
buffer where to serialize
Return Value:
TRUE if success, otherwise FALSE
--*/ { if ( !::Serialize( pX, (DWORD)m_IpEndpoint.GetNbEntry() ) ) { return FALSE; }
if ( !m_IpEndpoint.Serialize( pX ) ) { return FALSE; }
return TRUE; }
BOOL CIpEndpointList::Unserialize( CStoreXBF* pX ) /*++
Routine Description:
Unserialize a CIpEndpointList
Arguments:
pX - ptr to buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { LPBYTE pb = pX->GetBuff(); DWORD dw = pX->GetUsed();
return Unserialize( &pb, &dw ); }
BOOL CIpEndpointList::Unserialize( LPBYTE* ppb, LPDWORD pc ) /*++
Routine Description:
Unserialize CIpEndpointList
Arguments:
ppb - ptr to addr of buffer to unserialize from pc - ptr to count of bytes in buffer
Return Value:
TRUE if success, otherwise FALSE
--*/ { DWORD dwIp;
Reset();
if ( !::Unserialize( ppb, pc, &dwIp ) ) { return FALSE; }
if ( !m_IpEndpoint.Unserialize( ppb, pc, dwIp ) ) { return FALSE; }
return TRUE; }
BOOL CIpEndpointList::EnumIpEndpoint( UINT iIp, LPWSTR* ppszIp ) /*++
Routine Description:
Enumerate IP endpoints
Arguments:
iIp - IP index ( 0-based ) ppszName - updated with read-only IP addr ( as string ) on success
Return Value:
TRUE if success, otherwise FALSE LastError will be set to ERROR_NO_MORE_ITEMS if index out of range
--*/ { if ( iIp >= m_IpEndpoint.GetNbEntry() ) { SetLastError( ERROR_NO_MORE_ITEMS ); return FALSE; }
*ppszIp = m_IpEndpoint.GetEntry( iIp );
return TRUE; }
BOOL CIpEndpointList::BuildListFromLocalhost( ) /*++
Routine Description:
Build list of local IP endpoints
Arguments:
None
Return Value:
TRUE if success, otherwise FALSE
--*/ { char** pAddr; sockaddr_in SockAddr; struct hostent* pH; WCHAR achAddr[128]; DWORD cAddr;
Reset();
if ( pH = gethostbyname( NULL ) ) { if ( pH->h_addrtype == AF_INET ) { for ( pAddr = pH->h_addr_list; *pAddr ; ++pAddr ) { memcpy( &SockAddr.sin_addr, *pAddr, 4 ); SockAddr.sin_family = AF_INET; SockAddr.sin_port = 0;
cAddr = sizeof( achAddr ) / sizeof(WCHAR);
if ( WSAAddressToStringW( (struct sockaddr *)&SockAddr, sizeof(SockAddr), NULL, achAddr, &cAddr ) != 0 || m_IpEndpoint.AddEntry( achAddr ) == INDEX_ERROR ) { return FALSE; } }
return TRUE; } else { SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } }
return FALSE; }
|