You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1048 lines
28 KiB
1048 lines
28 KiB
//============================================================================
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: util.cpp
|
|
//
|
|
// History:
|
|
// 03/10/97 Kenn M. Takara Created
|
|
//
|
|
// Source code for some of the utility functions in util.h
|
|
//============================================================================
|
|
|
|
#include "stdafx.h"
|
|
#include "mprsnap.h"
|
|
#include "rtrutilp.h"
|
|
#include "rtrstr.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
static const GUID GUID_DevClass_Net = {0x4D36E972,0xE325,0x11CE,{0xBF,0xC1,0x08,0x00,0x2B,0xE1,0x03,0x18}};
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: ConnectRegistry
|
|
//
|
|
// Connects to the registry on the specified machine
|
|
//----------------------------------------------------------------------------
|
|
|
|
TFSCORE_API(DWORD)
|
|
ConnectRegistry(
|
|
IN LPCTSTR pszMachine,
|
|
OUT HKEY* phkeyMachine
|
|
) {
|
|
|
|
//
|
|
// if no machine name was specified, connect to the local machine.
|
|
// otherwise, connect to the specified machine
|
|
//
|
|
|
|
DWORD dwErr = NO_ERROR;
|
|
|
|
if (IsLocalMachine(pszMachine))
|
|
{
|
|
*phkeyMachine = HKEY_LOCAL_MACHINE;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// Make the connection
|
|
//
|
|
|
|
dwErr = ::RegConnectRegistry(
|
|
(LPTSTR)pszMachine, HKEY_LOCAL_MACHINE, phkeyMachine
|
|
);
|
|
}
|
|
|
|
HrReportExit(HRESULT_FROM_WIN32(dwErr), TEXT("ConnectRegistry"));
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: DisconnectRegistry
|
|
//
|
|
// Disconnects the specified config-handle. The handle is assumed to have been
|
|
// acquired by calling 'ConnectRegistry'.
|
|
//----------------------------------------------------------------------------
|
|
|
|
TFSCORE_API(VOID)
|
|
DisconnectRegistry(
|
|
IN HKEY hkeyMachine
|
|
) {
|
|
|
|
if (hkeyMachine != HKEY_LOCAL_MACHINE)
|
|
{
|
|
::RegCloseKey(hkeyMachine);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
QueryRouterType
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) QueryRouterType(HKEY hkeyMachine, DWORD *pdwRouterType,
|
|
RouterVersionInfo *pVersion)
|
|
{
|
|
Assert(pdwRouterType);
|
|
Assert(hkeyMachine);
|
|
|
|
DWORD dwErr = ERROR_SUCCESS;
|
|
HKEY hkey = 0;
|
|
DWORD dwType;
|
|
DWORD dwRouterType;
|
|
DWORD dwSize;
|
|
RouterVersionInfo versionTemp;
|
|
LPCTSTR pszRouterTypeKey = NULL;
|
|
BOOL fFirstTry = TRUE;
|
|
|
|
// If the version structure is not passed in, we have to do it
|
|
// ourselves
|
|
// ----------------------------------------------------------------
|
|
if (pVersion == NULL)
|
|
{
|
|
dwErr = QueryRouterVersionInfo(hkeyMachine, &versionTemp);
|
|
if ( dwErr != ERROR_SUCCESS )
|
|
{
|
|
goto Error;
|
|
}
|
|
pVersion = &versionTemp;
|
|
}
|
|
|
|
// Windows NT Bug : 137200
|
|
// Need to get the router type from a different place depending
|
|
// on the version.
|
|
// ----------------------------------------------------------------
|
|
// if (pVersion->dwRouterVersion <= 4)
|
|
if (pVersion->dwOsBuildNo < RASMAN_PPP_KEY_LAST_VERSION)
|
|
pszRouterTypeKey = c_szRegKeyRasProtocols;
|
|
else
|
|
pszRouterTypeKey = c_szRegKeyRemoteAccessParameters;
|
|
|
|
|
|
|
|
// This is where we perform a retry
|
|
// ----------------------------------------------------------------
|
|
Retry:
|
|
|
|
// Cool, we have a machine registry entry, now get the
|
|
// path down to the routertype key
|
|
dwErr = RegOpenKeyEx(hkeyMachine, pszRouterTypeKey, 0, KEY_READ, &hkey);
|
|
if (dwErr)
|
|
goto Error;
|
|
|
|
// Ok, at this point we just need to get the RouterType value from
|
|
// the key
|
|
dwType = REG_DWORD;
|
|
dwSize = sizeof(dwRouterType);
|
|
dwErr = RegQueryValueEx(hkey, c_szRouterType, NULL,
|
|
&dwType,
|
|
(LPBYTE) &dwRouterType,
|
|
&dwSize);
|
|
if (dwErr)
|
|
{
|
|
// Need to retry (look at the RAS/protocols key), for NT5
|
|
if ((pVersion->dwRouterVersion >= 5) && fFirstTry)
|
|
{
|
|
dwErr = ERROR_SUCCESS;
|
|
fFirstTry = FALSE;
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
hkey = 0;
|
|
pszRouterTypeKey = c_szRegKeyRasProtocols;
|
|
goto Retry;
|
|
}
|
|
goto Error;
|
|
}
|
|
|
|
// Is this the right type?
|
|
if (dwType != REG_DWORD)
|
|
{
|
|
dwErr = ERROR_BADKEY;
|
|
goto Error;
|
|
}
|
|
|
|
// We have the right type, now return that value
|
|
*pdwRouterType = dwRouterType;
|
|
|
|
Error:
|
|
if (hkey)
|
|
RegCloseKey(hkey);
|
|
|
|
return HrReportExit(HRESULT_FROM_WIN32(dwErr), TEXT("QueryRouterType"));
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: LoadLinkageList
|
|
//
|
|
// Loads a list of strings with the adapters to which 'pszService' is bound;
|
|
// the list is built by examining the 'Linkage' and 'Disabled' subkeys
|
|
// of the service under HKLM\System\CurrentControlSet\Services.
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT LoadLinkageList(
|
|
LPCTSTR pszMachine,
|
|
HKEY hkeyMachine,
|
|
LPCTSTR pszService,
|
|
CStringList* pLinkageList)
|
|
{
|
|
Assert(hkeyMachine);
|
|
|
|
DWORD dwErr;
|
|
BYTE* pValue = NULL;
|
|
HKEY hkeyLinkage = NULL, hkeyDisabled = NULL;
|
|
|
|
if (!pszService || !lstrlen(pszService) || !pLinkageList) {
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
|
|
do {
|
|
|
|
TCHAR* psz;
|
|
CString skey;
|
|
DWORD dwType, dwSize;
|
|
BOOL fNt4;
|
|
|
|
|
|
dwErr = IsNT4Machine(hkeyMachine, &fNt4);
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
//$NT5 : where is the registry key? same as NT4
|
|
skey = c_szSystemCCSServices;
|
|
skey += TEXT('\\');
|
|
skey += pszService;
|
|
skey += TEXT('\\');
|
|
skey += c_szLinkage;
|
|
|
|
//
|
|
// Open the service's 'Linkage' key
|
|
//
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
hkeyMachine, skey, 0, KEY_READ, &hkeyLinkage
|
|
);
|
|
if (dwErr != NO_ERROR) {
|
|
|
|
if (dwErr == ERROR_FILE_NOT_FOUND) { dwErr = NO_ERROR; }
|
|
CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("QueryLinkageList"));
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Retrieve the size of the 'Bind' value
|
|
//
|
|
|
|
dwErr = RegQueryValueEx(
|
|
hkeyLinkage, c_szBind, NULL, &dwType, NULL, &dwSize
|
|
);
|
|
if (dwErr != NO_ERROR) {
|
|
|
|
if (dwErr == ERROR_FILE_NOT_FOUND) { dwErr = NO_ERROR; }
|
|
|
|
CheckRegQueryValueError(dwErr, (LPCTSTR) skey, c_szBind, _T("QueryLinkageList"));
|
|
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the 'Bind' value
|
|
//
|
|
|
|
pValue = new BYTE[dwSize + sizeof(TCHAR)];
|
|
|
|
if (!pValue) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
|
|
|
|
::ZeroMemory(pValue, dwSize + sizeof(TCHAR));
|
|
|
|
|
|
//
|
|
// Read the 'Bind' value
|
|
//
|
|
|
|
dwErr = RegQueryValueEx(
|
|
hkeyLinkage, c_szBind, NULL, &dwType, pValue, &dwSize
|
|
);
|
|
CheckRegQueryValueError(dwErr, (LPCTSTR) skey, c_szBind, _T("QueryLinkageList"));
|
|
|
|
if (dwErr != NO_ERROR) { break; }
|
|
|
|
|
|
//
|
|
// Convert the 'Bind' multi-string to a list of strings,
|
|
// leaving out the string "\Device\" which is the prefix
|
|
// for all the bindings.
|
|
//
|
|
|
|
for (psz = (TCHAR*)pValue; *psz; psz += lstrlen(psz) + 1) {
|
|
|
|
pLinkageList->AddTail(psz + 8);
|
|
}
|
|
|
|
delete [] pValue; pValue = NULL;
|
|
|
|
|
|
//
|
|
// Now open the service's 'Disabled' key.
|
|
//
|
|
|
|
dwErr = RegOpenKeyEx(
|
|
hkeyLinkage, c_szDisabled, 0, KEY_READ, &hkeyDisabled
|
|
);
|
|
if (dwErr != NO_ERROR) {
|
|
|
|
if (dwErr == ERROR_FILE_NOT_FOUND) { dwErr = NO_ERROR; }
|
|
CheckRegOpenError(dwErr, c_szDisabled, _T("QueryLinkageList"));
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Retrieve the size of the 'Bind' value
|
|
//
|
|
|
|
dwErr = RegQueryValueEx(
|
|
hkeyDisabled, c_szBind, NULL, &dwType, NULL, &dwSize
|
|
);
|
|
if (dwErr != NO_ERROR) {
|
|
|
|
if (dwErr == ERROR_FILE_NOT_FOUND) { dwErr = NO_ERROR; }
|
|
CheckRegQueryValueError(dwErr, c_szDisabled, c_szBind, _T("QueryLinkageList"));
|
|
break;
|
|
}
|
|
|
|
|
|
//
|
|
// Allocate space for the 'Bind' value
|
|
//
|
|
|
|
pValue = new BYTE[dwSize + sizeof(TCHAR)];
|
|
|
|
if (!pValue) { dwErr = ERROR_NOT_ENOUGH_MEMORY; break; }
|
|
|
|
::ZeroMemory(pValue, dwSize + sizeof(TCHAR));
|
|
|
|
|
|
//
|
|
// Read the 'Bind' value
|
|
//
|
|
|
|
dwErr = RegQueryValueEx(
|
|
hkeyDisabled, c_szBind, NULL, &dwType, pValue, &dwSize
|
|
);
|
|
CheckRegQueryValueError(dwErr, c_szDisabled, c_szBind, _T("QueryLinkageList"));
|
|
|
|
if (dwErr != NO_ERROR) { break; }
|
|
|
|
|
|
//
|
|
// Each device in the 'Bind' mulit-string is disabled for the service,
|
|
// so we will now remove such devices from the string-list built
|
|
// from the 'Linkage' key.
|
|
//
|
|
|
|
for (psz = (TCHAR*)pValue; *psz; psz += lstrlen(psz) + 1) {
|
|
|
|
POSITION pos = pLinkageList->Find(psz);
|
|
|
|
if (pos) { pLinkageList->RemoveAt(pos); }
|
|
}
|
|
|
|
|
|
} while(FALSE);
|
|
|
|
if (pValue) { delete [] pValue; }
|
|
|
|
if (hkeyDisabled) { ::RegCloseKey(hkeyDisabled); }
|
|
|
|
if (hkeyLinkage) { ::RegCloseKey(hkeyLinkage); }
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IsNT4Machine
|
|
-
|
|
Author: KennT, WeiJiang
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(DWORD) GetNTVersion(HKEY hkeyMachine, DWORD *pdwMajor, DWORD *pdwMinor, DWORD* pdwCurrentBuildNumber)
|
|
{
|
|
// Look at the HKLM\Software\Microsoft\Windows NT\CurrentVersion
|
|
// CurrentVersion = REG_SZ "4.0"
|
|
CString skey;
|
|
DWORD dwErr;
|
|
TCHAR szVersion[64];
|
|
TCHAR szCurrentBuildNumber[64];
|
|
RegKey regkey;
|
|
CString strVersion;
|
|
CString strMajor;
|
|
CString strMinor;
|
|
|
|
|
|
ASSERT(pdwMajor);
|
|
ASSERT(pdwMinor);
|
|
ASSERT(pdwCurrentBuildNumber);
|
|
|
|
skey = c_szSoftware;
|
|
skey += TEXT('\\');
|
|
skey += c_szMicrosoft;
|
|
skey += TEXT('\\');
|
|
skey += c_szWindowsNT;
|
|
skey += TEXT('\\');
|
|
skey += c_szCurrentVersion;
|
|
|
|
dwErr = regkey.Open(hkeyMachine, (LPCTSTR) skey, KEY_READ);
|
|
CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("GetNTVersion"));
|
|
if (dwErr != ERROR_SUCCESS)
|
|
return dwErr;
|
|
|
|
// Ok, now try to get the current version value
|
|
dwErr = regkey.QueryValue( c_szCurrentVersion, szVersion,
|
|
sizeof(szVersion),
|
|
FALSE);
|
|
CheckRegQueryValueError(dwErr, (LPCTSTR) skey, c_szCurrentVersion,
|
|
_T("GetNTVersion"));
|
|
if (dwErr != ERROR_SUCCESS)
|
|
goto Err;
|
|
|
|
// Ok, now try to get the current build number value
|
|
dwErr = regkey.QueryValue( c_szCurrentBuildNumber, szCurrentBuildNumber,
|
|
sizeof(szCurrentBuildNumber),
|
|
FALSE);
|
|
CheckRegQueryValueError(dwErr, (LPCTSTR) skey, c_szCurrentBuildNumber,
|
|
_T("GetNTVersion"));
|
|
|
|
if (dwErr != ERROR_SUCCESS)
|
|
goto Err;
|
|
|
|
strVersion = szVersion;
|
|
strMajor = strVersion.Left(strVersion.Find(_T('.')));
|
|
strMinor = strVersion.Mid(strVersion.Find(_T('.')) + 1);
|
|
|
|
if(pdwMajor)
|
|
*pdwMajor = _ttol(strMajor);
|
|
|
|
if(pdwMinor)
|
|
*pdwMinor = _ttol(strMinor);
|
|
|
|
if(pdwCurrentBuildNumber)
|
|
*pdwCurrentBuildNumber = _ttol(szCurrentBuildNumber);
|
|
|
|
Err:
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
IsNT4Machine
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(DWORD) IsNT4Machine(HKEY hkeyMachine, BOOL *pfNt4)
|
|
{
|
|
// Look at the HKLM\Software\Microsoft\Windows NT\CurrentVersion
|
|
// CurrentVersion = REG_SZ "4.0"
|
|
DWORD dwMajor = 0;
|
|
DWORD dwErr = 0;
|
|
|
|
dwErr = GetNTVersion(hkeyMachine, &dwMajor, NULL, NULL);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
*pfNt4 = (dwMajor == 4);
|
|
}
|
|
|
|
return dwErr;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
// Function: FindRmSoftwareKey
|
|
//
|
|
// Finds the key for a router-manager in the Software section of the registry.
|
|
//----------------------------------------------------------------------------
|
|
|
|
HRESULT FindRmSoftwareKey(
|
|
HKEY hkeyMachine,
|
|
DWORD dwTransportId,
|
|
HKEY* phkrm,
|
|
LPTSTR* lplpszRm
|
|
)
|
|
{
|
|
Assert(phkrm);
|
|
|
|
DWORD dwErr;
|
|
RegKey regkey;
|
|
HRESULT hr = hrOK;
|
|
CString stKey;
|
|
RegKeyIterator regkeyIter;
|
|
HRESULT hrIter;
|
|
RegKey regkeyRM;
|
|
DWORD dwProtocolId;
|
|
BOOL bFound = FALSE;
|
|
|
|
//
|
|
// open the key HKLM\Software\Microsoft\Router\RouterManagers
|
|
//
|
|
|
|
CString skey(c_szSoftware);
|
|
|
|
skey += TEXT('\\');
|
|
skey += c_szMicrosoft;
|
|
skey += TEXT('\\');
|
|
skey += c_szRouter;
|
|
skey += TEXT('\\');
|
|
skey += c_szCurrentVersion;
|
|
skey += TEXT('\\');
|
|
skey += c_szRouterManagers;
|
|
|
|
dwErr = regkey.Open(hkeyMachine, (LPCTSTR) skey, KEY_READ);
|
|
CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("QueryRmSoftwareKey"));
|
|
CWRg(dwErr);
|
|
|
|
if (lplpszRm)
|
|
*lplpszRm = NULL;
|
|
*phkrm = 0;
|
|
|
|
//
|
|
// Enumerate its subkeys looking for one which has a ProtocolId value
|
|
// equal to 'dwTransportId';
|
|
//
|
|
|
|
CWRg( regkeyIter.Init(®key) );
|
|
|
|
hrIter = regkeyIter.Next(&stKey);
|
|
|
|
for (; hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
|
|
{
|
|
//
|
|
// open the key
|
|
//
|
|
dwErr = regkeyRM.Open(regkey, stKey, KEY_READ);
|
|
CheckRegOpenError(dwErr, stKey, _T("QueryRmSoftwareKey"));
|
|
if (dwErr != ERROR_SUCCESS) { continue; }
|
|
|
|
//
|
|
// try to read the ProtocolId value
|
|
//
|
|
dwErr = regkeyRM.QueryValue(c_szProtocolId, dwProtocolId);
|
|
CheckRegQueryValueError(dwErr, stKey, c_szProtocolId, _T("QueryRmSoftwareKey"));
|
|
|
|
//
|
|
// Break if this is the transport we're looking for,
|
|
// otherwise close the key and continue
|
|
//
|
|
if ((dwErr == ERROR_SUCCESS) && (dwProtocolId == dwTransportId))
|
|
break;
|
|
|
|
regkeyRM.Close();
|
|
}
|
|
|
|
if (hrIter == hrOK)
|
|
{
|
|
//
|
|
// The transport was found, so save its key-name and key
|
|
//
|
|
Assert(((HKEY)regkeyRM) != 0);
|
|
if (lplpszRm)
|
|
*lplpszRm = StrDup((LPCTSTR) stKey);
|
|
bFound = TRUE;
|
|
*phkrm = regkeyRM.Detach();
|
|
}
|
|
|
|
|
|
Error:
|
|
|
|
if (FHrSucceeded(hr) && !bFound)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
|
|
#ifdef _DEBUG
|
|
void CheckRegOpenErrorEx(DWORD dwError, LPCTSTR pszSubKey,
|
|
LPCTSTR pszDesc, LPCTSTR pszFile, int iLineNo)
|
|
{
|
|
if (dwError)
|
|
{
|
|
CString st;
|
|
|
|
st.Format(_T("RegOpenEx failed(%08lx)\nfile: %s\nline: %d\nDesc: %s\nkey: %s"),
|
|
dwError, pszFile, iLineNo,
|
|
pszDesc, pszSubKey);
|
|
if (AfxMessageBox(st, MB_OKCANCEL) == IDCANCEL)
|
|
{
|
|
DebugBreak();
|
|
}
|
|
}
|
|
}
|
|
|
|
void CheckRegQueryValueErrorEx(DWORD dwError, LPCTSTR pszSubKey,
|
|
LPCTSTR pszValue, LPCTSTR pszDesc,
|
|
LPCTSTR pszFile, int iLineNo)
|
|
{
|
|
if (dwError)
|
|
{
|
|
CString st;
|
|
|
|
st.Format(_T("RegQueryValue failed(%08lx)\nfile: %s\nline: %d\ndesc: %s\nkey: %s\nvalue: %s"),
|
|
dwError, pszFile, iLineNo, pszDesc, pszSubKey, pszValue);
|
|
if (AfxMessageBox(st, MB_OKCANCEL) == IDCANCEL)
|
|
{
|
|
DebugBreak();
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
SetupFindInterfaceTitle
|
|
-
|
|
This function retrieves the title of the given interface.
|
|
The argument 'LpszIf' should contain the ID of the interface,
|
|
for instance "EPRO1".
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP SetupFindInterfaceTitle(LPCTSTR pszMachine,
|
|
LPCTSTR pszInterface,
|
|
LPTSTR *ppszTitle)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
CString stMachine;
|
|
HDEVINFO hDevInfo = INVALID_HANDLE_VALUE;
|
|
HKEY hkMachine = NULL;
|
|
HKEY hkDevice= NULL;
|
|
CString stPnpInstanceId;
|
|
RegKey rkNet;
|
|
RegKey rkNetcard;
|
|
RegKey rkDevice;
|
|
RegKey rkConnection;
|
|
CString stBuffer, stPath;
|
|
CString stConnection;
|
|
TCHAR szClassGuid[128];
|
|
DWORD dwAction;
|
|
DWORD dwErr;
|
|
SP_DEVINFO_DATA DevInfo;
|
|
|
|
stMachine = pszMachine;
|
|
if (IsLocalMachine(stMachine))
|
|
{
|
|
hDevInfo = SetupDiCreateDeviceInfoList(
|
|
(LPGUID) &GUID_DevClass_Net,
|
|
NULL);
|
|
}
|
|
else
|
|
{
|
|
// Append on the "\\\\" if needed
|
|
if (StrniCmp((LPCTSTR) stMachine, _T("\\\\"), 2) != 0)
|
|
{
|
|
stMachine = _T("\\\\");
|
|
stMachine += pszMachine;
|
|
}
|
|
|
|
hDevInfo = SetupDiCreateDeviceInfoListEx(
|
|
(LPGUID) &GUID_DevClass_Net,
|
|
NULL,
|
|
(LPCTSTR) stMachine,
|
|
0);
|
|
}
|
|
|
|
// Get hkMachine from system
|
|
// ----------------------------------------------------------------
|
|
CWRg( ConnectRegistry( (LPCTSTR) stMachine, &hkMachine) );
|
|
|
|
|
|
// Get the PnpInstanceID
|
|
// ----------------------------------------------------------------
|
|
CWRg( rkNet.Open(hkMachine, c_szNetworkCardsNT5Key, KEY_READ) );
|
|
|
|
CWRg( rkNetcard.Open(rkNet, pszInterface, KEY_READ) );
|
|
|
|
dwErr = rkNetcard.QueryValue(c_szPnpInstanceID, stPnpInstanceId);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
{
|
|
RegKey rkConnection;
|
|
|
|
// Need to open another key to get this info.
|
|
CWRg( rkConnection.Open(rkNetcard, c_szRegKeyConnection, KEY_READ) );
|
|
|
|
CWRg( rkConnection.QueryValue(c_szPnpInstanceID, stPnpInstanceId) );
|
|
}
|
|
|
|
|
|
// Get hkDevice from SetupDiOpenDevRegKey
|
|
// Now get the info for this device
|
|
// ----------------------------------------------------------------
|
|
::ZeroMemory(&DevInfo, sizeof(DevInfo));
|
|
DevInfo.cbSize = sizeof(DevInfo);
|
|
|
|
if (!SetupDiOpenDeviceInfo(hDevInfo,
|
|
(LPCTSTR) stPnpInstanceId,
|
|
NULL,
|
|
0,
|
|
&DevInfo))
|
|
{
|
|
CWRg( GetLastError() );
|
|
}
|
|
|
|
|
|
// Now that we have the info, get the reg key
|
|
// ----------------------------------------------------------------
|
|
hkDevice = SetupDiOpenDevRegKey(hDevInfo,
|
|
&DevInfo,
|
|
DICS_FLAG_GLOBAL,
|
|
0,
|
|
DIREG_DRV,
|
|
KEY_READ);
|
|
if ((hkDevice == NULL) || (hkDevice == INVALID_HANDLE_VALUE))
|
|
{
|
|
CWRg( GetLastError() );
|
|
}
|
|
|
|
// Attach so that it will get freed up
|
|
// ----------------------------------------------------------------
|
|
rkDevice.Attach( hkDevice );
|
|
|
|
|
|
// Read in the netcfg instance
|
|
// ----------------------------------------------------------------
|
|
CWRg( rkDevice.QueryValue(c_szRegValNetCfgInstanceId, stBuffer) );
|
|
|
|
|
|
// Generate path in registry for lookup
|
|
StringFromGUID2(GUID_DevClass_Net,
|
|
szClassGuid,
|
|
DimensionOf(szClassGuid));
|
|
stPath.Format(_T("%s\\%s\\%s\\Connection"),
|
|
c_szRegKeyComponentClasses,
|
|
szClassGuid,
|
|
stBuffer);
|
|
|
|
// Open the key
|
|
CWRg( rkConnection.Open(hkMachine, stPath, KEY_READ) );
|
|
|
|
// Read in and store the connections name
|
|
CWRg( rkConnection.QueryValue(c_szRegValName, stConnection) );
|
|
|
|
*ppszTitle = StrDup((LPCTSTR) stConnection);
|
|
|
|
|
|
Error:
|
|
|
|
if (hDevInfo != INVALID_HANDLE_VALUE)
|
|
SetupDiDestroyDeviceInfoList(hDevInfo);
|
|
|
|
if (hkMachine)
|
|
DisconnectRegistry( hkMachine );
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RegFindInterfaceTitle
|
|
-
|
|
This function retrieves the title of the given interface.
|
|
The argument 'LpszIf' should contain the ID of the interface,
|
|
for instance "EPRO1".
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RegFindInterfaceTitle(LPCTSTR pszMachine,
|
|
LPCTSTR pszInterface,
|
|
LPTSTR *ppszTitle)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
DWORD dwErr;
|
|
HKEY hkeyMachine = NULL;
|
|
RegKey regkey;
|
|
RegKeyIterator regkeyIter;
|
|
HRESULT hrIter;
|
|
CString stKey;
|
|
RegKey regkeyCard;
|
|
CString stServiceName;
|
|
CString stTitle;
|
|
BOOL fNT4;
|
|
LPCTSTR pszKey;
|
|
CNetcardRegistryHelper ncreghelp;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
|
|
//
|
|
// connect to the registry
|
|
//
|
|
CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
|
|
|
|
CWRg( IsNT4Machine(hkeyMachine, &fNT4) );
|
|
|
|
//
|
|
// open HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards
|
|
//
|
|
pszKey = fNT4 ? c_szNetworkCardsKey : c_szNetworkCardsNT5Key;
|
|
CWRg( regkey.Open(hkeyMachine, pszKey, KEY_READ) );
|
|
|
|
//
|
|
// enumerate the subkeys, and for each key,
|
|
// see if it's the one we want
|
|
//
|
|
CWRg( regkeyIter.Init(®key) );
|
|
|
|
hrIter = regkeyIter.Next(&stKey);
|
|
|
|
for (; hrIter == hrOK; hrIter = regkeyIter.Next(&stKey))
|
|
{
|
|
hr = hrOK;
|
|
|
|
//
|
|
// now open the key
|
|
//
|
|
regkeyCard.Close();
|
|
dwErr = regkeyCard.Open(regkey, stKey, KEY_READ);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
continue;
|
|
|
|
ncreghelp.Initialize(fNT4, regkeyCard, stKey,
|
|
pszMachine);
|
|
|
|
//
|
|
// read the ServiceName
|
|
//
|
|
|
|
//$NT5: the service name is not in the same format as NT4
|
|
// this will need to be done differently.
|
|
if (fNT4)
|
|
{
|
|
ncreghelp.ReadServiceName();
|
|
if (dwErr != ERROR_SUCCESS)
|
|
continue;
|
|
stServiceName = ncreghelp.GetServiceName();
|
|
}
|
|
else
|
|
stServiceName = pszKey;
|
|
|
|
//
|
|
// see if it's the one we're looking for
|
|
//
|
|
if (StriCmp(pszInterface, (LPCTSTR) stServiceName))
|
|
{
|
|
dwErr = ERROR_INVALID_HANDLE;
|
|
continue;
|
|
}
|
|
|
|
//
|
|
// this is the one; read the title
|
|
//
|
|
dwErr = ncreghelp.ReadTitle();
|
|
if (dwErr != NO_ERROR)
|
|
break;
|
|
|
|
stTitle = (LPCTSTR) ncreghelp.GetTitle();
|
|
|
|
*ppszTitle = StrDup((LPCTSTR) stTitle);
|
|
}
|
|
|
|
|
|
if (dwErr)
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
if (hkeyMachine)
|
|
DisconnectRegistry(hkeyMachine);
|
|
return hr;
|
|
}
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
RegFindRtrMgrTitle
|
|
-
|
|
This function retrieves the title of the given router-manager.
|
|
The argument 'dwTransportId' should contain the ID of the router-manager,
|
|
for instance PID_IP.
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
STDMETHODIMP RegFindRtrMgrTitle(LPCTSTR pszMachine,
|
|
DWORD dwTransportId,
|
|
LPTSTR *ppszTitle)
|
|
{
|
|
HRESULT hr = hrOK;
|
|
HKEY hkey, hkeyMachine = 0;
|
|
RegKey regkey;
|
|
CString stValue;
|
|
|
|
COM_PROTECT_TRY
|
|
{
|
|
//
|
|
// connect to the registry
|
|
//
|
|
CWRg( ConnectRegistry(pszMachine, &hkeyMachine) );
|
|
|
|
//
|
|
// open the key for the router-manager
|
|
// under HKLM\Software\Microsoft\Router\RouterManagers
|
|
//
|
|
CORg( FindRmSoftwareKey(hkeyMachine, dwTransportId, &hkey, NULL) );
|
|
regkey.Attach(hkey);
|
|
|
|
//
|
|
// Now find the "Title" value
|
|
//
|
|
CWRg( regkey.QueryValue( c_szTitle, stValue ) );
|
|
|
|
// Copy the output data
|
|
*ppszTitle = StrDup((LPCTSTR) stValue);
|
|
|
|
COM_PROTECT_ERROR_LABEL;
|
|
}
|
|
COM_PROTECT_CATCH;
|
|
|
|
if (hkeyMachine)
|
|
DisconnectRegistry(hkeyMachine);
|
|
return hr;
|
|
}
|
|
|
|
|
|
/*!--------------------------------------------------------------------------
|
|
QueryRouterVersionInfo
|
|
-
|
|
Author: KennT
|
|
---------------------------------------------------------------------------*/
|
|
TFSCORE_API(HRESULT) QueryRouterVersionInfo(HKEY hkeyMachine,
|
|
RouterVersionInfo *pVerInfo)
|
|
{
|
|
// Look at the HKLM\Software\Microsoft\Windows NT\CurrentVersion
|
|
// CurrentVersion = REG_SZ "4.0"
|
|
CString skey;
|
|
DWORD dwErr;
|
|
TCHAR szData[64];
|
|
RegKey regkey;
|
|
BOOL fNt4;
|
|
DWORD dwMajorVer, dwMinorVer, dwBuildNumber;
|
|
DWORD dwConfigured;
|
|
DWORD dwSPVer = 0;
|
|
DWORD dwOsFlags = 0;
|
|
|
|
skey = c_szSoftware;
|
|
skey += TEXT('\\');
|
|
skey += c_szMicrosoft;
|
|
skey += TEXT('\\');
|
|
skey += c_szWindowsNT;
|
|
skey += TEXT('\\');
|
|
skey += c_szCurrentVersion;
|
|
|
|
Assert(hkeyMachine != NULL);
|
|
Assert(hkeyMachine != INVALID_HANDLE_VALUE);
|
|
|
|
dwErr = regkey.Open(hkeyMachine, (LPCTSTR) skey, KEY_READ);
|
|
CheckRegOpenError(dwErr, (LPCTSTR) skey, _T("IsNT4Machine"));
|
|
if (dwErr != ERROR_SUCCESS)
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
|
|
// Ok, now try to get the current version value
|
|
dwErr = regkey.QueryValue( c_szCurrentVersion, szData,
|
|
sizeof(szData),
|
|
FALSE);
|
|
CheckRegQueryValueError(dwErr, (LPCTSTR) skey, c_szCurrentVersion,
|
|
_T("QueryRouterVersionInfo"));
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
int nPos;
|
|
int nLength;
|
|
CString stData;
|
|
|
|
stData = szData;
|
|
|
|
nPos = stData.Find(_T('.'));
|
|
nLength = stData.GetLength();
|
|
|
|
// This assumes that
|
|
// CurrentVersion : REG_SZ : Major.Minor.XX.XX
|
|
// ------------------------------------------------------------
|
|
|
|
// Pick out the major version from the string
|
|
// ------------------------------------------------------------
|
|
dwMajorVer = _ttoi(stData.Left(nPos));
|
|
|
|
// Pick out the minor version
|
|
// ------------------------------------------------------------
|
|
dwMinorVer = _ttoi(stData.Right(nLength - nPos - 1));
|
|
}
|
|
|
|
|
|
// Get the build number
|
|
// ----------------------------------------------------------------
|
|
dwErr = regkey.QueryValue( c_szCurrentBuildNumber, szData,
|
|
sizeof(szData),
|
|
FALSE);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
dwBuildNumber = _ttoi(szData);
|
|
|
|
|
|
// If this is an NT4 machine, look for the Software\Microsoft\Router
|
|
// registry key. If that doesn't exist, then this is a
|
|
// non-Steelhead router.
|
|
// ----------------------------------------------------------------
|
|
if ((dwErr == ERROR_SUCCESS) && (dwMajorVer < 5))
|
|
{
|
|
RegKey regkeyRouter;
|
|
dwErr = regkeyRouter.Open(hkeyMachine, c_szRegKeyRouter, KEY_READ);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
dwOsFlags |= RouterSnapin_RASOnly;
|
|
|
|
// Ignore the return code
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
|
|
// Now get the SP version
|
|
// ----------------------------------------------------------------
|
|
dwErr = regkey.QueryValue( c_szCSDVersion, szData,
|
|
sizeof(szData),
|
|
FALSE);
|
|
if (dwErr == ERROR_SUCCESS)
|
|
dwSPVer = _ttoi(szData);
|
|
dwErr = ERROR_SUCCESS; // this could fail, so ignore return code
|
|
|
|
// Look at the router is configured flag
|
|
// ----------------------------------------------------------------
|
|
regkey.Close();
|
|
if (ERROR_SUCCESS == regkey.Open(hkeyMachine,c_szRemoteAccessKey) )
|
|
{
|
|
dwErr = regkey.QueryValue( c_szRtrConfigured, dwConfigured);
|
|
if (dwErr != ERROR_SUCCESS)
|
|
dwConfigured = FALSE;
|
|
|
|
// Ignore the return code
|
|
dwErr = ERROR_SUCCESS;
|
|
}
|
|
|
|
if (dwErr == ERROR_SUCCESS)
|
|
{
|
|
pVerInfo->dwRouterVersion = dwMajorVer;
|
|
pVerInfo->dwOsMajorVersion = dwMajorVer;
|
|
pVerInfo->dwOsMinorVersion = dwMinorVer;
|
|
pVerInfo->dwOsServicePack = dwSPVer;
|
|
pVerInfo->dwOsFlags |= (1 | dwOsFlags);
|
|
pVerInfo->dwRouterFlags = dwConfigured ? RouterSnapin_IsConfigured : 0;
|
|
|
|
// If this is NT4, then the default is the router is configured
|
|
if (dwMajorVer <= 4)
|
|
pVerInfo->dwRouterFlags |= RouterSnapin_IsConfigured;
|
|
|
|
pVerInfo->dwOsBuildNo = dwBuildNumber;
|
|
}
|
|
|
|
return HRESULT_FROM_WIN32(dwErr);
|
|
}
|
|
|