2796 lines
71 KiB
C++
2796 lines
71 KiB
C++
//+---------------------------------------------------------------------------
|
||
//
|
||
// Microsoft Windows
|
||
// Copyright (C) Microsoft Corporation, 1997 - 2000
|
||
//
|
||
// File: H N C A P I . C P P
|
||
//
|
||
// Contents: Routines exported from HNetCfg.dll
|
||
//
|
||
// Notes:
|
||
//
|
||
// Author: jonburs 20 June 2000
|
||
//
|
||
// History: billi 09 July 2000 - added HNet[Get|Set]ShareAndBridgeSettings
|
||
// and supporting static functions
|
||
// billi 14 Sep 2000 - added timeout work around for bridge creation
|
||
// and SharePrivate. This work to be removed
|
||
// by Whistler Beta 2 due to DHCP fix.
|
||
// billi 27 Dec 2000 - added HNW logging strings
|
||
//
|
||
//----------------------------------------------------------------------------
|
||
|
||
#include "pch.h"
|
||
#pragma hdrstop
|
||
#include <lmcons.h>
|
||
#include <lmapibuf.h>
|
||
#include <ndispnp.h>
|
||
#include <raserror.h>
|
||
#include <winsock2.h>
|
||
#include <iphlpapi.h> // ip helper
|
||
#include <netconp.h>
|
||
|
||
extern "C" { // make it work in C++
|
||
#include <dhcpcsdk.h> // dhcp client options api
|
||
#include "powrprof.h"
|
||
}
|
||
|
||
|
||
const DWORD MAX_DISABLE_EVENT_TIMEOUT = 0xFFFF;
|
||
|
||
#define SECONDS_TO_WAIT_FOR_BRIDGE 20
|
||
#define SECONDS_TO_WAIT_FOR_DHCP 20
|
||
#define INITIAL_BUFFER_SIZE 256
|
||
|
||
extern HINSTANCE g_hOemInstance;
|
||
|
||
typedef struct _HNET_DELETE_RAS_PARAMS
|
||
{
|
||
GUID Guid;
|
||
HMODULE hModule;
|
||
} HNET_DELETE_RAS_PARAMS, *PHNET_DELETE_RAS_PARAMS;
|
||
|
||
|
||
|
||
VOID
|
||
HNetFreeFirewallLoggingSettings(
|
||
HNET_FW_LOGGING_SETTINGS *pSettings
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Frees the memory used by a an HNET_FW_LOGGING_SETTINGS structure. This
|
||
routine should only be used for structures obtained from
|
||
IHNetFirewallSettings::GetFirewallLoggingSettings.
|
||
|
||
|
||
Arguments:
|
||
|
||
pSettings - pointer to the structure to free. This pointer should not be
|
||
NULL.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
if (NULL != pSettings)
|
||
{
|
||
if (NULL != pSettings->pszwPath)
|
||
{
|
||
CoTaskMemFree(pSettings->pszwPath);
|
||
}
|
||
|
||
CoTaskMemFree(pSettings);
|
||
}
|
||
else
|
||
{
|
||
_ASSERT(FALSE);
|
||
}
|
||
}
|
||
|
||
|
||
DWORD
|
||
WINAPI
|
||
HNetDeleteRasConnectionWorker(
|
||
VOID *pVoid
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Work item to perform the actual cleanup of a deleted
|
||
RAS connection.
|
||
|
||
Arguments:
|
||
|
||
pVoid - HNET_DELETE_RAS_PARAMS
|
||
|
||
Return Value:
|
||
|
||
DWORD
|
||
|
||
--*/
|
||
|
||
{
|
||
BOOL fComInitialized = FALSE;
|
||
HRESULT hr;
|
||
IHNetCfgMgr *pHNetCfgMgr;
|
||
IHNetConnection *pHNetConnection;
|
||
PHNET_DELETE_RAS_PARAMS pParams;
|
||
|
||
_ASSERT(NULL != pVoid);
|
||
pParams = reinterpret_cast<PHNET_DELETE_RAS_PARAMS>(pVoid);
|
||
|
||
//
|
||
// Make sure COM is initialized on this thread
|
||
//
|
||
|
||
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
fComInitialized = TRUE;
|
||
}
|
||
else if (RPC_E_CHANGED_MODE == hr)
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
|
||
//
|
||
// Create the config manager
|
||
//
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = CoCreateInstance(
|
||
CLSID_HNetCfgMgr,
|
||
NULL,
|
||
CLSCTX_SERVER,
|
||
IID_PPV_ARG(IHNetCfgMgr, &pHNetCfgMgr)
|
||
);
|
||
}
|
||
|
||
//
|
||
// Try to obtain the IHNetConnection for the guid
|
||
//
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = pHNetCfgMgr->GetIHNetConnectionForGuid(
|
||
&pParams->Guid,
|
||
FALSE,
|
||
FALSE,
|
||
&pHNetConnection
|
||
);
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
//
|
||
// Ask the connection to delete itself
|
||
//
|
||
|
||
hr = pHNetConnection->DeleteRasConnectionEntry();
|
||
pHNetConnection->Release();
|
||
}
|
||
|
||
pHNetCfgMgr->Release();
|
||
}
|
||
|
||
//
|
||
// Uninitialize COM, if necessary
|
||
//
|
||
|
||
if (TRUE == fComInitialized)
|
||
{
|
||
CoUninitialize();
|
||
}
|
||
|
||
//
|
||
// Free the params and exit thread.
|
||
//
|
||
|
||
HMODULE hModule = pParams->hModule;
|
||
HeapFree(GetProcessHeap(), 0, pParams);
|
||
FreeLibraryAndExitThread(hModule, ERROR_SUCCESS);
|
||
|
||
return ERROR_SUCCESS;
|
||
} // HNetDeleteRasConnectionWorker
|
||
|
||
|
||
VOID
|
||
WINAPI
|
||
HNetDeleteRasConnection(
|
||
GUID *pGuid
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Called by rasapi32 when a RAS connection is being deleted. The
|
||
actual work is performed on a separate thread.
|
||
|
||
Arguments:
|
||
|
||
pGuid - the GUID of the connection to delete
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
HANDLE hThread;
|
||
PHNET_DELETE_RAS_PARAMS pParams = NULL;
|
||
|
||
do
|
||
{
|
||
if (NULL == pGuid)
|
||
{
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Setup the work item paramters
|
||
//
|
||
|
||
pParams =
|
||
reinterpret_cast<PHNET_DELETE_RAS_PARAMS>(
|
||
HeapAlloc(GetProcessHeap(), 0, sizeof(*pParams))
|
||
);
|
||
|
||
if (NULL == pParams)
|
||
{
|
||
break;
|
||
}
|
||
|
||
//
|
||
// We need to add a reference to hnetcfg to guarantee that the
|
||
// dll won't be unloaded before the worker finishes execution.
|
||
//
|
||
|
||
pParams->hModule = LoadLibraryW(L"hnetcfg");
|
||
|
||
if (NULL == pParams->hModule)
|
||
{
|
||
break;
|
||
}
|
||
|
||
CopyMemory(&pParams->Guid, pGuid, sizeof(*pGuid));
|
||
|
||
//
|
||
// Create the worker thread. (We can't use QueueUserWorkItem
|
||
// due to a possible race condition w/r/t unloading the
|
||
// library and returning from the work item).
|
||
//
|
||
|
||
hThread =
|
||
CreateThread(
|
||
NULL,
|
||
0,
|
||
HNetDeleteRasConnectionWorker,
|
||
pParams,
|
||
0,
|
||
NULL
|
||
);
|
||
|
||
if (NULL == hThread)
|
||
{
|
||
break;
|
||
}
|
||
|
||
CloseHandle(hThread);
|
||
|
||
return;
|
||
|
||
} while (FALSE);
|
||
|
||
|
||
//
|
||
// Failure path cleanup
|
||
//
|
||
|
||
if (NULL != pParams)
|
||
{
|
||
if (NULL != pParams->hModule)
|
||
{
|
||
FreeLibrary(pParams->hModule);
|
||
}
|
||
|
||
HeapFree(GetProcessHeap(), 0, pParams);
|
||
}
|
||
|
||
} // HNetDeleteRasConnection
|
||
|
||
|
||
|
||
#if DBG
|
||
|
||
WCHAR tcDbgPrtBuf[ BUF_SIZE + 1 ] = _T("");
|
||
|
||
void inline rawdebugprintf( wchar_t *buf )
|
||
{
|
||
_sntprintf( tcDbgPrtBuf, BUF_SIZE, buf );
|
||
|
||
tcDbgPrtBuf[BUF_SIZE] = _T('\0');
|
||
|
||
OutputDebugString(tcDbgPrtBuf);
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
void inline debugprintf( wchar_t *preamble, wchar_t *buf )
|
||
{
|
||
OutputDebugString( _T("HNET: ") );
|
||
|
||
OutputDebugString( preamble );
|
||
|
||
OutputDebugString( buf );
|
||
|
||
OutputDebugString( _T("\r\n") );
|
||
|
||
return;
|
||
}
|
||
|
||
void inline debugretprintf( wchar_t *msg, HRESULT hResult )
|
||
{
|
||
_sntprintf( tcDbgPrtBuf, BUF_SIZE, _T("HNET: %s = %x\r\n"), msg, hResult );
|
||
|
||
tcDbgPrtBuf[BUF_SIZE] = _T('\0');
|
||
|
||
OutputDebugString( tcDbgPrtBuf );
|
||
|
||
return;
|
||
}
|
||
|
||
#define TRACE_ENTER(x) debugprintf( _T("==> "), _T(x) );
|
||
|
||
#define TRACE_LEAVE(x,y) debugretprintf( _T("<== ")_T(x), y );
|
||
|
||
#else
|
||
|
||
#define rawdebugprintf(x)
|
||
#define debugprintf(x,y)
|
||
#define debugretprintf(x,y)
|
||
#define TRACE_ENTER(x)
|
||
#define TRACE_LEAVE(x,y)
|
||
|
||
#endif
|
||
|
||
|
||
|
||
HRESULT
|
||
UpdateHnwLog(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
IN UINT uID,
|
||
IN LPCWSTR lpczwValue
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
|
||
if ( NULL == lpHnwCallback )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else
|
||
{
|
||
LPWSTR lpFormat = new WCHAR[ NOTIFYFORMATBUFFERSIZE ];
|
||
|
||
if ( NULL != lpFormat )
|
||
{
|
||
if ( LoadString( g_hOemInstance, // handle to resource module
|
||
uID, // resource identifier
|
||
lpFormat, // resource buffer
|
||
NOTIFYFORMATBUFFERSIZE-1 ) // size of buffer
|
||
== 0 )
|
||
{
|
||
hr = HrFromLastWin32Error();
|
||
}
|
||
else
|
||
{
|
||
if ( NULL != lpczwValue )
|
||
{
|
||
LPWSTR lpBuffer = new WCHAR[ HNWCALLBACKBUFFERSIZE ];
|
||
|
||
if ( NULL != lpBuffer )
|
||
{
|
||
_snwprintf( lpBuffer, HNWCALLBACKBUFFERSIZE-1, lpFormat, lpczwValue );
|
||
|
||
(*lpHnwCallback)( lpBuffer, lpContext );
|
||
|
||
delete [] lpBuffer;
|
||
}
|
||
else
|
||
{
|
||
(*lpHnwCallback)( lpFormat, lpContext );
|
||
|
||
hr = E_OUTOFMEMORY;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
(*lpHnwCallback)( lpFormat, lpContext );
|
||
}
|
||
}
|
||
|
||
delete [] lpFormat;
|
||
}
|
||
else
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
}
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
UpdateHnwLog(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
IN UINT uID,
|
||
IN DWORD dwValue
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
WCHAR pzwValue[ 32 ];
|
||
|
||
_snwprintf( pzwValue, 32, L"%lx", dwValue );
|
||
|
||
return UpdateHnwLog( lpHnwCallback, lpContext, uID, pzwValue );
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
UpdateHnwLog(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
IN UINT uID,
|
||
IN int iValue
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
WCHAR pzwValue[ 32 ];
|
||
|
||
_snwprintf( pzwValue, 32, L"%x", iValue );
|
||
|
||
return UpdateHnwLog( lpHnwCallback, lpContext, uID, pzwValue );
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
UpdateHnwLog(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
IN UINT uID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
return UpdateHnwLog( lpHnwCallback, lpContext, uID, NULL );
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
UpdateHnwLog(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
IN UINT uID,
|
||
IN LPCSTR lpczValue
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = E_FAIL;
|
||
int iChars = 0;
|
||
|
||
iChars = MultiByteToWideChar( CP_THREAD_ACP, 0, lpczValue, -1, NULL, 0 );
|
||
|
||
if ( 0 != iChars )
|
||
{
|
||
LPWSTR lpWideStr = new WCHAR[ iChars + 1 ];
|
||
|
||
if ( NULL != lpWideStr )
|
||
{
|
||
if ( !MultiByteToWideChar( CP_THREAD_ACP, 0, lpczValue, -1, lpWideStr, iChars ) )
|
||
{
|
||
hr = UpdateHnwLog( lpHnwCallback, lpContext, uID, lpWideStr );
|
||
}
|
||
else
|
||
{
|
||
hr = HrFromLastWin32Error();
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hr = HrFromLastWin32Error();
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
CheckNetCfgWriteLock(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr;
|
||
INetCfg *pnetcfg = NULL;
|
||
|
||
TRACE_ENTER("CheckNetCfgWriteLock");
|
||
|
||
hr = CoCreateInstance( CLSID_CNetCfg, NULL, CLSCTX_SERVER, IID_PPV_ARG(INetCfg, &pnetcfg ) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
INetCfgLock *pncfglock = NULL;
|
||
|
||
// Get the lock interface
|
||
|
||
hr = pnetcfg->QueryInterface( IID_PPV_ARG(INetCfgLock, &pncfglock) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// Get the NetCfg lock
|
||
|
||
hr = pncfglock->AcquireWriteLock( 5, L"HNetCfg", NULL );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
pncfglock->ReleaseWriteLock();
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
pncfglock->Release();
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
pnetcfg->Release();
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
TRACE_LEAVE("CheckNetCfgWriteLock", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
ArpForConflictingDhcpAddress(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr = S_OK;
|
||
WSADATA wsaData;
|
||
int iWsaErr;
|
||
|
||
TRACE_ENTER("ArpForConflictingDhcpAddress");
|
||
|
||
iWsaErr = WSAStartup( 0x202, &wsaData );
|
||
|
||
if ( 0 != iWsaErr )
|
||
{
|
||
hr = MAKE_HRESULT( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
|
||
}
|
||
else
|
||
{
|
||
// Obtain required ICS server address
|
||
|
||
ULONG TargetAddress, TargetMask;
|
||
|
||
hr = ReadDhcpScopeSettings( &TargetAddress, &TargetMask );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// Retrieve the best interface for the target IP address,
|
||
// and also perform a UDP-connect to determine the 'closest'
|
||
// local IP address to the target IP address.
|
||
|
||
ULONG InterfaceIndex;
|
||
|
||
if ( GetBestInterface( TargetAddress, &InterfaceIndex ) != NO_ERROR )
|
||
{
|
||
int Length;
|
||
SOCKADDR_IN SockAddrIn;
|
||
SOCKET Socket;
|
||
|
||
SockAddrIn.sin_family = AF_INET;
|
||
SockAddrIn.sin_port = 0;
|
||
SockAddrIn.sin_addr.s_addr = TargetAddress;
|
||
|
||
Socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||
|
||
if ( INVALID_SOCKET != Socket )
|
||
{
|
||
iWsaErr = connect( Socket, (PSOCKADDR)&SockAddrIn, sizeof(SockAddrIn) );
|
||
|
||
if ( NO_ERROR == iWsaErr )
|
||
{
|
||
iWsaErr = getsockname( Socket, ( PSOCKADDR)&SockAddrIn, &Length );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
iWsaErr = SOCKET_ERROR;
|
||
}
|
||
|
||
if ( NO_ERROR != iWsaErr )
|
||
{
|
||
hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, iWsaErr );
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_WSAERRORDURINGDETECTION, iWsaErr );
|
||
}
|
||
else
|
||
{
|
||
// Make sure the target IP address isn't already cached,
|
||
// by removing it from the ARP cache if present using the interface index
|
||
// determined above.
|
||
|
||
MIB_IPNETROW IpNetRow;
|
||
DWORD dwError;
|
||
CHAR HardwareAddress[6];
|
||
ULONG HardwareAddressLength;
|
||
ULONG SourceAddress;
|
||
|
||
SourceAddress = SockAddrIn.sin_addr.s_addr;
|
||
|
||
ZeroMemory( &IpNetRow, sizeof(IpNetRow) );
|
||
IpNetRow.dwIndex = InterfaceIndex;
|
||
IpNetRow.dwPhysAddrLen = 6;
|
||
IpNetRow.dwAddr = TargetAddress;
|
||
IpNetRow.dwType = MIB_IPNET_TYPE_INVALID;
|
||
|
||
DeleteIpNetEntry( &IpNetRow );
|
||
|
||
dwError = SendARP( TargetAddress, // destination IP address
|
||
SourceAddress, // IP address of sender
|
||
(PULONG)HardwareAddress, // returned physical address
|
||
&HardwareAddressLength // length of returned physical addr.
|
||
);
|
||
|
||
if ( NO_ERROR == dwError )
|
||
{
|
||
TargetAddress = inet_addr( HardwareAddress );
|
||
|
||
if ( TargetAddress != SourceAddress )
|
||
{
|
||
hr = E_ICSADDRESSCONFLICT;
|
||
|
||
UpdateHnwLog( lpHnwCallback,
|
||
lpContext,
|
||
IDS_ICSADDRESSCONFLICTDETECTED,
|
||
HardwareAddress );
|
||
}
|
||
else
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hr = MAKE_SCODE( SEVERITY_ERROR, FACILITY_INTERNET, dwError );
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_SENDARPERRORDURINGDETECTION, dwError );
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
TRACE_LEAVE("ArpForConflictingDhcpAddress", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
ObtainIcsErrorConditions(
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("ObtainIcsErrorConditions");
|
||
|
||
hr = ArpForConflictingDhcpAddress( lpHnwCallback, lpContext );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = CheckNetCfgWriteLock( lpHnwCallback, lpContext );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// Create Homenet Configuration Manager COM Instance
|
||
|
||
IHNetCfgMgr* pCfgMgr;
|
||
|
||
hr = CoCreateInstance( CLSID_HNetCfgMgr,
|
||
NULL,
|
||
CLSCTX_INPROC_SERVER,
|
||
IID_PPV_ARG(IHNetCfgMgr, &pCfgMgr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
pCfgMgr->Release();
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
|
||
}
|
||
}
|
||
}
|
||
|
||
TRACE_LEAVE("ObtainIcsErrorConditions", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT
|
||
HRGetConnectionAdapterName(
|
||
INetConnection *pNetConnection,
|
||
LPWSTR *ppzwAdapterName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("HRGetConnectionAdapterName");
|
||
|
||
if ( NULL == pNetConnection )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else if ( NULL == ppzwAdapterName )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else
|
||
{
|
||
NETCON_PROPERTIES* pProps;
|
||
|
||
*ppzwAdapterName = NULL;
|
||
|
||
hr = pNetConnection->GetProperties(&pProps);
|
||
|
||
if ( SUCCEEDED( hr ) )
|
||
{
|
||
*ppzwAdapterName = new WCHAR[ wcslen( pProps->pszwDeviceName ) + 1 ];
|
||
|
||
if ( NULL != *ppzwAdapterName )
|
||
{
|
||
wcscpy( *ppzwAdapterName, pProps->pszwDeviceName );
|
||
|
||
debugprintf( _T("\t"), *ppzwAdapterName );
|
||
}
|
||
else
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
}
|
||
|
||
NcFreeNetconProperties( pProps );
|
||
}
|
||
}
|
||
|
||
TRACE_LEAVE("HRGetConnectionAdapterName", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
GetIcsPublicConnection(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
OUT INetConnection **ppNetPublicConnection,
|
||
OUT BOOLEAN *pbSharePublicConnection OPTIONAL,
|
||
OUT BOOLEAN *pbFirewallPublicConnection OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("GetIcsPublicConnection");
|
||
|
||
CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != ppNetPublicConnection );
|
||
|
||
if ( NULL == ppNetPublicConnection )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
|
||
*ppNetPublicConnection = NULL;
|
||
}
|
||
else
|
||
{
|
||
// initialize arguments
|
||
|
||
*ppNetPublicConnection = NULL;
|
||
|
||
if ( NULL != pbSharePublicConnection )
|
||
*pbSharePublicConnection = FALSE;
|
||
|
||
if ( NULL != pbFirewallPublicConnection )
|
||
*pbFirewallPublicConnection = FALSE;
|
||
|
||
// Obtain interface pointer
|
||
|
||
hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
CComPtr<IEnumHNetIcsPublicConnections> spehiPublic;
|
||
|
||
if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &spehiPublic ) ) == S_OK )
|
||
{
|
||
CComPtr<IHNetIcsPublicConnection> spIHNetIcsPublic;
|
||
|
||
// obtain only the first IHNetIcsPublicConnetion
|
||
|
||
if ( ( hr = spehiPublic->Next( 1, &spIHNetIcsPublic, NULL ) ) == S_OK )
|
||
{
|
||
// obtain pointer to IID_IHNetConnection interface of object
|
||
|
||
CComPtr<IHNetConnection> spIHNetPublic;
|
||
|
||
hr = spIHNetIcsPublic->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPublic ) );
|
||
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// The reference count will be decremented by the caller
|
||
// if necessary. Notice we are using the caller's pointer
|
||
// variable.
|
||
|
||
hr = spIHNetPublic->GetINetConnection( ppNetPublicConnection );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
HNET_CONN_PROPERTIES *phncProperties;
|
||
|
||
hr = spIHNetPublic->GetProperties( &phncProperties );
|
||
|
||
if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
|
||
{
|
||
if ( NULL != pbSharePublicConnection )
|
||
*pbSharePublicConnection = phncProperties->fIcsPublic;
|
||
|
||
if ( NULL != pbFirewallPublicConnection )
|
||
*pbFirewallPublicConnection = phncProperties->fFirewalled;
|
||
|
||
CoTaskMemFree( phncProperties );
|
||
|
||
} //if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
(*ppNetPublicConnection)->Release();
|
||
|
||
*ppNetPublicConnection = NULL;
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
} // if ( ( hr = pehiPublic->Next( 1, &sphicPublic, NULL ) ) == S_OK )
|
||
|
||
} // if ( ( hr = pIHNetCfgMgr->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
|
||
}
|
||
|
||
TRACE_LEAVE("GetIcsPublicConnection", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
GetIcsPrivateConnections(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
OUT INetConnection ***ppNetPrivateConnection
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Obtain the private connections enumerator and loop
|
||
through enumeration twice. Set the required array
|
||
length during the first enumeration. If the parameter
|
||
array is big enough initialize it during the second
|
||
enumeration.
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
ULONG ulArrayLength, ulListLength, uIndex;
|
||
BOOLEAN bBufferAllocated;
|
||
|
||
CComPtr<IHNetIcsSettings> spIHNetIcsSettings;
|
||
IHNetIcsPrivateConnection *pIHNetIcsPrivate;
|
||
IHNetIcsPrivateConnection **ppIHNetIPList;
|
||
CComPtr<IEnumHNetIcsPrivateConnections> spehiPrivate;
|
||
|
||
TRACE_ENTER("GetIcsPrivateConnections");
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != ppNetPrivateConnection );
|
||
|
||
if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( NULL == ppNetPrivateConnection )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else
|
||
{
|
||
// initialize local vars
|
||
|
||
ulArrayLength = 0L;
|
||
ulListLength = 0L;
|
||
bBufferAllocated = FALSE;
|
||
|
||
// Obtain interface pointer
|
||
|
||
hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetIcsSettings, &spIHNetIcsSettings ) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
|
||
} // else
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
|
||
{
|
||
while ( spehiPrivate->Next( 1, &pIHNetIcsPrivate, NULL ) == S_OK )
|
||
{
|
||
ulArrayLength++;
|
||
pIHNetIcsPrivate->Release();
|
||
}
|
||
|
||
// releasing the enumeration interface now so we can re-initialize it later
|
||
|
||
spehiPrivate = NULL;
|
||
|
||
} // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
if ( ( hr = spIHNetIcsSettings->EnumIcsPrivateConnections( &spehiPrivate ) ) == S_OK )
|
||
{
|
||
hr = spehiPrivate->Next( ulArrayLength, &pIHNetIcsPrivate, &ulListLength );
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
// Allocate array of INetConnection pointers. There will
|
||
// be on extra pointer element for the NULL pointer at the
|
||
// end of the array. We allocate this buffer with
|
||
// NetApiBufferAllocate so the buffer must be released using
|
||
// NetApiBufferFree.
|
||
|
||
NET_API_STATUS nErr;
|
||
LPVOID lpvBuffer;
|
||
|
||
++ulArrayLength;
|
||
|
||
nErr = NetApiBufferAllocate( ulArrayLength * sizeof(INetConnection *),
|
||
(LPVOID *)ppNetPrivateConnection );
|
||
|
||
if ( NERR_Success == nErr )
|
||
{
|
||
bBufferAllocated = TRUE;
|
||
|
||
for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
|
||
{
|
||
(*ppNetPrivateConnection)[uIndex] = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
|
||
// must release IHNetIcsPrivateConnection instances
|
||
|
||
ppIHNetIPList = &pIHNetIcsPrivate;
|
||
|
||
for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
|
||
{
|
||
ppIHNetIPList[uIndex]->Release();
|
||
}
|
||
}
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
// done with enumeration interface pointer so we explicitly release it
|
||
|
||
spehiPrivate = NULL;
|
||
|
||
} // if ( ( hr = spIHNetIcsSettings->EnumIcsPublicConnections( &pehiPublic ) ) == S_OK )
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
ppIHNetIPList = &pIHNetIcsPrivate;
|
||
|
||
for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
|
||
{
|
||
if ( uIndex < ulArrayLength - 1 )
|
||
{
|
||
CComPtr<IHNetConnection> spIHNetPrivate;
|
||
|
||
hr = ppIHNetIPList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
|
||
|
||
hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
}
|
||
|
||
} // if ( uIndex < uiArrayLength - 1 )
|
||
|
||
ppIHNetIPList[uIndex]->Release();
|
||
|
||
} // for ( uIndex = 0L; ...
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
if ( !SUCCEEDED(hr) )
|
||
{
|
||
// If we fail after allocating the buffer then we need release
|
||
// references and buffer
|
||
|
||
if ( bBufferAllocated )
|
||
{
|
||
for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
|
||
{
|
||
if ( NULL != (*ppNetPrivateConnection)[uIndex] )
|
||
{
|
||
(*ppNetPrivateConnection)[uIndex]->Release();
|
||
}
|
||
}
|
||
|
||
NetApiBufferFree( *ppNetPrivateConnection );
|
||
}
|
||
}
|
||
|
||
TRACE_LEAVE("GetIcsPrivateConnections", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
GetBridge(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
OUT IHNetBridge **ppBridge
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Obtain the bridge enumerator and loop through enumeration.
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
|
||
TRACE_ENTER("GetBridge");
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != ppBridge );
|
||
|
||
if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( NULL == ppBridge )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else
|
||
{
|
||
CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
|
||
|
||
hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
CComPtr<IEnumHNetBridges> spBridgeEnum;
|
||
|
||
hr = spIHNetBridgeSettings->EnumBridges( &spBridgeEnum );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = spBridgeEnum->Next( 1, ppBridge, NULL );
|
||
|
||
if ( S_FALSE == hr )
|
||
{
|
||
hr = E_FAIL;
|
||
}
|
||
|
||
// We allow the caller to invoke Release for *ppBridge
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
} // else
|
||
|
||
TRACE_LEAVE("GetBridge", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
GetBridgedConnections(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
OUT INetConnection ***ppNetPrivateConnection
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Obtain the bridge connections enumerator and loop
|
||
through enumeration twice. Set the required array
|
||
length during the first enumeration. If the parameter
|
||
array is big enough initialize it during the second
|
||
enumeration.
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
ULONG ulArrayLength, ulListLength, uIndex;
|
||
|
||
CComPtr<IHNetBridge> spBridge;
|
||
CComPtr<IEnumHNetBridgedConnections> spEnum;
|
||
IHNetBridgedConnection *pIHNetBridged;
|
||
IHNetBridgedConnection **ppIHNetBridgeList;
|
||
|
||
TRACE_ENTER("GetBridgedConnections");
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != ppNetPrivateConnection );
|
||
|
||
if ( NULL == ppNetPrivateConnection )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
|
||
*ppNetPrivateConnection = NULL;
|
||
}
|
||
else
|
||
{
|
||
// initialize arguments
|
||
|
||
*ppNetPrivateConnection = NULL;
|
||
ulArrayLength = 0L;
|
||
ulListLength = 0L;
|
||
|
||
// Obtain bridge interface pointer
|
||
|
||
hr = GetBridge( spIHNetCfgMgr, &spBridge );
|
||
|
||
} // else
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
|
||
{
|
||
while ( spEnum->Next( 1, &pIHNetBridged, NULL ) == S_OK )
|
||
{
|
||
ulArrayLength++;
|
||
pIHNetBridged->Release();
|
||
}
|
||
|
||
// releasing the enumeration interface instance so we can re-initialize it later
|
||
|
||
spEnum = NULL;
|
||
|
||
} // if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
if ( ( hr = spBridge->EnumMembers( &spEnum ) ) == S_OK )
|
||
{
|
||
hr = spEnum->Next( ulArrayLength, &pIHNetBridged, &ulListLength );
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
// Allocate array of INetConnection pointers. There will
|
||
// be on extra pointer element for the NULL pointer at the
|
||
// end of the array. We allocate this buffer with
|
||
// NetApiBufferAllocate so the buffer must be released using
|
||
// NetApiBufferFree.
|
||
|
||
NET_API_STATUS nErr;
|
||
|
||
++ulArrayLength;
|
||
|
||
nErr = NetApiBufferAllocate( ulArrayLength*sizeof(INetConnection *),
|
||
(LPVOID *)ppNetPrivateConnection );
|
||
|
||
if ( NERR_Success == nErr )
|
||
{
|
||
for ( uIndex = 0L; uIndex < ulArrayLength; uIndex++ )
|
||
{
|
||
(*ppNetPrivateConnection)[uIndex] = NULL;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
|
||
// must release IHNetIcsPrivateConnection instances
|
||
|
||
ppIHNetBridgeList = &pIHNetBridged;
|
||
|
||
for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
|
||
{
|
||
ppIHNetBridgeList[uIndex]->Release();
|
||
}
|
||
|
||
} // else
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
// releasing enumeration interface instance
|
||
|
||
spEnum = NULL;
|
||
|
||
} // if ( ( hr = pBridge->EnumMembers( &spEnum ) ) == S_OK )
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
ppIHNetBridgeList = &pIHNetBridged;
|
||
|
||
for ( uIndex = 0L; uIndex < ulListLength; uIndex++ )
|
||
{
|
||
if ( uIndex < ulArrayLength - 1 )
|
||
{
|
||
CComPtr<IHNetConnection> spIHNetPrivate;
|
||
|
||
hr = ppIHNetBridgeList[uIndex]->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNetPrivate ) );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// We allow the caller to invoke Release for (*ppNetPrivateConnection)[uIndex]
|
||
|
||
hr = spIHNetPrivate->GetINetConnection( &((*ppNetPrivateConnection)[uIndex]) );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
}
|
||
|
||
} // if ( uIndex < uiArrayLength - 1 )
|
||
|
||
ppIHNetBridgeList[uIndex]->Release();
|
||
|
||
} // for ( uIndex = 0L; ...
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
TRACE_LEAVE("GetBridgedConnections", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
SetIcsPublicConnection(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
IN INetConnection *pNetPublicConnection,
|
||
IN BOOLEAN bSharePublicConnection,
|
||
IN BOOLEAN bFirewallPublicConnection,
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("SetIcsPublicConnection");
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != pNetPublicConnection );
|
||
|
||
if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( NULL == pNetPublicConnection )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else
|
||
{
|
||
INetConnectionRefresh* pNetConnectionRefresh;
|
||
|
||
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
_ASSERT( pNetConnectionRefresh );
|
||
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
OLECHAR *strAdapter = L"Adapter";
|
||
OLECHAR *strName = strAdapter;
|
||
|
||
CComPtr<IHNetConnection> spHNetConnection;
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
|
||
&spHNetConnection );
|
||
if ( S_OK == hr )
|
||
{
|
||
if ( HRGetConnectionAdapterName( pNetPublicConnection, &strName ) != S_OK )
|
||
{
|
||
strName = strAdapter;
|
||
}
|
||
|
||
if ( bSharePublicConnection )
|
||
{
|
||
CComPtr<IHNetIcsPublicConnection> spIcsPublicConn;
|
||
|
||
hr = spHNetConnection->SharePublic( &spIcsPublicConn );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// Instantiating the IHNetIcsPublicConnection pointer with
|
||
// SharePublic results in updating our WMI store with
|
||
// the new sharing properties for this connection. This
|
||
// is our only goal at this time.
|
||
|
||
//
|
||
// set the power scheme!
|
||
//
|
||
|
||
if (!SetActivePwrScheme(3, NULL, NULL)) {
|
||
debugprintf( _T("Unable to set power scheme to always on\n"), strName);
|
||
}
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONCREATED, strName );
|
||
|
||
spIcsPublicConn.Release();
|
||
|
||
debugprintf( _T("\t"), strName );
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPUBLICCONNECTIONFAILED, strName );
|
||
}
|
||
|
||
} // if ( bSharePublicConnection )
|
||
|
||
if ( SUCCEEDED(hr) && bFirewallPublicConnection )
|
||
{
|
||
CComPtr<IHNetFirewalledConnection> spFirewalledConn;
|
||
|
||
hr = spHNetConnection->Firewall( &spFirewalledConn );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// Instantiating the IHNetFirewalledConnection pointer with
|
||
// SharePublic results in updating our WMI store with
|
||
// the new firewall properties for this connection. This
|
||
// is our only goal at this time.
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTION, strName );
|
||
|
||
spFirewalledConn.Release();
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_FIREWALLCONNECTIONFAILED, strName );
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) && bFirewallPublicConnection )
|
||
|
||
} // if ( S_OK == hr )
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCFGFORADAPTERUNAVAIL, strName );
|
||
}
|
||
|
||
if ( strName != strAdapter )
|
||
{
|
||
delete strName;
|
||
}
|
||
|
||
pNetConnectionRefresh->DisableEvents( FALSE, 0L );
|
||
pNetConnectionRefresh->Release();
|
||
|
||
} // if( SUCCEEDED(hr) )
|
||
|
||
} // else
|
||
|
||
TRACE_LEAVE("SetIcsPublicConnection", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT WaitForConnectionToInitialize(
|
||
IN CComPtr<IHNetConnection> spIHNC,
|
||
IN ULONG ulSeconds,
|
||
IN BOOLEAN bIsBridge
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
GUID *pGuid;
|
||
UNICODE_STRING UnicodeString;
|
||
|
||
TRACE_ENTER("WaitForConnectionToInitialize");
|
||
|
||
ZeroMemory( &UnicodeString, sizeof(UnicodeString) );
|
||
|
||
hr = spIHNC->GetGuid( &pGuid );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
NTSTATUS Status = RtlStringFromGUID( *pGuid, &UnicodeString );
|
||
|
||
hr = ( STATUS_SUCCESS == Status ) ? S_OK : E_FAIL;
|
||
|
||
CoTaskMemFree( pGuid );
|
||
}
|
||
|
||
pGuid = NULL;
|
||
|
||
#ifdef WAIT_FOR_MEDIA_STATUS_CONNECTED
|
||
|
||
if ( SUCCEEDED(hr) && bIsBridge )
|
||
{
|
||
// Query the state of the connection. Try to wait for the
|
||
// bridge to build the spanning tree and report media state connected.
|
||
|
||
LPWSTR pwsz;
|
||
|
||
// Build a buffer large enough for the device string
|
||
|
||
pwsz = new WCHAR[ sizeof(c_wszDevice)/sizeof(WCHAR) + UnicodeString.Length/sizeof(WCHAR) + 1 ];
|
||
|
||
if ( NULL != pwsz )
|
||
{
|
||
UNICODE_STRING DeviceString;
|
||
NIC_STATISTICS NdisStatistics;
|
||
ULONG ulTimeout;
|
||
|
||
swprintf( pwsz, L"%s%s", c_wszDevice, UnicodeString.Buffer );
|
||
|
||
ulTimeout = SECONDS_TO_WAIT_FOR_BRIDGE;
|
||
RtlInitUnicodeString( &DeviceString, pwsz );
|
||
|
||
do
|
||
{
|
||
ZeroMemory( &NdisStatistics, sizeof(NdisStatistics) );
|
||
NdisStatistics.Size = sizeof(NdisStatistics);
|
||
NdisQueryStatistics( &DeviceString, &NdisStatistics );
|
||
|
||
if ( NdisStatistics.MediaState == MEDIA_STATE_UNKNOWN )
|
||
{
|
||
hr = HRESULT_FROM_WIN32(ERROR_SHARING_HOST_ADDRESS_CONFLICT);
|
||
}
|
||
else if ( NdisStatistics.DeviceState != DEVICE_STATE_CONNECTED ||
|
||
NdisStatistics.MediaState != MEDIA_STATE_CONNECTED )
|
||
{
|
||
hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
|
||
}
|
||
else
|
||
{
|
||
// AHA! Bridge initialized!
|
||
|
||
hr = S_OK;
|
||
break;
|
||
}
|
||
|
||
debugretprintf( pwsz, hr );
|
||
|
||
Sleep( 1000 );
|
||
}
|
||
while ( ulTimeout-- );
|
||
|
||
delete [] pwsz;
|
||
|
||
} // if ( NULL != pwsz )
|
||
|
||
} // if ( SUCCEEDED(hr) && bIsBridge )
|
||
|
||
#endif
|
||
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
DWORD dwResult;
|
||
DWORD dwVersion; // version of the DHCP Client Options API reported
|
||
|
||
hr = HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN);
|
||
dwResult = DhcpCApiInitialize( &dwVersion );
|
||
|
||
if ( ERROR_SUCCESS == dwResult )
|
||
{
|
||
DHCPCAPI_PARAMS requests[1] = { {0, OPTION_SUBNET_MASK, FALSE, NULL, 0} }; // subnet mask
|
||
DHCPCAPI_PARAMS_ARRAY sendarray = { 0, NULL }; // we aren't sending anything
|
||
DHCPCAPI_PARAMS_ARRAY requestarray = { 1, requests }; // we are requesting 2 items
|
||
|
||
while ( --ulSeconds )
|
||
{
|
||
DWORD dwSize = INITIAL_BUFFER_SIZE; // size of buffer for options
|
||
LPBYTE buffer = NULL; // buffer for options
|
||
IN_ADDR addr; // address in return code
|
||
|
||
do
|
||
{
|
||
if ( NULL != buffer )
|
||
{
|
||
LocalFree( buffer );
|
||
}
|
||
|
||
buffer = (LPBYTE) LocalAlloc( LPTR, dwSize ); // allocate the buffer
|
||
|
||
if ( NULL == buffer )
|
||
{
|
||
break;
|
||
}
|
||
|
||
// make the request on the adapter
|
||
|
||
dwResult = DhcpRequestParams( DHCPCAPI_REQUEST_SYNCHRONOUS,
|
||
NULL,
|
||
UnicodeString.Buffer,
|
||
NULL,
|
||
sendarray,
|
||
requestarray,
|
||
buffer,
|
||
&dwSize,
|
||
NULL );
|
||
}
|
||
while ( ERROR_MORE_DATA == dwResult );
|
||
|
||
if ( NULL != buffer )
|
||
{
|
||
LocalFree( buffer );
|
||
}
|
||
|
||
if ( ERROR_SUCCESS == dwResult )
|
||
{
|
||
hr = S_OK;
|
||
break;
|
||
}
|
||
|
||
// wait for dhcp to pick up connection
|
||
|
||
debugretprintf( UnicodeString.Buffer, hr );
|
||
|
||
Sleep( 1000 );
|
||
|
||
} // while ( --ulSeconds )
|
||
|
||
DhcpCApiCleanup();
|
||
|
||
} // if ( 0 == dwResult )
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
RtlFreeUnicodeString( &UnicodeString );
|
||
|
||
TRACE_LEAVE("WaitForConnectionToInitialize", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
SetIcsPrivateConnections(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
IN INetConnection *pNetPrivateConnection[],
|
||
IN BOOLEAN bSharePublicConnection,
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
OUT INetConnection **pNetPrivateInterface
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("SetIcsPrivateConnections");
|
||
|
||
CComPtr<IHNetBridgeSettings> spIHNetBridgeSettings;
|
||
INetConnectionRefresh* pNetConnectionRefresh = NULL;
|
||
|
||
_ASSERT( spIHNetCfgMgr != NULL );
|
||
_ASSERT( NULL != pNetPrivateConnection );
|
||
|
||
if ( spIHNetCfgMgr == NULL )
|
||
{
|
||
hr = E_POINTER;
|
||
}
|
||
else if ( NULL == pNetPrivateConnection )
|
||
{
|
||
hr = E_INVALIDARG;
|
||
}
|
||
else
|
||
{
|
||
hr = spIHNetCfgMgr->QueryInterface( IID_PPV_ARG( IHNetBridgeSettings, &spIHNetBridgeSettings ) );
|
||
}
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
|
||
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
_ASSERT( pNetConnectionRefresh );
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
}
|
||
else
|
||
{
|
||
pNetConnectionRefresh = NULL;
|
||
}
|
||
}
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
CComPtr<IHNetConnection> spIHNC;
|
||
INetConnection **ppNC;
|
||
ULONG uIndex;
|
||
BOOLEAN bIsBridge;
|
||
INetCfg *pnetcfg = NULL;
|
||
INetCfgLock *pncfglock = NULL;
|
||
|
||
ppNC = pNetPrivateConnection;
|
||
bIsBridge = FALSE;
|
||
|
||
for ( uIndex=0L; NULL != *ppNC; ppNC++ )
|
||
{
|
||
_ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
|
||
|
||
if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
|
||
{
|
||
hr = E_POINTER;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
#if DBG
|
||
LPWSTR lpzwAdapterName;
|
||
HRESULT hrGetName;
|
||
|
||
hrGetName = HRGetConnectionAdapterName( *ppNC, &lpzwAdapterName );
|
||
|
||
if ( SUCCEEDED( hrGetName ) )
|
||
{
|
||
debugprintf( _T("\t"), lpzwAdapterName );
|
||
|
||
delete lpzwAdapterName;
|
||
}
|
||
#endif
|
||
// We only count this as a valid connection for valid pointers
|
||
|
||
uIndex++;
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
HRESULT hrWrite;
|
||
|
||
hrWrite = InitializeNetCfgForWrite( &pnetcfg, &pncfglock );
|
||
|
||
if ( 1 < uIndex )
|
||
{
|
||
CComPtr<IHNetBridge> spHNetBridge;
|
||
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNetBridgeSettings->CreateBridge( &spHNetBridge, pnetcfg );
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
ULONG uCount;
|
||
|
||
ppNC = pNetPrivateConnection;
|
||
|
||
for ( uCount=0L; (NULL != *ppNC) && (uCount < uIndex); uCount++, ppNC++ )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC, &spIHNC );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
CComPtr<IHNetBridgedConnection> spBridgedConn;
|
||
|
||
hr = spHNetBridge->AddMember( spIHNC, &spBridgedConn, pnetcfg );
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
// Instantiating the IHNetBridgeConnection pointer with
|
||
// SharePublic results in updating our WMI store with
|
||
// the new bridge properties for this connection. This
|
||
// is our only goal at this time.
|
||
|
||
spBridgedConn.Release();
|
||
}
|
||
else
|
||
{
|
||
debugretprintf( _T("AddMember FAILED with "), hr );
|
||
}
|
||
|
||
// We no longer need this IHNetConnection reference
|
||
// so we NULL the smart pointer to release it.
|
||
|
||
spIHNC = NULL;
|
||
}
|
||
|
||
} // for ( uCount=0L; ...
|
||
|
||
hr = spHNetBridge->QueryInterface( IID_PPV_ARG( IHNetConnection, &spIHNC ) );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
bIsBridge = TRUE;
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGECREATED );
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWBRIDGEFAILED );
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
} // if ( 1 < uIndex )
|
||
|
||
else if ( 1 == uIndex )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPrivateConnection[0], &spIHNC );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
}
|
||
else
|
||
{
|
||
// We don't have ANY private connections so we null out
|
||
// this pointer to make sure we don't try to use it.
|
||
|
||
spIHNC = NULL;
|
||
}
|
||
|
||
if ( SUCCEEDED(hrWrite) )
|
||
{
|
||
UninitializeNetCfgForWrite( pnetcfg, pncfglock );
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
else
|
||
{
|
||
// Some previous error condition occurred and we need to
|
||
// null out this pointer to make sure we don't try to use it.
|
||
|
||
spIHNC = NULL;
|
||
}
|
||
|
||
|
||
if ( bSharePublicConnection && SUCCEEDED(hr) && ( spIHNC != NULL ) )
|
||
{
|
||
OLECHAR *strAdapter = _T("Adapter");
|
||
OLECHAR *strName = strAdapter;
|
||
|
||
CComPtr<IHNetIcsPrivateConnection> spIcsPrivateConn;
|
||
|
||
// Get name of private connection candidate
|
||
|
||
if ( spIHNC != NULL )
|
||
{
|
||
if ( S_OK != spIHNC->GetName( &strName ) )
|
||
{
|
||
strName = strAdapter;
|
||
}
|
||
}
|
||
|
||
// Wait for connection to finish initialization and share it
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// if we are in ICS Upgrade, don't wait for dhcp
|
||
// service because it won't be running during GUI Mode Setup.
|
||
|
||
HANDLE hIcsUpgradeEvent = OpenEvent( EVENT_MODIFY_STATE, FALSE, c_wszIcsUpgradeEventName );
|
||
|
||
if ( NULL != hIcsUpgradeEvent )
|
||
{
|
||
CloseHandle( hIcsUpgradeEvent );
|
||
}
|
||
else
|
||
{
|
||
// We are running normally with dhcp so we must wait
|
||
// for dhcp to pick up the new bridge interface
|
||
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = WaitForConnectionToInitialize( spIHNC, SECONDS_TO_WAIT_FOR_DHCP, bIsBridge );
|
||
|
||
if ( HRESULT_FROM_WIN32(ERROR_SHARING_NO_PRIVATE_LAN) == hr )
|
||
{
|
||
// If WaitForConnectionToInitialize can't get statistics then try
|
||
// SharePrivate anyway.
|
||
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNC->SharePrivate( &spIcsPrivateConn );
|
||
}
|
||
}
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
// We are only configuring the connection
|
||
|
||
// Instantiating the IHNetIcsPrivateConnection pointer with
|
||
// SharePublic results in updating our WMI store with
|
||
// the new private connection properties for this connection.
|
||
|
||
// Obtain Interface pointer to private connection if requested
|
||
|
||
if ( NULL != pNetPrivateInterface )
|
||
{
|
||
spIHNC->GetINetConnection( pNetPrivateInterface );
|
||
}
|
||
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONCREATED, strName );
|
||
|
||
spIcsPrivateConn.Release();
|
||
|
||
debugprintf( _T("SharePrivate: "), strName );
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_NEWPRIVATECONNECTIONFAILED, strName );
|
||
|
||
debugretprintf( _T("SharePrivate FAILED with "), hr );
|
||
}
|
||
|
||
if ( strName != strAdapter )
|
||
{
|
||
CoTaskMemFree( strName );
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) && ( spIHNC != NULL ) )
|
||
|
||
// We no longer need this IHNetConnection reference so we NULL the smart
|
||
// pointer to release it. If the smart pointer is all ready NULL then
|
||
// no release or AV will occur. We do this here because the smart pointer
|
||
// may be valid even though we did not enter the preceeding block.
|
||
|
||
spIHNC = NULL;
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
|
||
if ( pNetConnectionRefresh )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( FALSE, 0L );
|
||
pNetConnectionRefresh->Release();
|
||
}
|
||
|
||
TRACE_LEAVE("SetIcsPrivateConnections", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
HRESULT
|
||
DisableEverything(
|
||
IN CComPtr<IHNetCfgMgr> spIHNetCfgMgr,
|
||
IN INetConnection *pNetPublicConnection,
|
||
IN INetConnection *pNetPrivateConnection[],
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
INetConnectionRefresh* pNetConnectionRefresh;
|
||
|
||
TRACE_ENTER("DisableEverything");
|
||
|
||
hr = CoCreateInstance(CLSID_ConnectionManager, NULL, CLSCTX_SERVER, IID_INetConnectionRefresh, reinterpret_cast<void**>(&pNetConnectionRefresh));
|
||
|
||
if( SUCCEEDED(hr) )
|
||
{
|
||
ULONG ulConnections;
|
||
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
if ( pNetPublicConnection )
|
||
{
|
||
IHNetConnection* pHNetPublicConnection;
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( pNetPublicConnection,
|
||
&pHNetPublicConnection );
|
||
if ( S_OK == hr )
|
||
{
|
||
IHNetFirewalledConnection* pPublicConnectionFirewall;
|
||
|
||
hr = pHNetPublicConnection->GetControlInterface( IID_IHNetFirewalledConnection,
|
||
(void**)&pPublicConnectionFirewall );
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
hr = pPublicConnectionFirewall->Unfirewall();
|
||
pPublicConnectionFirewall->Release();
|
||
pPublicConnectionFirewall = NULL;
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
|
||
}
|
||
}
|
||
|
||
pHNetPublicConnection->Release();
|
||
pHNetPublicConnection = NULL;
|
||
}
|
||
}
|
||
|
||
if ( pNetPrivateConnection && pNetPrivateConnection[0] )
|
||
{
|
||
INetConnection** ppNC = pNetPrivateConnection;
|
||
|
||
while ( *ppNC )
|
||
{
|
||
IHNetConnection* pHNetPrivateConnection;
|
||
|
||
_ASSERT( !IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) );
|
||
|
||
if ( IsBadReadPtr( *ppNC, sizeof( *ppNC ) ) )
|
||
{
|
||
hr = E_POINTER;
|
||
break;
|
||
}
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( *ppNC,
|
||
&pHNetPrivateConnection );
|
||
if ( S_OK == hr )
|
||
{
|
||
IHNetFirewalledConnection* pPrivateConnectionFirewall;
|
||
|
||
hr = pHNetPrivateConnection->GetControlInterface( IID_IHNetFirewalledConnection,
|
||
(void**)&pPrivateConnectionFirewall );
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = pPrivateConnectionFirewall->Unfirewall();
|
||
pPrivateConnectionFirewall->Release();
|
||
pPrivateConnectionFirewall = NULL;
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEFIREWALLFAIL, hr );
|
||
}
|
||
}
|
||
|
||
pHNetPrivateConnection->Release();
|
||
pHNetPrivateConnection = NULL;
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
ppNC++;
|
||
|
||
} // while ( ppNC )
|
||
|
||
} // if ( pNetPrivateConnection && pNetPrivateConnection[0] )
|
||
|
||
{
|
||
CComQIPtr<IHNetBridgeSettings> spIHNetBridge = spIHNetCfgMgr;
|
||
|
||
if ( spIHNetBridge != NULL )
|
||
{
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNetBridge->DestroyAllBridges( &ulConnections );
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_DESTROYBRIDGEFAIL, hr );
|
||
}
|
||
}
|
||
}
|
||
|
||
{
|
||
CComQIPtr<IHNetIcsSettings> spIHNetIcs = spIHNetCfgMgr;
|
||
|
||
if ( spIHNetIcs != NULL )
|
||
{
|
||
ULONG ulPrivateConnections;
|
||
|
||
pNetConnectionRefresh->DisableEvents( TRUE, MAX_DISABLE_EVENT_TIMEOUT );
|
||
|
||
hr = spIHNetIcs->DisableIcs( &ulConnections, &ulPrivateConnections );
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_DISABLEICS, hr );
|
||
}
|
||
}
|
||
}
|
||
|
||
pNetConnectionRefresh->DisableEvents( FALSE, 0L );
|
||
pNetConnectionRefresh->Release();
|
||
}
|
||
|
||
TRACE_LEAVE("DisableEverything", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
extern
|
||
HRESULT APIENTRY
|
||
HNetSetShareAndBridgeSettings(
|
||
IN INetConnection *pNetPublicConnection,
|
||
IN INetConnection *pNetPrivateConnection[],
|
||
IN BOOLEAN bSharePublicConnection,
|
||
IN BOOLEAN bFirewallPublicConnection,
|
||
IN LPHNWCALLBACK lpHnwCallback,
|
||
IN LPARAM lpContext,
|
||
OUT INetConnection **pNetPrivateInterface
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
TRACE_ENTER("HNetSetShareAndBridgeSettings");
|
||
|
||
HRESULT hr;
|
||
|
||
// Initialize returned interface pointer if necessary
|
||
|
||
if ( NULL != pNetPrivateInterface )
|
||
{
|
||
*pNetPrivateInterface = NULL;
|
||
}
|
||
|
||
// Create Homenet Configuration Manager COM Instance
|
||
// and obtain connection settings.
|
||
|
||
CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
|
||
|
||
hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
DisableEverything( spIHNetCfgMgr,
|
||
pNetPublicConnection,
|
||
pNetPrivateConnection,
|
||
lpHnwCallback,
|
||
lpContext );
|
||
|
||
if ( NULL != pNetPublicConnection )
|
||
{
|
||
hr = SetIcsPublicConnection( spIHNetCfgMgr,
|
||
pNetPublicConnection,
|
||
bSharePublicConnection,
|
||
bFirewallPublicConnection,
|
||
lpHnwCallback,
|
||
lpContext );
|
||
}
|
||
|
||
if ( ( NULL != pNetPrivateConnection ) && ( NULL != pNetPrivateConnection[0] ) && SUCCEEDED(hr) )
|
||
{
|
||
hr = SetIcsPrivateConnections( spIHNetCfgMgr,
|
||
pNetPrivateConnection,
|
||
bSharePublicConnection,
|
||
lpHnwCallback,
|
||
lpContext,
|
||
pNetPrivateInterface );
|
||
}
|
||
|
||
if ( FAILED(hr) )
|
||
{
|
||
DisableEverything( spIHNetCfgMgr,
|
||
pNetPublicConnection,
|
||
pNetPrivateConnection,
|
||
lpHnwCallback,
|
||
lpContext );
|
||
}
|
||
}
|
||
else
|
||
{
|
||
UpdateHnwLog( lpHnwCallback, lpContext, IDS_SHARINGCONFIGURATIONUNAVAIL );
|
||
}
|
||
|
||
TRACE_LEAVE("HNetSetShareAndBridgeSettings", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
extern
|
||
HRESULT APIENTRY
|
||
HNetGetShareAndBridgeSettings(
|
||
OUT INetConnection **ppNetPublicConnection,
|
||
OUT INetConnection ***ppNetPrivateConnection,
|
||
OUT BOOLEAN *pbSharePublicConnection,
|
||
OUT BOOLEAN *pbFirewallPublicConnection
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr;
|
||
|
||
TRACE_ENTER("HNetGetShareAndBridgeSettings");
|
||
|
||
// Create Homenet Configuration Manager COM Instance
|
||
// and obtain connection settings.
|
||
|
||
CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
|
||
|
||
*ppNetPublicConnection = NULL;
|
||
*ppNetPrivateConnection = NULL;
|
||
*pbSharePublicConnection = FALSE;
|
||
*pbFirewallPublicConnection = FALSE;
|
||
|
||
hr = spIHNetCfgMgr.CoCreateInstance( CLSID_HNetCfgMgr );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
if ( NULL != ppNetPublicConnection )
|
||
{
|
||
hr = GetIcsPublicConnection( spIHNetCfgMgr,
|
||
ppNetPublicConnection,
|
||
pbSharePublicConnection,
|
||
pbFirewallPublicConnection );
|
||
}
|
||
|
||
if ( NULL != ppNetPrivateConnection )
|
||
{
|
||
hr = GetIcsPrivateConnections( spIHNetCfgMgr, ppNetPrivateConnection );
|
||
|
||
if ( S_OK == hr )
|
||
{
|
||
CComPtr<IHNetConnection> spIHNetConnection;
|
||
INetConnection **ppINetCon;
|
||
|
||
// Check first private connection to see if it is the bridge
|
||
|
||
hr = spIHNetCfgMgr->GetIHNetConnectionForINetConnection( (*ppNetPrivateConnection)[0],
|
||
&spIHNetConnection );
|
||
_ASSERT( SUCCEEDED(hr) );
|
||
|
||
if ( SUCCEEDED(hr) )
|
||
{
|
||
HNET_CONN_PROPERTIES *phncProperties;
|
||
|
||
hr = spIHNetConnection->GetProperties( &phncProperties );
|
||
|
||
if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
|
||
{
|
||
if ( phncProperties->fBridge )
|
||
{
|
||
// If Bridge, then release the private connection instances
|
||
// and get the list of bridged connections
|
||
|
||
for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
|
||
{
|
||
(*ppINetCon)->Release();
|
||
*ppINetCon = NULL;
|
||
}
|
||
|
||
NetApiBufferFree( *ppNetPrivateConnection );
|
||
|
||
*ppNetPrivateConnection = NULL;
|
||
|
||
hr = GetBridgedConnections( spIHNetCfgMgr, ppNetPrivateConnection );
|
||
|
||
} // if ( phncProperties->fBridge )
|
||
|
||
CoTaskMemFree( phncProperties );
|
||
|
||
} // if ( SUCCEEDED(hr) && ( NULL != phncProperties ) )
|
||
|
||
} // if ( SUCCEEDED(hr)
|
||
|
||
// What if we fail along this path? Then we need to release
|
||
// any private connection interface pointer held.
|
||
|
||
if ( FAILED(hr) && ( NULL != ppNetPrivateConnection ) )
|
||
{
|
||
for ( ppINetCon = *ppNetPrivateConnection; NULL != *ppINetCon; ppINetCon++ )
|
||
{
|
||
(*ppINetCon)->Release();
|
||
}
|
||
|
||
NetApiBufferFree( *ppNetPrivateConnection );
|
||
|
||
*ppNetPrivateConnection = NULL;
|
||
}
|
||
|
||
} // if ( S_OK == hr )
|
||
|
||
} // if ( NULL != ppNetPrivateConnection )
|
||
|
||
// If we fail along the way then we need to release the public interface
|
||
// and NULL the pointer so that it won't be used.
|
||
|
||
if ( FAILED(hr) && ( NULL != ppNetPublicConnection ) )
|
||
{
|
||
(*ppNetPublicConnection)->Release();
|
||
|
||
*ppNetPublicConnection = NULL;
|
||
}
|
||
|
||
} // if ( SUCCEEDED(hr) )
|
||
|
||
TRACE_LEAVE("HNetGetShareAndBridgeSettings", hr);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
HRESULT DisablePersonalFirewallOnAll()
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Disable firewall on all connections
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr = S_OK;
|
||
CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
|
||
|
||
TRACE_ENTER("DisablePersonalFirewallOnAll");
|
||
|
||
hr = CoCreateInstance(CLSID_HNetCfgMgr,
|
||
NULL,
|
||
CLSCTX_ALL,
|
||
IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
CComQIPtr<IHNetFirewallSettings> spIHNetFirewall = spIHNetCfgMgr;
|
||
|
||
if ( NULL != spIHNetFirewall.p )
|
||
{
|
||
ULONG ulConnections = 0;
|
||
hr = spIHNetFirewall->DisableAllFirewalling( &ulConnections );
|
||
}
|
||
else
|
||
{
|
||
hr = E_FAIL;
|
||
}
|
||
}
|
||
|
||
|
||
TRACE_LEAVE("DisablePersonalFirewallOnAll", hr);
|
||
|
||
return hr;
|
||
|
||
}
|
||
|
||
HRESULT EnablePersonalFirewallOnAll()
|
||
/*++
|
||
|
||
Routine Description:
|
||
Enable firewall on all connections that can be firewalled
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
hResult
|
||
|
||
--*/
|
||
|
||
{
|
||
HRESULT hr = S_OK;
|
||
HRESULT hrTemp = S_OK;
|
||
ULONG ulCount = 0;
|
||
|
||
CComPtr<IEnumNetConnection> spEnum;
|
||
|
||
// Get the net connection manager
|
||
CComPtr<INetConnectionManager> spConnMan;
|
||
CComPtr<INetConnection> spConn;
|
||
|
||
// Create Homenet Configuration Manager COM Instance
|
||
// and obtain connection settings.
|
||
CComPtr<IHNetCfgMgr> spIHNetCfgMgr;
|
||
|
||
TRACE_ENTER("EnablePersonalFirewallOnAll");
|
||
|
||
hr = CoCreateInstance(CLSID_HNetCfgMgr,
|
||
NULL,
|
||
CLSCTX_ALL,
|
||
IID_PPV_ARG(IHNetCfgMgr, &spIHNetCfgMgr));
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
goto End;
|
||
}
|
||
|
||
//disable any previous firewall settings otherwise enabling
|
||
//firewall on the same connection twice will return errors
|
||
//We will continue do the enable firewall if this step fails
|
||
DisablePersonalFirewallOnAll();
|
||
|
||
hr = CoCreateInstance(CLSID_ConnectionManager,
|
||
NULL,
|
||
CLSCTX_ALL,
|
||
IID_PPV_ARG(INetConnectionManager, &spConnMan));
|
||
|
||
if (FAILED(hr))
|
||
{
|
||
goto End;
|
||
}
|
||
|
||
|
||
// Get the enumeration of connections
|
||
SetProxyBlanket(spConnMan);
|
||
|
||
hr = spConnMan->EnumConnections(NCME_DEFAULT, &spEnum);
|
||
if (FAILED(hr))
|
||
{
|
||
goto End;
|
||
}
|
||
|
||
SetProxyBlanket(spEnum);
|
||
|
||
|
||
hr = spEnum->Reset();
|
||
if (FAILED(hr))
|
||
{
|
||
goto End;
|
||
}
|
||
|
||
do
|
||
{
|
||
NETCON_PROPERTIES* pProps = NULL;
|
||
|
||
//release any previous ref count we hold
|
||
spConn = NULL;
|
||
|
||
hr = spEnum->Next(1, &spConn, &ulCount);
|
||
if (FAILED(hr) || 1 != ulCount)
|
||
{
|
||
break;
|
||
}
|
||
|
||
SetProxyBlanket(spConn);
|
||
|
||
hr = spConn->GetProperties(&pProps);
|
||
if (FAILED(hr) || NULL == pProps)
|
||
{
|
||
continue;
|
||
}
|
||
|
||
//ICF is available only for certain types of connections
|
||
if (NCM_PHONE == pProps->MediaType ||
|
||
NCM_ISDN == pProps->MediaType ||
|
||
NCM_PPPOE == pProps->MediaType ||
|
||
NCM_LAN == pProps->MediaType ||
|
||
NCM_TUNNEL == pProps->MediaType )
|
||
{
|
||
CComPtr<IHNetConnection> spHNetConnection;
|
||
//release the ref count if we are holding one
|
||
spHNetConnection = NULL;
|
||
hrTemp = spIHNetCfgMgr->GetIHNetConnectionForINetConnection(
|
||
spConn,
|
||
&spHNetConnection );
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = hrTemp;
|
||
}
|
||
|
||
if (SUCCEEDED(hrTemp))
|
||
{
|
||
//check whether the connect can be firewalled
|
||
HNET_CONN_PROPERTIES *phncProperties = NULL;
|
||
|
||
hrTemp = spHNetConnection->GetProperties( &phncProperties );
|
||
if (SUCCEEDED(hrTemp) && NULL != phncProperties)
|
||
{
|
||
if (phncProperties->fCanBeFirewalled)
|
||
{
|
||
CComPtr<IHNetFirewalledConnection> spFirewalledConn;
|
||
|
||
//turn on the firewall
|
||
hrTemp = spHNetConnection->Firewall( &spFirewalledConn );
|
||
}
|
||
CoTaskMemFree(phncProperties);
|
||
}
|
||
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = hrTemp;
|
||
}
|
||
}
|
||
}
|
||
NcFreeNetconProperties(pProps);
|
||
|
||
} while (SUCCEEDED(hr) && 1 == ulCount);
|
||
|
||
End:
|
||
TRACE_LEAVE("EnablePersonalFirewallOnAll", hr);
|
||
|
||
//normalize hr because we used IEnum
|
||
if (S_FALSE == hr)
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
return hr;
|
||
}
|
||
|
||
extern "C"
|
||
BOOL
|
||
WINAPI
|
||
WinBomConfigureHomeNet(
|
||
LPCTSTR lpszUnattend,
|
||
LPCTSTR lpszSection
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
Reads home networking settings from the specified unattend file and saves
|
||
those in current system that is already setup and running.
|
||
|
||
|
||
|
||
Arguments:
|
||
lpszUnattend [IN] Points to a string buffer which contains the full path
|
||
to the unattend file (winbom.ini in this case) with all
|
||
the home network settings.
|
||
|
||
lpszSection [IN] Points to a string buffer which contains the name of
|
||
the section which contains all the home network settings
|
||
in the unattend file specified above.
|
||
|
||
|
||
Return Value:
|
||
Returns TRUE if the settings were successfully read and saved to the system.
|
||
Otherwise returns FALSE to indicate something failed.
|
||
|
||
--*/
|
||
|
||
{
|
||
if (NULL == lpszSection || NULL == lpszUnattend)
|
||
return FALSE;
|
||
|
||
BOOL fRet = TRUE;
|
||
WCHAR szBuf[256] = {0};
|
||
DWORD dwRet = 0;
|
||
dwRet = GetPrivateProfileString(lpszSection,
|
||
c_szEnableFirewall,
|
||
_T(""),
|
||
szBuf,
|
||
sizeof(szBuf)/sizeof(szBuf[0]),
|
||
lpszUnattend);
|
||
|
||
if (dwRet)
|
||
{
|
||
if (0 == lstrcmpi(szBuf, c_szYes))
|
||
{
|
||
fRet = SUCCEEDED(EnablePersonalFirewallOnAll());
|
||
}
|
||
else if (0 == lstrcmpi(szBuf, c_szNo))
|
||
{
|
||
fRet = SUCCEEDED(DisablePersonalFirewallOnAll());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//if there is no EnableFirewall there, we should treat this
|
||
//as a success
|
||
fRet = TRUE;
|
||
}
|
||
|
||
return fRet;
|
||
}
|