1172 lines
35 KiB
C++
1172 lines
35 KiB
C++
/**********************************************************************/
|
|
/** RemCfg.cpp : Implementation of CRemCfg **/
|
|
/** **/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(C) Microsoft Corporation, 1997 - 1999 **/
|
|
/**********************************************************************/
|
|
|
|
#include "stdafx.h"
|
|
#include <ntsecapi.h>
|
|
#include <iptypes.h>
|
|
#define _PNP_POWER_
|
|
#include <ndispnp.h>
|
|
#define _USTRINGP_NO_UNICODE_STRING
|
|
#include "ustringp.h"
|
|
#include <ntddip.h>
|
|
#include <iphlpapi.h>
|
|
#include "ndisutil.h"
|
|
#include "assert.h"
|
|
#include "remras.h"
|
|
|
|
#include "atlapp.h"
|
|
#include "atltmp.h"
|
|
|
|
#include "RemCfg.h"
|
|
|
|
#include "netcfgp.h" // private INetCfg stuff
|
|
#include "devguid.h"
|
|
EXTERN_C const CLSID CLSID_CNetCfg;
|
|
|
|
#include "update.h"
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CRemCfg
|
|
|
|
|
|
BOOL s_fWriteIPConfig;
|
|
BOOL s_fRestartRouter;
|
|
RemCfgIPEntryList s_IPEntryList;
|
|
extern DWORD g_dwTraceHandle;
|
|
|
|
|
|
|
|
CRemCfg::~CRemCfg()
|
|
{
|
|
TraceSz("CRemCfg destructor");
|
|
|
|
DeleteCriticalSection(&m_critsec);
|
|
}
|
|
|
|
STDMETHODIMP CRemCfg::NotifyChanges(/* [in] */ BOOL fEnableRouter,
|
|
/* [in] */ BYTE uPerformRouterDiscovery)
|
|
{
|
|
//Do nothing to fix bug 405636 and 345700
|
|
//But still keep to method for compatibility with old builds
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::SetRasEndpoints
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::SetRasEndpoints(DWORD dwFlags, DWORD dwTotalEndpoints, DWORD dwTotalIncoming, DWORD dwTotalOutgoing)
|
|
{
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::GetIpxVirtualNetworkNumber
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::GetIpxVirtualNetworkNumber(DWORD * pdwVNetworkNumber)
|
|
{
|
|
//$ TODO : need to add a try/catch block around the whole thing!
|
|
INetCfg * pNetCfg = NULL;
|
|
IIpxAdapterInfo * pIpxAdapterInfo = NULL;
|
|
DWORD dwNetwork;
|
|
HRESULT hr = S_OK;
|
|
|
|
TraceSz("CRemCfg::GetIpxVirtualNetworkNumber entered");
|
|
|
|
if (pdwVNetworkNumber == NULL)
|
|
return E_INVALIDARG;
|
|
|
|
|
|
// Create the INetCfg, we're only reading so we don't
|
|
// need to grab the write lock.
|
|
hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
|
|
&pNetCfg,
|
|
FALSE /* fGetWriteLock */,
|
|
0 /* cmsTimeout */,
|
|
NULL /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
hr = HrGetIpxPrivateInterface(pNetCfg, &pIpxAdapterInfo);
|
|
|
|
if (hr == S_OK)
|
|
hr = pIpxAdapterInfo->GetVirtualNetworkNumber(&dwNetwork);
|
|
|
|
if (hr == S_OK)
|
|
*pdwVNetworkNumber = dwNetwork;
|
|
|
|
if (pIpxAdapterInfo)
|
|
pIpxAdapterInfo->Release();
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE, /* fInitCom, */
|
|
pNetCfg,
|
|
FALSE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::GetIpxVirtualNetworkNumber", hr);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::SetIpxVirtualNetworkNumber
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::SetIpxVirtualNetworkNumber(DWORD dwVNetworkNumber)
|
|
{
|
|
//$ TODO : need to add a try/catch block around the whole thing!
|
|
INetCfg * pNetCfg = NULL;
|
|
IIpxAdapterInfo * pIpxAdapterInfo = NULL;
|
|
HRESULT hr = S_OK;
|
|
CString st;
|
|
|
|
TraceSz("CRemCfg::SetIpxVirtualNetworkNumber entered");
|
|
|
|
try
|
|
{
|
|
st.LoadString(IDS_CLIENT_DESC);
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
};
|
|
|
|
// Create the INetCfg, we're only reading so we don't
|
|
// need to grab the write lock.
|
|
if (hr == S_OK)
|
|
hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
|
|
&pNetCfg,
|
|
TRUE /* fGetWriteLock */,
|
|
500 /* cmsTimeout */,
|
|
(LPCTSTR) st /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
hr = HrGetIpxPrivateInterface(pNetCfg, &pIpxAdapterInfo);
|
|
|
|
if (hr == S_OK)
|
|
hr = pIpxAdapterInfo->SetVirtualNetworkNumber(dwVNetworkNumber);
|
|
|
|
if (hr == S_OK)
|
|
hr = pNetCfg->Apply();
|
|
|
|
if (pIpxAdapterInfo)
|
|
pIpxAdapterInfo->Release();
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE, /*fInitCom, */
|
|
pNetCfg,
|
|
TRUE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::SetIpxVirtualNetworkNumber", hr);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::GetIpInfo
|
|
-
|
|
Author: TongLu, KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::GetIpInfo(const GUID *pGuid, REMOTE_RRAS_IPINFO * * ppInfo)
|
|
{
|
|
// TODO: Add your implementation code here
|
|
|
|
INetCfg * pNetCfg = NULL;
|
|
ITcpipProperties * pTcpipProperties = NULL;
|
|
DWORD dwNetwork;
|
|
HRESULT hr = S_OK;
|
|
REMOTE_IPINFO *pRemoteIpInfo = NULL;
|
|
REMOTE_RRAS_IPINFO * pRemoteRrasIpInfo = NULL;
|
|
|
|
TraceSz("CRemCfg::GetIpInfo entered");
|
|
|
|
if ((pGuid == NULL) || (ppInfo == NULL))
|
|
return E_INVALIDARG;
|
|
|
|
// Create the INetCfg, we're only reading so we don't
|
|
// need to grab the write lock.
|
|
hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
|
|
&pNetCfg,
|
|
FALSE /* fGetWriteLock */,
|
|
0 /* cmsTimeout */,
|
|
NULL /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
|
|
TraceResult("HrGetIpPrivateInterface", hr);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pTcpipProperties->GetIpInfoForAdapter(pGuid, &pRemoteIpInfo);
|
|
|
|
if (hr != S_OK)
|
|
{
|
|
OLECHAR szBuffer[256];
|
|
CHAR szOutBuffer[256];
|
|
|
|
StringFromGUID2(*pGuid, szBuffer, 256);
|
|
|
|
wsprintfA(szOutBuffer, "ITcpipProperties::GetIpInfoForAdapter(%ls)",
|
|
szBuffer);
|
|
TraceResult(szOutBuffer, hr);
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// Need to duplicate the functionality (best to keep the
|
|
// memory allocations separate).
|
|
|
|
// Need to allocate the memory for the structure
|
|
pRemoteRrasIpInfo = (REMOTE_RRAS_IPINFO *) CoTaskMemAlloc(sizeof(REMOTE_RRAS_IPINFO));
|
|
if (!pRemoteRrasIpInfo)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
::ZeroMemory(pRemoteRrasIpInfo, sizeof(*pRemoteRrasIpInfo));
|
|
|
|
// Set dhcp
|
|
pRemoteRrasIpInfo->dwEnableDhcp = pRemoteIpInfo->dwEnableDhcp;
|
|
// pRemoteRrasIpInfo->dwEnableDhcp = FALSE;
|
|
|
|
// Allocate space for each string and copy the data
|
|
// pRemoteRrasIpInfo->bstrIpAddrList =
|
|
// SysAllocString(_T("1.2.3.4,1.2.3.5"));
|
|
// pRemoteRrasIpInfo->bstrSubnetMaskList =
|
|
// SysAllocString(_T("255.0.0.0,255.0.0.0"));
|
|
// pRemoteRrasIpInfo->bstrOptionList =
|
|
// SysAllocString(_T("12.12.13.15,12.12.13.14"));
|
|
pRemoteRrasIpInfo->bstrIpAddrList =
|
|
SysAllocString(pRemoteIpInfo->pszwIpAddrList);
|
|
if (!pRemoteRrasIpInfo->bstrIpAddrList &&
|
|
pRemoteIpInfo->pszwIpAddrList)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
|
|
pRemoteRrasIpInfo->bstrSubnetMaskList =
|
|
SysAllocString(pRemoteIpInfo->pszwSubnetMaskList);
|
|
if (!pRemoteRrasIpInfo->bstrSubnetMaskList &&
|
|
pRemoteIpInfo->pszwSubnetMaskList)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
|
|
pRemoteRrasIpInfo->bstrOptionList =
|
|
SysAllocString(pRemoteIpInfo->pszwOptionList);
|
|
if (!pRemoteRrasIpInfo->bstrOptionList &&
|
|
pRemoteIpInfo->pszwOptionList)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
goto Error;
|
|
}
|
|
}
|
|
|
|
Error:
|
|
if (!SUCCEEDED(hr))
|
|
{
|
|
if (pRemoteRrasIpInfo)
|
|
{
|
|
SysFreeString(pRemoteRrasIpInfo->bstrIpAddrList);
|
|
SysFreeString(pRemoteRrasIpInfo->bstrSubnetMaskList);
|
|
SysFreeString(pRemoteRrasIpInfo->bstrOptionList);
|
|
CoTaskMemFree(pRemoteRrasIpInfo);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
*ppInfo = pRemoteRrasIpInfo;
|
|
pRemoteRrasIpInfo = NULL;
|
|
}
|
|
|
|
if (pRemoteIpInfo)
|
|
{
|
|
CoTaskMemFree(pRemoteIpInfo);
|
|
pRemoteIpInfo = NULL;
|
|
}
|
|
|
|
if (pTcpipProperties)
|
|
pTcpipProperties->Release();
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE,
|
|
pNetCfg,
|
|
FALSE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::GetIpInfo", hr);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::SetIpInfo
|
|
-
|
|
Author: TongLu, KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::SetIpInfo(const GUID *pGuid, REMOTE_RRAS_IPINFO * pIpInfo)
|
|
{
|
|
// TODO: Add your implementation code here
|
|
|
|
INetCfg * pNetCfg = NULL;
|
|
ITcpipProperties * pTcpipProperties = NULL;
|
|
DWORD dwNetwork;
|
|
HRESULT hr = S_OK;
|
|
CString st;
|
|
RemCfgIPEntry * pIpEntry = NULL;
|
|
RtrCriticalSection cs(&m_critsec);
|
|
|
|
TraceSz("CRemCfg::SetIpInfo entered");
|
|
|
|
if ((pGuid == NULL) || (pIpInfo == NULL))
|
|
{
|
|
TraceResult("CRemCfg::SetIpInfo", E_INVALIDARG);
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
try
|
|
{
|
|
st.LoadString(IDS_CLIENT_DESC);
|
|
pIpEntry = new RemCfgIPEntry;
|
|
pIpEntry->m_newIPInfo.pszwIpAddrList = NULL;
|
|
pIpEntry->m_newIPInfo.pszwSubnetMaskList = NULL;
|
|
pIpEntry->m_newIPInfo.pszwOptionList = NULL;
|
|
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
};
|
|
|
|
// Create the INetCfg, we're only reading so we don't
|
|
// need to grab the write lock.
|
|
if (hr == S_OK)
|
|
hr = HrCreateAndInitializeINetCfg(NULL,
|
|
&pNetCfg,
|
|
TRUE /* fGetWriteLock */,
|
|
500 /* cmsTimeout */,
|
|
(LPCTSTR) st /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
pIpEntry->m_IPGuid = *pGuid;
|
|
pIpEntry->m_newIPInfo.dwEnableDhcp = pIpInfo->dwEnableDhcp;
|
|
pIpEntry->m_newIPInfo.pszwIpAddrList = StrDupW((LPWSTR) pIpInfo->bstrIpAddrList);
|
|
pIpEntry->m_newIPInfo.pszwSubnetMaskList = StrDupW((LPWSTR) pIpInfo->bstrSubnetMaskList);
|
|
pIpEntry->m_newIPInfo.pszwOptionList = StrDupW((LPWSTR) pIpInfo->bstrOptionList);
|
|
|
|
hr = pTcpipProperties->SetIpInfoForAdapter(pGuid, &(pIpEntry->m_newIPInfo));
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// Add this to the list of OK IP address changes
|
|
s_IPEntryList.Add(pIpEntry);
|
|
pIpEntry = NULL;
|
|
s_fWriteIPConfig = TRUE;
|
|
}
|
|
|
|
// this now gets done in CommitIPInfo
|
|
// if (hr == S_OK)
|
|
// hr = pNetCfg->Apply();
|
|
|
|
//Error:
|
|
if (pTcpipProperties)
|
|
pTcpipProperties->Release();
|
|
|
|
if (pIpEntry)
|
|
{
|
|
delete pIpEntry->m_newIPInfo.pszwIpAddrList;
|
|
delete pIpEntry->m_newIPInfo.pszwSubnetMaskList;
|
|
delete pIpEntry->m_newIPInfo.pszwOptionList;
|
|
delete pIpEntry;
|
|
}
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE,
|
|
pNetCfg,
|
|
TRUE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::SetIpInfo", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrCleanRouterManagerEntries
|
|
//
|
|
// Purpose: Remove all Router Manager entries from the registry.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: MikeG (a-migall) 6 Nov 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrCleanRouterManagerEntries()
|
|
{
|
|
// Open a connection to the registry key so we can "clean"
|
|
// the registry entries before an install/update to ensure
|
|
// that we can start with a "clean" state.
|
|
CRegKey rk;
|
|
long lRes = rk.Open(HKEY_LOCAL_MACHINE,
|
|
_T("System\\CurrentControlSet\\Services\\RemoteAccess\\RouterManagers"));
|
|
Assert(rk.m_hKey != NULL);
|
|
HRESULT hr = S_OK;
|
|
if (lRes == ERROR_FILE_NOT_FOUND) // if key doesn't exist, exit...
|
|
return hr;
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
TraceError ("HrCleanRouterManagerEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
// Eliminate the IP transport subkey.
|
|
lRes = rk.DeleteSubKey(_T("Ip"));
|
|
if (lRes > ERROR_FILE_NOT_FOUND)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
TraceError ("HrCleanRouterManagerEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
// Eliminate the IPX transport subkey.
|
|
lRes = rk.DeleteSubKey(_T("Ipx"));
|
|
if (lRes > ERROR_FILE_NOT_FOUND)
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
|
|
TraceError ("HrCleanRouterManagerEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: RecurseDeleteKey
|
|
//
|
|
// Purpose: Delete a named registry key and all of its subkeys.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: MikeG (a-migall) 6 Nov 1998
|
|
//
|
|
// Notes: Shamelessly stolen from Kenn's code in ...\tfscore\tregkey.h.
|
|
//
|
|
long
|
|
RecurseDeleteKey(
|
|
IN CRegKey &rk,
|
|
IN LPCTSTR lpszKey)
|
|
{
|
|
Assert(!::IsBadReadPtr(&rk, sizeof(CRegKey)));
|
|
Assert(rk.m_hKey != NULL);
|
|
Assert(!::IsBadStringPtr(lpszKey, ::lstrlen(lpszKey)));
|
|
|
|
CRegKey key;
|
|
long lRes = key.Open(HKEY(rk), lpszKey);
|
|
if (lRes != ERROR_SUCCESS)
|
|
return lRes;
|
|
|
|
FILETIME time;
|
|
TCHAR szBuffer[256];
|
|
DWORD dwSize = 256;
|
|
|
|
while (::RegEnumKeyEx(HKEY(key),
|
|
0,
|
|
szBuffer,
|
|
&dwSize,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&time) == ERROR_SUCCESS)
|
|
{
|
|
lRes = RecurseDeleteKey(key, szBuffer);
|
|
if (lRes != ERROR_SUCCESS)
|
|
return lRes;
|
|
dwSize = 256;
|
|
}
|
|
|
|
key.Close();
|
|
return rk.DeleteSubKey(lpszKey);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: HrCleanRouterInterfacesEntries
|
|
//
|
|
// Purpose: Remove all Router Interface entries from the registry.
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Returns:
|
|
//
|
|
// Author: MikeG (a-migall) 6 Nov 1998
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrCleanRouterInterfacesEntries()
|
|
{
|
|
// Open a connection to the registry key so we can "clean" the
|
|
// registry entries before an install/update to ensure that we
|
|
// can start with a "clean" state.
|
|
CRegKey rk;
|
|
long lRes = rk.Open(HKEY_LOCAL_MACHINE,
|
|
_T("System\\CurrentControlSet\\Services\\RemoteAccess\\Interfaces"));
|
|
Assert(rk.m_hKey != NULL);
|
|
HRESULT hr = S_OK;
|
|
if (lRes == ERROR_FILE_NOT_FOUND) // if key doesn't exist, exit...
|
|
return hr;
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
TraceError ("HrCleanRouterInterfacesEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
// Determine how many interfaces have been defined.
|
|
DWORD dwSubKeyCnt = 0;
|
|
lRes = ::RegQueryInfoKey(HKEY(rk), // handle to key to query
|
|
NULL, // address of buffer for class string
|
|
NULL, // address of size of class string buffer
|
|
NULL, // reserved...
|
|
&dwSubKeyCnt, // address of buffer for number of subkeys
|
|
NULL, // address of buffer for longest subkey name length
|
|
NULL, // address of buffer for longest class string length
|
|
NULL, // address of buffer for number of value entries
|
|
NULL, // address of buffer for longest value name length
|
|
NULL, // address of buffer for longest value data length
|
|
NULL, // address of buffer for security descriptor length
|
|
NULL); // address of buffer for last write time
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
TraceError ("HrCleanRouterInterfacesEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
// Eliminate each of the subkeys.
|
|
CString st;
|
|
DWORD dwStrSize = 256;
|
|
LPTSTR pszKeyName = st.GetBuffer(dwStrSize);
|
|
// while (dwSubKeyCnt >= 0)
|
|
while (TRUE) // change from above to TRUE, and lRes from the API will cause loop to end
|
|
{
|
|
// Get the name of the subkey to be deleted.
|
|
lRes = ::RegEnumKeyEx(HKEY(rk), // handle to key to enumerate
|
|
--dwSubKeyCnt, // index of subkey to enumerate
|
|
pszKeyName, // address of buffer for subkey name
|
|
&dwStrSize, // address for size of subkey buffer
|
|
NULL, // reserved...
|
|
NULL, // address of buffer for class string
|
|
NULL, // address for size of class buffer
|
|
NULL); // address for time key last written to
|
|
if (lRes != ERROR_SUCCESS)
|
|
{
|
|
if ((lRes == ERROR_FILE_NOT_FOUND) ||
|
|
(lRes == ERROR_NO_MORE_ITEMS))
|
|
{
|
|
lRes = 0; // we've run out of keys; so, we can successfuly exit.
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Delete the key and all of its children.
|
|
lRes = RecurseDeleteKey(rk, pszKeyName);
|
|
if (lRes > ERROR_FILE_NOT_FOUND)
|
|
break;
|
|
|
|
// Cleanup for next pass.
|
|
dwStrSize = 256;
|
|
::ZeroMemory(pszKeyName, (dwStrSize*sizeof(TCHAR)));
|
|
}
|
|
st.ReleaseBuffer();
|
|
|
|
hr = HRESULT_FROM_WIN32(lRes);
|
|
TraceError ("HrCleanRouterInterfacesEntries", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
STDMETHODIMP CRemCfg::UpgradeRouterConfig()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INetCfg * pNetCfg = NULL;
|
|
|
|
TraceSz("CRemCfg::UpgradeRouterConfig entered");
|
|
|
|
try
|
|
{
|
|
// This is a two-step process
|
|
CSteelhead update;
|
|
CString st;
|
|
|
|
st.LoadString(IDS_CLIENT_DESC);
|
|
|
|
// First get the INetCfg
|
|
hr = HrCreateAndInitializeINetCfg(NULL, /* &fInitCom, */
|
|
&pNetCfg,
|
|
FALSE /* fGetWriteLock */,
|
|
500 /* cmsTimeout */,
|
|
(LPCTSTR) st /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
update.Initialize(pNetCfg);
|
|
hr = update.HrFindOtherComponents();
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// Delete all previous router configs so we can get back
|
|
// to a "clean" install point.
|
|
hr = HrCleanRouterManagerEntries();
|
|
Assert(SUCCEEDED(hr));
|
|
hr = HrCleanRouterInterfacesEntries();
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
// Now create the router config info.
|
|
hr = update.HrUpdateRouterConfiguration();
|
|
Assert(SUCCEEDED(hr));
|
|
|
|
update.ReleaseOtherComponents();
|
|
|
|
RegFlushKey(HKEY_LOCAL_MACHINE);
|
|
}
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_FAIL;
|
|
}
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE, /* fInitCom, */
|
|
pNetCfg,
|
|
FALSE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::UpgradeRouterConfig", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CRemCfg::SetUserConfig(LPCOLESTR pszService,
|
|
LPCOLESTR pszNewGroup)
|
|
{
|
|
DWORD err;
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
err = SvchostChangeSvchostGroup(pszService, pszNewGroup);
|
|
|
|
hr = HRESULT_FROM_WIN32(err);
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
TraceResult("CRemCfg::SetUserConfig", hr);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
CRemCfg::RestartRouter
|
|
Implementation of IRemoteRouterRestart::RestartRouter
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP CRemCfg::RestartRouter(DWORD dwFlags)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try
|
|
{
|
|
// the router will be restarted when remrras.exe shuts down
|
|
// ------------------------------------------------------------
|
|
s_fRestartRouter = TRUE;
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
}
|
|
|
|
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CommitIPInfo()
|
|
{
|
|
// TODO: Add your implementation code here
|
|
|
|
INetCfg * pNetCfg = NULL;
|
|
ITcpipProperties * pTcpipProperties = NULL;
|
|
DWORD dwNetwork;
|
|
HRESULT hr = S_OK;
|
|
CString st;
|
|
WCHAR swzGuid[256];
|
|
|
|
TraceSz("CRemCfg::CommitIpInfo entered");
|
|
|
|
try
|
|
{
|
|
st.LoadString(IDS_CLIENT_DESC);
|
|
}
|
|
catch(...)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
};
|
|
|
|
// Create the INetCfg, we're only reading so we don't
|
|
// need to grab the write lock.
|
|
if (hr == S_OK)
|
|
hr = HrCreateAndInitializeINetCfg(NULL,
|
|
&pNetCfg,
|
|
TRUE /* fGetWriteLock */,
|
|
500 /* cmsTimeout */,
|
|
(LPCTSTR) st /* swzClientDesc */,
|
|
NULL /* ppszwClientDesc */);
|
|
|
|
if (hr == S_OK)
|
|
hr = HrGetIpPrivateInterface(pNetCfg, &pTcpipProperties);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
RemCfgIPEntry * pIpEntry = NULL;
|
|
|
|
for (int i=0; i<s_IPEntryList.GetSize(); i++)
|
|
{
|
|
pIpEntry = s_IPEntryList[i];
|
|
|
|
hr = pTcpipProperties->SetIpInfoForAdapter(
|
|
&(pIpEntry->m_IPGuid),
|
|
&(pIpEntry->m_newIPInfo));
|
|
|
|
StringFromGUID2(pIpEntry->m_IPGuid,
|
|
swzGuid, 128);
|
|
|
|
TracePrintf(g_dwTraceHandle,
|
|
_T("Setting IP info for %ls returned 0x%08lx"),
|
|
swzGuid, hr);
|
|
TracePrintf(g_dwTraceHandle,
|
|
_T("DHCP Enabled : %d"),
|
|
pIpEntry->m_newIPInfo.dwEnableDhcp);
|
|
if (pIpEntry->m_newIPInfo.pszwIpAddrList)
|
|
TracePrintf(g_dwTraceHandle,
|
|
_T(" IP Address : %ls"),
|
|
pIpEntry->m_newIPInfo.pszwIpAddrList);
|
|
if (pIpEntry->m_newIPInfo.pszwSubnetMaskList)
|
|
TracePrintf(g_dwTraceHandle,
|
|
_T(" Subnet masks : %ls"),
|
|
pIpEntry->m_newIPInfo.pszwSubnetMaskList);
|
|
if (pIpEntry->m_newIPInfo.pszwOptionList)
|
|
TracePrintf(g_dwTraceHandle,
|
|
_T(" Gateway List : %ls"),
|
|
pIpEntry->m_newIPInfo.pszwOptionList);
|
|
|
|
}
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
hr = pNetCfg->Apply();
|
|
TraceResult("CRemCfg::CommitIpInfo calling Apply", hr);
|
|
}
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
// Release all memory
|
|
for (int i=0; i<s_IPEntryList.GetSize(); i++)
|
|
{
|
|
RemCfgIPEntry * pIpEntry = s_IPEntryList[i];
|
|
delete pIpEntry->m_newIPInfo.pszwIpAddrList;
|
|
delete pIpEntry->m_newIPInfo.pszwSubnetMaskList;
|
|
delete pIpEntry->m_newIPInfo.pszwOptionList;
|
|
delete pIpEntry;
|
|
}
|
|
s_IPEntryList.RemoveAll();
|
|
s_fWriteIPConfig = FALSE;
|
|
}
|
|
|
|
|
|
//Error:
|
|
if (pTcpipProperties)
|
|
pTcpipProperties->Release();
|
|
|
|
if (pNetCfg)
|
|
{
|
|
HrUninitializeAndReleaseINetCfg(FALSE,
|
|
pNetCfg,
|
|
TRUE /* fHasLock */);
|
|
pNetCfg = NULL;
|
|
}
|
|
|
|
TraceResult("CRemCfg::CommitIpInfo", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
HrGetIpxPrivateInterface
|
|
-
|
|
Author: ScottBri, KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT HrGetIpxPrivateInterface(INetCfg* pNetCfg,
|
|
IIpxAdapterInfo** ppIpxAdapterInfo)
|
|
{
|
|
HRESULT hr;
|
|
INetCfgClass* pncclass = NULL;
|
|
|
|
if ((pNetCfg == NULL) || (ppIpxAdapterInfo == NULL))
|
|
return E_INVALIDARG;
|
|
|
|
hr = pNetCfg->QueryNetCfgClass (&GUID_DEVCLASS_NETTRANS, IID_INetCfgClass,
|
|
reinterpret_cast<void**>(&pncclass));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgComponent * pnccItem = NULL;
|
|
|
|
// Find the component.
|
|
hr = pncclass->FindComponent(TEXT("MS_NWIPX"), &pnccItem);
|
|
//AssertSz (SUCCEEDED(hr), "pncclass->Find failed.");
|
|
if (S_OK == hr)
|
|
{
|
|
INetCfgComponentPrivate* pinccp = NULL;
|
|
hr = pnccItem->QueryInterface(IID_INetCfgComponentPrivate,
|
|
reinterpret_cast<void**>(&pinccp));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pinccp->QueryNotifyObject(IID_IIpxAdapterInfo,
|
|
reinterpret_cast<void**>(ppIpxAdapterInfo));
|
|
pinccp->Release();
|
|
}
|
|
}
|
|
|
|
if (pnccItem)
|
|
pnccItem->Release();
|
|
}
|
|
|
|
if (pncclass)
|
|
pncclass->Release();
|
|
|
|
// S_OK indicates success (interface returned)
|
|
// S_FALSE indicates Ipx not installed
|
|
// other values are errors
|
|
TraceResult("HrGetIpxPrivateInterface", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
HrGetIpPrivateInterface
|
|
-
|
|
Author: TongLu, KennT
|
|
---------------------------------------------------------------------------*/
|
|
HRESULT HrGetIpPrivateInterface(INetCfg* pNetCfg,
|
|
ITcpipProperties **ppTcpProperties)
|
|
{
|
|
HRESULT hr;
|
|
INetCfgClass* pncclass = NULL;
|
|
|
|
if ((pNetCfg == NULL) || (ppTcpProperties == NULL))
|
|
return E_INVALIDARG;
|
|
|
|
hr = pNetCfg->QueryNetCfgClass (&GUID_DEVCLASS_NETTRANS, IID_INetCfgClass,
|
|
reinterpret_cast<void**>(&pncclass));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgComponent * pnccItem = NULL;
|
|
|
|
// Find the component.
|
|
hr = pncclass->FindComponent(TEXT("MS_TCPIP"), &pnccItem);
|
|
//AssertSz (SUCCEEDED(hr), "pncclass->Find failed.");
|
|
if (S_OK == hr)
|
|
{
|
|
INetCfgComponentPrivate* pinccp = NULL;
|
|
hr = pnccItem->QueryInterface(IID_INetCfgComponentPrivate,
|
|
reinterpret_cast<void**>(&pinccp));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = pinccp->QueryNotifyObject(IID_ITcpipProperties,
|
|
reinterpret_cast<void**>(ppTcpProperties));
|
|
pinccp->Release();
|
|
}
|
|
}
|
|
|
|
if (pnccItem)
|
|
pnccItem->Release();
|
|
}
|
|
|
|
if (pncclass)
|
|
pncclass->Release();
|
|
|
|
// S_OK indicates success (interface returned)
|
|
// S_FALSE indicates Ipx not installed
|
|
// other values are errors
|
|
TraceResult("HrGetIpPrivateInterface", hr);
|
|
return hr;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrCreateAndInitializeINetCfg
|
|
//
|
|
// Purpose: Cocreate and initialize the root INetCfg object. This will
|
|
// optionally initialize COM for the caller too.
|
|
//
|
|
// Arguments:
|
|
// pfInitCom [in,out] TRUE to call CoInitialize before creating.
|
|
// returns TRUE if COM was successfully
|
|
// initialized FALSE if not. If NULL, means
|
|
// don't initialize COM.
|
|
// ppnc [out] The returned INetCfg object.
|
|
// fGetWriteLock [in] TRUE if a writable INetCfg is needed
|
|
// cmsTimeout [in] See INetCfg::LockForWrite
|
|
// szwClientDesc [in] See INetCfg::LockForWrite
|
|
// ppszwClientDesc [out] See INetCfg::LockForWrite
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 7 May 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrCreateAndInitializeINetCfg (
|
|
BOOL* pfInitCom,
|
|
INetCfg** ppnc,
|
|
BOOL fGetWriteLock,
|
|
DWORD cmsTimeout,
|
|
LPCWSTR szwClientDesc,
|
|
LPWSTR * ppszwClientDesc)
|
|
{
|
|
// ASSERT (ppnc);
|
|
|
|
// Initialize the output parameter.
|
|
*ppnc = NULL;
|
|
|
|
if (ppszwClientDesc)
|
|
*ppszwClientDesc = NULL;
|
|
|
|
// Initialize COM if the caller requested.
|
|
HRESULT hr = S_OK;
|
|
if (pfInitCom && *pfInitCom)
|
|
{
|
|
hr = CoInitializeEx( NULL,
|
|
COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED );
|
|
if (RPC_E_CHANGED_MODE == hr)
|
|
{
|
|
hr = S_OK;
|
|
if (pfInitCom)
|
|
{
|
|
*pfInitCom = FALSE;
|
|
}
|
|
}
|
|
}
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Create the object implementing INetCfg.
|
|
//
|
|
INetCfg* pnc;
|
|
hr = CoCreateInstance(CLSID_CNetCfg, NULL, CLSCTX_INPROC_SERVER,
|
|
IID_INetCfg, reinterpret_cast<void**>(&pnc));
|
|
TraceResult("HrCreateAndInitializeINetCfg - CoCreateInstance(CLSID_CNetCfg)", hr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgLock * pnclock = NULL;
|
|
if (fGetWriteLock)
|
|
{
|
|
// Get the locking interface
|
|
hr = pnc->QueryInterface(IID_INetCfgLock,
|
|
reinterpret_cast<LPVOID *>(&pnclock));
|
|
TraceResult("HrCreateAndInitializeINetCfg - QueryInterface(IID_INetCfgLock", hr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Attempt to lock the INetCfg for read/write
|
|
hr = pnclock->AcquireWriteLock(cmsTimeout, szwClientDesc,
|
|
ppszwClientDesc);
|
|
TraceResult("HrCreateAndInitializeINetCfg - INetCfgLock::LockForWrite", hr);
|
|
if (S_FALSE == hr)
|
|
{
|
|
// Couldn't acquire the lock
|
|
hr = NETCFG_E_NO_WRITE_LOCK;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Initialize the INetCfg object.
|
|
//
|
|
hr = pnc->Initialize (NULL);
|
|
TraceResult("HrCreateAndInitializeINetCfg - Initialize", hr);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*ppnc = pnc;
|
|
if (pnc)
|
|
pnc->AddRef();
|
|
}
|
|
else
|
|
{
|
|
if (pnclock)
|
|
{
|
|
pnclock->ReleaseWriteLock();
|
|
}
|
|
}
|
|
// Transfer reference to caller.
|
|
}
|
|
ReleaseObj(pnclock);
|
|
pnclock = NULL;
|
|
|
|
ReleaseObj(pnc);
|
|
pnc = NULL;
|
|
}
|
|
|
|
// If we failed anything above, and we've initialized COM,
|
|
// be sure an uninitialize it.
|
|
//
|
|
if (FAILED(hr) && pfInitCom && *pfInitCom)
|
|
{
|
|
CoUninitialize ();
|
|
}
|
|
}
|
|
TraceResult("HrCreateAndInitializeINetCfg", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUninitializeAndReleaseINetCfg
|
|
//
|
|
// Purpose: Unintialize and release an INetCfg object. This will
|
|
// optionally uninitialize COM for the caller too.
|
|
//
|
|
// Arguments:
|
|
// fUninitCom [in] TRUE to uninitialize COM after the INetCfg is
|
|
// uninitialized and released.
|
|
// pnc [in] The INetCfg object.
|
|
// fHasLock [in] TRUE if the INetCfg was locked for write and
|
|
// must be unlocked.
|
|
//
|
|
// Returns: S_OK or an error code.
|
|
//
|
|
// Author: shaunco 7 May 1997
|
|
//
|
|
// Notes: The return value is the value returned from
|
|
// INetCfg::Uninitialize. Even if this fails, the INetCfg
|
|
// is still released. Therefore, the return value is for
|
|
// informational purposes only. You can't touch the INetCfg
|
|
// object after this call returns.
|
|
//
|
|
HRESULT
|
|
HrUninitializeAndReleaseINetCfg (
|
|
BOOL fUninitCom,
|
|
INetCfg* pnc,
|
|
BOOL fHasLock)
|
|
{
|
|
// Assert (pnc);
|
|
HRESULT hr = S_OK;
|
|
|
|
if (fHasLock)
|
|
{
|
|
hr = HrUninitializeAndUnlockINetCfg(pnc);
|
|
}
|
|
else
|
|
{
|
|
hr = pnc->Uninitialize ();
|
|
}
|
|
|
|
ReleaseObj (pnc);
|
|
pnc = NULL;
|
|
|
|
if (fUninitCom)
|
|
{
|
|
CoUninitialize ();
|
|
}
|
|
TraceResult("HrUninitializeAndReleaseINetCfg", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: HrUninitializeAndUnlockINetCfg
|
|
//
|
|
// Purpose: Uninitializes and unlocks the INetCfg object
|
|
//
|
|
// Arguments:
|
|
// pnc [in] INetCfg to uninitialize and unlock
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 13 Nov 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT
|
|
HrUninitializeAndUnlockINetCfg (
|
|
INetCfg* pnc)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = pnc->Uninitialize();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
INetCfgLock * pnclock;
|
|
|
|
// Get the locking interface
|
|
hr = pnc->QueryInterface(IID_INetCfgLock,
|
|
reinterpret_cast<LPVOID *>(&pnclock));
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Attempt to lock the INetCfg for read/write
|
|
hr = pnclock->ReleaseWriteLock();
|
|
|
|
ReleaseObj(pnclock);
|
|
pnclock = NULL;
|
|
}
|
|
}
|
|
|
|
TraceResult("HrUninitializeAndUnlockINetCfg", hr);
|
|
return hr;
|
|
}
|
|
|