windows-nt/Source/XPSP1/NT/net/mmc/rtrlib/rtrcomn.cpp
2020-09-26 16:20:57 +08:00

525 lines
14 KiB
C++

/**********************************************************************/
/** Microsoft Windows/NT **/
/** Copyright(c) Microsoft Corporation, 1997 - 1999 **/
/**********************************************************************/
/*
rtrcomn.cpp
FILE HISTORY:
*/
#include "stdafx.h"
#include "tfschar.h"
#include "info.h"
#include "rtrstr.h"
#include "rtrcomn.h"
#include "rtrguid.h"
#include "mprapi.h"
#include "rtrutil.h"
#include "lsa.h"
#include "tregkey.h"
#include "reg.h"
/*---------------------------------------------------------------------------
Function: IfInterfaceIdHasIpxExtensions
Checks the string to see if it has the following extensions
EthernetSNAP
EthernetII
Ethernet802.2
Ethernet802.3
---------------------------------------------------------------------------*/
int IfInterfaceIdHasIpxExtensions(LPCTSTR pszIfId)
{
CString stIfEnd;
CString stIf = pszIfId;
BOOL bFound = TRUE;
int iPos = 0;
do
{
stIfEnd = stIf.Right(lstrlen(c_szEthernetII));
if (stIfEnd == c_szEthernetII)
break;
stIfEnd = stIf.Right(lstrlen(c_szEthernetSNAP));
if (stIfEnd == c_szEthernetSNAP)
break;
stIfEnd = stIf.Right(lstrlen(c_szEthernet8022));
if (stIfEnd == c_szEthernet8022)
break;
stIfEnd = stIf.Right(lstrlen(c_szEthernet8023));
if (stIfEnd == c_szEthernet8023)
break;
bFound = FALSE;
}
while (FALSE);
if (bFound)
iPos = stIf.GetLength() - stIfEnd.GetLength();
return iPos;
}
extern const GUID CLSID_RemoteRouterConfig;
HRESULT CoCreateRouterConfig(LPCTSTR pszMachine,
IRouterInfo *pRouter,
COSERVERINFO *pcsi,
const GUID& riid,
IUnknown **ppUnk)
{
HRESULT hr = hrOK;
MULTI_QI qi;
Assert(ppUnk);
*ppUnk = NULL;
if (IsLocalMachine(pszMachine))
{
hr = CoCreateInstance(CLSID_RemoteRouterConfig,
NULL,
CLSCTX_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
riid,
(LPVOID *) &(qi.pItf));
}
else
{
SPIRouterAdminAccess spAdmin;
BOOL fAdminInfoSet = FALSE;
COSERVERINFO csi;
Assert(pcsi);
qi.pIID = &riid;
qi.pItf = NULL;
qi.hr = 0;
pcsi->dwReserved1 = 0;
pcsi->dwReserved2 = 0;
pcsi->pwszName = (LPWSTR) (LPCTSTR) pszMachine;
if (pRouter)
{
spAdmin.HrQuery(pRouter);
if (spAdmin && spAdmin->IsAdminInfoSet())
{
int cPassword;
int cchPassword;
WCHAR * pszPassword = NULL;
UCHAR ucSeed = 0x83;
pcsi->pAuthInfo->dwAuthnSvc = RPC_C_AUTHN_WINNT;
pcsi->pAuthInfo->dwAuthzSvc = RPC_C_AUTHZ_NONE;
pcsi->pAuthInfo->pwszServerPrincName = NULL;
pcsi->pAuthInfo->dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
pcsi->pAuthInfo->dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
// pcsi->pAuthInfo->pAuthIdentityData = &caid;
pcsi->pAuthInfo->dwCapabilities = EOAC_NONE;
if (spAdmin->GetUserName())
{
pcsi->pAuthInfo->pAuthIdentityData->User = (LPTSTR) spAdmin->GetUserName();
pcsi->pAuthInfo->pAuthIdentityData->UserLength = StrLenW(spAdmin->GetUserName());
}
if (spAdmin->GetDomainName())
{
pcsi->pAuthInfo->pAuthIdentityData->Domain = (LPTSTR) spAdmin->GetDomainName();
pcsi->pAuthInfo->pAuthIdentityData->DomainLength = StrLenW(spAdmin->GetDomainName());
}
spAdmin->GetUserPassword(NULL, &cPassword);
// Assume that the password is Unicode
cchPassword = cPassword / sizeof(WCHAR);
pszPassword = (WCHAR *) new BYTE[cPassword + sizeof(WCHAR)];
spAdmin->GetUserPassword((PBYTE) pszPassword, &cPassword);
pszPassword[cchPassword] = 0;
RtlDecodeW(ucSeed, pszPassword);
delete pcsi->pAuthInfo->pAuthIdentityData->Password;
pcsi->pAuthInfo->pAuthIdentityData->Password = pszPassword;
pcsi->pAuthInfo->pAuthIdentityData->PasswordLength = cchPassword;
pcsi->pAuthInfo->pAuthIdentityData->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
fAdminInfoSet = TRUE;
}
else
{
pcsi->pAuthInfo = NULL;
}
}
hr = CoCreateInstanceEx(CLSID_RemoteRouterConfig,
NULL,
CLSCTX_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
pcsi,
1,
&qi);
if (FHrOK(hr) && fAdminInfoSet)
{
DWORD dwAuthnSvc, dwAuthzSvc, dwAuthnLevel, dwImpLevel;
DWORD dwCaps;
OLECHAR * pszServerPrincipal = NULL;
CComPtr<IUnknown> spIUnk;
qi.pItf->QueryInterface(IID_IUnknown, (void**)&spIUnk);
CoQueryProxyBlanket(spIUnk,
&dwAuthnSvc,
&dwAuthzSvc,
&pszServerPrincipal,
&dwAuthnLevel,
&dwImpLevel,
NULL,
&dwCaps);
hr = CoSetProxyBlanket(spIUnk,
dwAuthnSvc,
dwAuthzSvc,
pszServerPrincipal,
dwAuthnLevel,
dwImpLevel,
(RPC_AUTH_IDENTITY_HANDLE) pcsi->pAuthInfo->pAuthIdentityData,
dwCaps);
CoTaskMemFree(pszServerPrincipal);
pszServerPrincipal = NULL;
CoQueryProxyBlanket(qi.pItf,
&dwAuthnSvc,
&dwAuthzSvc,
&pszServerPrincipal,
&dwAuthnLevel,
&dwImpLevel,
NULL,
&dwCaps);
hr = CoSetProxyBlanket(qi.pItf,
dwAuthnSvc,
dwAuthzSvc,
pszServerPrincipal,
dwAuthnLevel,
dwImpLevel,
(RPC_AUTH_IDENTITY_HANDLE) pcsi->pAuthInfo->pAuthIdentityData,
dwCaps);
CoTaskMemFree(pszServerPrincipal);
}
}
if (FHrSucceeded(hr))
{
*ppUnk = qi.pItf;
qi.pItf = NULL;
}
return hr;
}
/*!--------------------------------------------------------------------------
CoCreateProtocolConfig
-
Author: KennT
---------------------------------------------------------------------------*/
HRESULT CoCreateProtocolConfig(const GUID& iid,
IRouterInfo *pRouter,
DWORD dwTransportId,
DWORD dwProtocolId,
IRouterProtocolConfig **ppConfig)
{
HRESULT hr = hrOK;
GUID guidConfig;
guidConfig = iid;
if (((iid == GUID_RouterNull) ||
(iid == GUID_RouterError)) &&
pRouter)
{
RouterVersionInfo routerVersion;
pRouter->GetRouterVersionInfo(&routerVersion);
// If we don't have a configuration GUID and this is an NT4
// router, then we create the default configuration object
// and use that to add/remove a protocol
// ------------------------------------------------------------
if ((routerVersion.dwRouterVersion <= 4) &&
(dwTransportId == PID_IP))
{
// For NT4, we have to create our own object
// --------------------------------------------------------
guidConfig = CLSID_IPRouterConfiguration;
}
}
if (guidConfig == GUID_RouterNull)
{
// Skip the rest of the creation, we didn't supply a GUID
// ------------------------------------------------------------
goto Error;
}
if (guidConfig == GUID_RouterError)
{
// We don't have a valid GUID
// ------------------------------------------------------------
CWRg( ERROR_BADKEY );
}
hr = CoCreateInstance(guidConfig,
NULL,
CLSCTX_INPROC_SERVER | CLSCTX_ENABLE_CODE_DOWNLOAD,
IID_IRouterProtocolConfig,
(LPVOID *) ppConfig);
CORg( hr );
Error:
return hr;
}
//----------------------------------------------------------------------------
// Function: QueryIpAddressList(
//
// Loads a list of strings with the IP addresses configured
// for a given LAN interface, if any.
//----------------------------------------------------------------------------
HRESULT
QueryIpAddressList(
IN LPCTSTR pszMachine,
IN HKEY hkeyMachine,
IN LPCTSTR pszInterface,
OUT CStringList* pAddressList,
OUT CStringList* pNetmaskList,
OUT BOOL * pfDhcpObtained,
OUT BOOL * pfDns,
OUT CString * pDhcpServer
) {
DWORD dwErr;
BOOL bDisconnect = FALSE;
RegKey regkeyMachine;
RegKey regkeyInterface;
DWORD dwType, dwSize, dwEnableDHCP;
SPBYTE spValue;
HRESULT hr = hrOK;
HKEY hkeyInterface;
INT i;
TCHAR* psz;
LPCTSTR aszSources[2];
CStringList* alistDestinations[2] = { pAddressList, pNetmaskList };
CString stNameServer;
LPCTSTR pszNameServer = NULL;
if (!pszInterface || !lstrlen(pszInterface) ||
!pAddressList || !pNetmaskList)
CORg(E_INVALIDARG);
//
// If no HKEY_LOCAL_MACHINE key was given, get one
//
if (hkeyMachine == NULL)
{
CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
regkeyMachine.Attach(hkeyMachine);
}
//
// Connect to the LAN card's registry key
//
CWRg( OpenTcpipInterfaceParametersKey(pszMachine, pszInterface,
hkeyMachine, &hkeyInterface) );
regkeyInterface.Attach(hkeyInterface);
//
// Read the 'EnableDHCP' flag to see whether to read
// the 'DhcpIPAddress' or the 'IPAddress'.
//
dwErr = regkeyInterface.QueryValue( c_szEnableDHCP, dwEnableDHCP );
if (dwErr == ERROR_SUCCESS)
{
if (pfDhcpObtained)
*pfDhcpObtained = dwEnableDHCP;
}
else
dwEnableDHCP = FALSE;
//
// If the flag isn't found, we look for the IP address;
// otherwise, we look for the setting indicated by the flag
//
if (dwErr == NO_ERROR && dwEnableDHCP)
{
//
// Read the 'DhcpIpAddress' and 'DhcpSubnetMask'
//
aszSources[0] = c_szDhcpIpAddress;
aszSources[1] = c_szDhcpSubnetMask;
pszNameServer = c_szRegValDhcpNameServer;
}
else
{
//
// Read the 'IPAddress' and 'SubnetMask'
//
aszSources[0] = c_szIPAddress;
aszSources[1] = c_szSubnetMask;
pszNameServer= c_szRegValNameServer;
}
if (pDhcpServer)
{
pDhcpServer->Empty();
regkeyInterface.QueryValue(c_szRegValDhcpServer, *pDhcpServer);
}
// Check the DhcpNameServer/NameServer to find the existence
// of DNS servers
if (pfDns)
{
regkeyInterface.QueryValue(pszNameServer, stNameServer);
stNameServer.TrimLeft();
stNameServer.TrimRight();
*pfDns = !stNameServer.IsEmpty();
}
//
// Read the address list and the netmask list
//
for (i = 0; i < 2 && dwErr == NO_ERROR; i++)
{
//
// Get the size of the multi-string-list
//
dwErr = regkeyInterface.QueryTypeAndSize(aszSources[i],
&dwType, &dwSize);
// CheckRegQueryValueError(dwErr, (LPCTSTR) c_szTcpip, aszSources[i], _T("QueryIpAddressList"));
CWRg( dwErr );
//
// Allocate space for the list
//
spValue = new BYTE[dwSize + sizeof(TCHAR)];
Assert(spValue);
::ZeroMemory(spValue, dwSize + sizeof(TCHAR));
//
// Read the list
//
dwErr = regkeyInterface.QueryValue(aszSources[i], (LPTSTR) (BYTE *)spValue, dwSize,
FALSE /* fExpandSz */);
// CheckRegQueryValueError(dwErr, (LPCTSTR) c_szTcpip, aszSources[i], _T("QueryIpAddressList"));
CWRg( dwErr );
//
// Fill the CString list with items
//
for (psz = (TCHAR*)(BYTE *)spValue; *psz; psz += lstrlen(psz) + 1)
{
alistDestinations[i]->AddTail(psz);
}
spValue.Free();
dwErr = NO_ERROR;
}
Error:
return dwErr;
}
/*!--------------------------------------------------------------------------
OpenTcpipInterfaceParametersKey
-
Author: KennT
---------------------------------------------------------------------------*/
DWORD OpenTcpipInterfaceParametersKey(LPCTSTR pszMachine,
LPCTSTR pszInterface,
HKEY hkeyMachine,
HKEY *phkeyParams)
{
DWORD dwErr;
BOOL fNt4;
CString skey;
dwErr = IsNT4Machine(hkeyMachine, &fNt4);
if (dwErr != ERROR_SUCCESS)
return dwErr;
//$NT5 : kennt, the tcpip key is stored separately. What they
// have done is to reverse the hierarchy, instead of a tcpip key
// under interfaces, there are now interfaces under tcpip
// the key location is
// HKLM\System\CCS\Services\Tcpip\Parameters\Interfaces\{interface}
// In NT4, this was
// HKLM\System\CCS\Services\{interface}\Parameters\Tcpip
// Need to determine if the target machine is running NT5 or not
if (fNt4)
{
skey = c_szSystemCCSServices;
skey += TEXT('\\');
skey += pszInterface;
skey += TEXT('\\');
skey += c_szParameters;
skey += TEXT('\\');
skey += c_szTcpip;
}
else
{
skey = c_szSystemCCSServices;
skey += TEXT('\\');
skey += c_szTcpip;
skey += TEXT('\\');
skey += c_szParameters;
skey += TEXT('\\');
skey += c_szInterfaces;
skey += TEXT('\\');
skey += pszInterface;
}
if (dwErr == ERROR_SUCCESS)
{
dwErr = ::RegOpenKeyEx(
hkeyMachine, skey, 0, KEY_ALL_ACCESS, phkeyParams);
// CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("OpenTcpInterfaceParametersKey"));
}
return dwErr;
}