|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1999.
//
// File: L A N A M A P . C P P
//
// Contents: NetBios Lana map routines.
//
// Notes:
//
// Author: billbe 17 Feb 1999
//
//----------------------------------------------------------------------------
#include <pch.h>
#pragma hdrstop
#include "lanamap.h"
#include "nceh.h"
#include "ncerror.h"
#include "ncreg.h"
#include "ncsetup.h"
#include "netsetup.h"
#include "persist.h"
const WCHAR c_szRegKeyNetBiosLinkage[] = L"System\\CurrentControlSet\\Services\\NetBios\\Linkage";
const WCHAR c_szRegKeyNetBiosParameters[] = L"System\\CurrentControlSet\\Services\\NetBIOS\\Parameters";
const WCHAR c_szRegValueLanaMap[] = L"LanaMap"; const WCHAR c_szRegValueMaxLana[] = L"MaxLana";
#if DBG
VOID DbgVerifyBindPathString (PCWSTR pszBindPath); #else
VOID DbgVerifyBindPathString (PCWSTR /*pszBindPath*/) {} #endif
typedef vector<const GUID*> VECTOR_OF_GUIDS;
struct LANA_BIND_PATH { VECTOR_OF_GUIDS GuidsOfComponentsOnPath; BYTE LanaNumber; };
VOID GetFirstComponentFromBindPath ( IN PCWSTR pszBindPath, OUT PCWSTR* ppszComponentStart, OUT DWORD* pcchComponent) { PCWSTR pszComponentEnd; PCWSTR pszComponentStart;
Assert (pszBindPath); Assert (ppszComponentStart); Assert (pcchComponent);
*pcchComponent = 0;
// The Bind path is of the form \Device\<component>_<component>_<etc.>
//
pszComponentEnd = wcschr (pszBindPath, L'_'); if (!pszComponentEnd) { // There is no underscore so set the end pointer
// to the end of the string.
pszComponentEnd = pszBindPath + wcslen (pszBindPath); }
for (pszComponentStart = pszComponentEnd; pszComponentStart != pszBindPath; pszComponentStart--) { // Backup from the end until we get to the slash.
// If we don't find a slash, the loop will stop when
// we hit the beginning.
//
if (L'\\' == *pszComponentStart) { // We hit the slash. The Component start is one character
// past that.
pszComponentStart++; break; } }
*ppszComponentStart = pszComponentStart; *pcchComponent = pszComponentEnd - pszComponentStart; }
VOID CLanaMap::Dump ( OUT CWideString* pstr) const { Assert (this); Assert (pstr);
WCHAR pszBuf[1024]; pstr->erase();
const CLanaEntry* pEntry;
for (pEntry = begin(); pEntry != end(); pEntry++) { swprintf (pszBuf, L"Lana: %3d Export: %d Path: %s\n", pEntry->RegLanaEntry.LanaNumber, pEntry->RegLanaEntry.Exported, pEntry->pszBindPath);
pstr->append (pszBuf); } }
HRESULT CLanaMap::HrLoadLanaMap() { HRESULT hr; HKEY hkey;
// The lana map is stored in Netbios's linkage key.
//
hr = HrRegOpenKeyEx (HKEY_LOCAL_MACHINE, c_szRegKeyNetBiosLinkage, KEY_READ, &hkey);
if (S_OK == hr) { REG_LANA_ENTRY* pRegEntries; DWORD cbLanaEntries;
// Read in the lana map binary blob.
hr = HrRegQueryBinaryWithAlloc (hkey, c_szRegValueLanaMap, (BYTE**)&pRegEntries, &cbLanaEntries);
if (S_OK == hr) { DWORD cEntries = cbLanaEntries / sizeof (REG_LANA_ENTRY);
PWSTR pmszBindPaths;
// Grab the bind paths for NetBios so we can match them
// up with the lana map.
hr = HrRegQueryMultiSzWithAlloc (hkey, L"Bind", &pmszBindPaths);
if (S_OK == hr) { PCWSTR pszScan; DWORD cPaths; for (pszScan = pmszBindPaths, cPaths = 0; *pszScan; pszScan += wcslen(pszScan) + 1) { ++cPaths; }
m_pszBindPathsBuffer = pmszBindPaths;
hr = HrReserveRoomForEntries (cPaths);
if (S_OK == hr) { DWORD dw = 0; CLanaEntry Entry;
for (pszScan = pmszBindPaths; *pszScan; pszScan += wcslen(pszScan) + 1) { Entry.pszBindPath = pszScan;
if (dw < cEntries) { Entry.RegLanaEntry.LanaNumber = pRegEntries[dw].LanaNumber; Entry.RegLanaEntry.Exported = pRegEntries[dw].Exported; } else { // We have more bind paths but no more
// lana map entries to correlate.
// Now we assign available lanas.
//
BYTE* location = find (m_LanasInUse, m_LanasInUse + MAX_LANA, 0); if (location != m_LanasInUse + MAX_LANA) { Entry.RegLanaEntry.LanaNumber = location - m_LanasInUse; Entry.RegLanaEntry.Exported = 1; } }
// Mark this Lana as taken.
m_LanasInUse[Entry.RegLanaEntry.LanaNumber] = 1;
hr = HrAppendEntry (&Entry);
if (S_OK != hr) { break; }
dw++; } }
} MemFree (pRegEntries); }
// If lana map or bind is not there, it is okay since we will be
// recreating the info.
//
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK; }
RegCloseKey (hkey); } else { // If the linkage has not been created yet, it is okay since it will
// be creating after the lanamap is written out. This occurs when
// NetBios is first installed.
//
if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr) { hr = S_OK; } }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaMap::HrLoadLanaMap"); return hr; }
#if DBG
VOID DbgVerifyBindPathString ( PCWSTR pszBindPath) { const WCHAR c_szDevice[] = L"\\Device\\"; Assert (pszBindPath); Assert (0 == _wcsnicmp (pszBindPath, c_szDevice, celems(c_szDevice)-1)); } #endif // DBG
BOOL FBindPathContainsMultipleInterface ( IN const CComponentList& Components, IN PCWSTR pszBindPath) { BOOL fContainsMultipleInterface = FALSE; PCWSTR pszLastDevice = wcsrchr (pszBindPath, L'{');
if (pszLastDevice) { GUID Guid; if (S_OK == IIDFromString ((PWSTR)pszLastDevice, &Guid)) { // If this is a multiple interface, it will not exist
// as a component.
//
CComponent* pComponent;
pComponent = Components. PFindComponentByInstanceGuid (&Guid);
if (!pComponent) { // This means the path contains a multiple interface.
fContainsMultipleInterface = TRUE; } } } return fContainsMultipleInterface; }
HRESULT CLanaMap::HrAppendEntry ( IN CLanaEntry* pEntry) { HRESULT hr;
Assert (pEntry); Assert (pEntry->pszBindPath && *(pEntry->pszBindPath));
DbgVerifyBindPathString (pEntry->pszBindPath);
NC_TRY { push_back (*pEntry); hr = S_OK; } NC_CATCH_ALL { hr = E_OUTOFMEMORY; }
if (S_OK == hr) { // Update out lanas in use map.
m_LanasInUse[pEntry->RegLanaEntry.LanaNumber] = 1; }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaMap::HrAppendLanaEntry"); return hr; }
HRESULT CLanaMap::HrCreateRegistryMap() { HRESULT hr;
CLanaEntry* pEntry;
if (m_RegistryLanaMap.CountOfBytesUsed()) { m_RegistryLanaMap.Clear(); }
hr = m_RegistryLanaMap.HrReserveBytes ( CountEntries() * sizeof (REG_LANA_ENTRY));
if (S_OK == hr) { for (pEntry = begin(); pEntry != end(); pEntry++) { hr = m_RegistryLanaMap.HrCopyBytes ((BYTE*)&pEntry->RegLanaEntry, sizeof (REG_LANA_ENTRY)); } }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaEntry::HrCreateRegistryMap"); return hr; }
HRESULT CLanaMap::HrReserveRoomForEntries ( IN UINT cEntries) { HRESULT hr;
NC_TRY { reserve (cEntries); hr = S_OK; } NC_CATCH_ALL { hr = E_OUTOFMEMORY; }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaMap::HrReserveRoomForEntries"); return hr; }
BYTE CLanaMap::GetExportValue ( IN const CComponentList& Components, IN PCWSTR pszBindPath) { const WCHAR c_szNdisWanNbfIn[] = L"NdisWanNbfIn{";
BYTE Exported = 1; PCWSTR pszLastDevice;
Assert (pszBindPath && *pszBindPath);
// Get the last "device" on the bind path.
// If it matches NbfIn, we don't export.
//
pszLastDevice = wcsrchr (pszBindPath, L'_'); if (!pszLastDevice) { pszLastDevice = wcsrchr (pszBindPath, L'\\'); if (!pszLastDevice) { pszLastDevice = pszBindPath; } }
if (pszLastDevice != pszBindPath) { pszLastDevice++; }
if (0 == _wcsnicmp (pszLastDevice, c_szNdisWanNbfIn, wcslen (c_szNdisWanNbfIn))) { Exported = 0; }
// If we haven't turned off export, check to see if this bind path
// contains a multiple interface.
//
if (0 != Exported && FBindPathContainsMultipleInterface (Components, pszBindPath)) { Exported = 0; }
return Exported; }
VOID CLanaMap::GetLanaEntry ( IN const CComponentList& Components, IN CLanaEntry* pEntry) { CLanaEntry* pCurrentEntry; BOOL fFound = FALSE;
Assert (pEntry->pszBindPath);
// Check the map for the entry
//
for (pCurrentEntry = begin(); pCurrentEntry != end(); pCurrentEntry++) { if (0 == _wcsicmp (pEntry->pszBindPath, pCurrentEntry->pszBindPath)) { // Found the entry, set the lana number and figure out
// if this entry should be exported.
//
pEntry->RegLanaEntry.Exported = GetExportValue (Components, pEntry->pszBindPath); pEntry->RegLanaEntry.LanaNumber = pCurrentEntry->RegLanaEntry.LanaNumber; fFound = TRUE; break; } }
if (!fFound) { // no match, get next available lana number
BYTE* location = find (m_LanasInUse, m_LanasInUse + MAX_LANA, 0); if (location != m_LanasInUse + MAX_LANA) { pEntry->RegLanaEntry.Exported = GetExportValue (Components, pEntry->pszBindPath); pEntry->RegLanaEntry.LanaNumber = location - m_LanasInUse; m_LanasInUse[location - m_LanasInUse] = 1; } else { // They tell me this is impossible.
AssertSz (FALSE, "No more available Lanas."); pEntry->RegLanaEntry.Exported = 0; pEntry->RegLanaEntry.LanaNumber = MAX_LANA + 1; } } }
HRESULT CLanaMap::HrWriteLanaMapConfig() { HKEY hkeyLinkage; HRESULT hr;
hr = HrRegCreateKeyEx (HKEY_LOCAL_MACHINE, c_szRegKeyNetBiosLinkage, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkeyLinkage, NULL);
if (S_OK == hr) { const BYTE* pbBuffer; DWORD cbBuffer = m_RegistryLanaMap.CountOfBytesUsed();
if (cbBuffer > 0) { pbBuffer = m_RegistryLanaMap.PbBuffer(); } else { pbBuffer = NULL; }
hr = HrRegSetBinary (hkeyLinkage, c_szRegValueLanaMap, pbBuffer, cbBuffer); RegCloseKey (hkeyLinkage); }
if (S_OK == hr) { HKEY hkeyParams; hr = HrRegCreateKeyEx (HKEY_LOCAL_MACHINE, c_szRegKeyNetBiosParameters, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hkeyParams, NULL);
if (S_OK == hr) { hr = HrRegSetDword (hkeyParams, c_szRegValueMaxLana, GetMaxLana());
RegCloseKey (hkeyParams); } }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaMap::HrWriteLanaMapConfig"); return hr; }
HRESULT HrGetNetBiosProviderName ( IN CComponent* pComponent, OUT PWSTR pszName) { HRESULT hr;
Assert (pComponent); Assert (pszName);
// The netbios provider name for a component is stored in its
// <service>\Parameters key.
//
HKEY hkeyService; hr = pComponent->HrOpenServiceKey (KEY_READ, &hkeyService);
if (S_OK == hr) { HKEY hkeyParams; hr = HrRegOpenKeyEx (hkeyService, L"Parameters", KEY_READ, &hkeyParams);
if (S_OK == hr) { DWORD cbBuffer = _MAX_PATH; hr = HrRegQuerySzBuffer (hkeyParams, L"NbProvider", pszName, &cbBuffer);
RegCloseKey (hkeyParams); } RegCloseKey (hkeyService); }
TraceHr (ttidError, FAL, hr, HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr, "HrGetNetBiosProviderName"); return hr; }
HRESULT CLanaMap::HrSetLanaNumber ( IN BYTE OldLanaNumber, IN BYTE NewLanaNumber) { HRESULT hr = S_OK; if (0 == m_LanasInUse[NewLanaNumber]) { CLanaEntry* pEntry;
for (pEntry = begin(); pEntry != end(); pEntry++) { if (OldLanaNumber == pEntry->RegLanaEntry.LanaNumber) { // free up the lana number this entry had.
m_LanasInUse[pEntry->RegLanaEntry.LanaNumber] = 0;
// Give the entry the new lana number.
pEntry->RegLanaEntry.LanaNumber = NewLanaNumber;
m_LanasInUse[NewLanaNumber] = 1; break; } }
if (pEntry == end()) { hr = HRESULT_FROM_WIN32 (ERROR_OBJECT_NOT_FOUND); } } else { // The lana is not free. We will swap the lanas used by the
// two paths.
//
CLanaEntry* pEntry; CLanaEntry* pEntryToSet = NULL; CLanaEntry* pEntryUsingLana = NULL;
for (pEntry = begin(); pEntry != end(); pEntry++) { if (!pEntryToSet && (OldLanaNumber == pEntry->RegLanaEntry.LanaNumber)) { pEntryToSet = pEntry; } else if (!pEntryUsingLana && (NewLanaNumber == pEntry->RegLanaEntry.LanaNumber)) { pEntryUsingLana = pEntry; }
if (pEntryToSet && pEntryUsingLana) { // Give the entry the new lana number.
pEntryToSet->RegLanaEntry.LanaNumber = NewLanaNumber;
// Give the old lana number to the entry that was using the
// new lana number.
pEntryUsingLana->RegLanaEntry.LanaNumber = OldLanaNumber; break; } }
if (!pEntryToSet || !pEntryUsingLana) { hr = HRESULT_FROM_WIN32 (ERROR_OBJECT_NOT_FOUND); } }
TraceHr (ttidError, FAL, hr, FALSE, "CLanaMap::HrSetLanaNumber");
return hr; }
BYTE CLanaMap::GetMaxLana() { for (BYTE b = MAX_LANA; b; b--) { if (m_LanasInUse[b]) return b; }
return 0; }
HRESULT CLanaMap::HrWriteLanaConfiguration ( IN const CComponentList& Components) { HRESULT hr;
// Create the registry map that will be stored.
hr = HrCreateRegistryMap(); if (S_OK == hr) { // Write out the map and other lana info.
hr = HrWriteLanaMapConfig(); }
TraceHr (ttidError, FAL, hr, FALSE, "HrWriteLanaConfiguration"); return hr; }
VOID DumpLanaBindPaths ( IN LANA_BIND_PATH* pBindSet, IN DWORD cPaths) { LANA_BIND_PATH* pPath = pBindSet; DWORD dw = 0; VECTOR_OF_GUIDS::iterator iter;
for (dw = 0; dw < cPaths; dw++) { TraceTag (ttidNetcfgBase, "Path %d", dw); for (iter = pPath->GuidsOfComponentsOnPath.begin(); iter != pPath->GuidsOfComponentsOnPath.end(); iter++) { const GUID* guid = *iter; TraceTag (ttidNetcfgBase, " %lX", guid->Data1); } pPath++; } }
VOID UpdateLanaConfigWithAnswerFileInfo ( IN CLanaMap* pLanaMap, IN DWORD cAfPaths, IN LANA_BIND_PATH* pOriginalBindSet, IN LANA_BIND_PATH* pAnswerFileBindSet) { DWORD dwAnswerFile; DWORD dwPaths; DWORD dwComponents; DWORD dwNumberOfComponents; BOOL fEqual; LANA_BIND_PATH* pAfEntry; LANA_BIND_PATH* pOEntry;
Assert (pLanaMap); Assert (pOriginalBindSet); Assert (pAnswerFileBindSet);
TraceTag (ttidNetcfgBase, "Dumping original bind set"); DumpLanaBindPaths (pOriginalBindSet, pLanaMap->CountEntries()); TraceTag (ttidNetcfgBase, "Dumping af bind set"); DumpLanaBindPaths (pAnswerFileBindSet, cAfPaths);
pAfEntry = pAnswerFileBindSet; for (dwAnswerFile = 0; dwAnswerFile < cAfPaths; dwAnswerFile++) { // Do we have a valid path?
if (!pAfEntry->GuidsOfComponentsOnPath.empty()) { pOEntry = pOriginalBindSet; for (dwPaths = 0; dwPaths < pLanaMap->CountEntries(); dwPaths++) { if (pAfEntry->GuidsOfComponentsOnPath.size() == pOEntry->GuidsOfComponentsOnPath.size()) { dwNumberOfComponents = pAfEntry->GuidsOfComponentsOnPath.size();
fEqual = TRUE; for (dwComponents = 0; dwComponents < dwNumberOfComponents; dwComponents++) { if (pAfEntry->GuidsOfComponentsOnPath[dwComponents] != pOEntry->GuidsOfComponentsOnPath[dwComponents]) { fEqual = FALSE; } }
if (fEqual) { HRESULT hr; hr = pLanaMap->HrSetLanaNumber ( pOEntry->LanaNumber, pAfEntry->LanaNumber);
TraceTag (ttidNetcfgBase, "af path %d matches %d", dwAnswerFile, dwPaths); TraceTag (ttidNetcfgBase, "Changing lana number " "from %X to %X", pOEntry->LanaNumber, pAfEntry->LanaNumber);
TraceHr (ttidError, FAL, hr, FALSE, "Setting lana"); } } pOEntry++; } } pAfEntry++; } }
VOID ConvertAnswerFileComponentsToGuids ( IN const CComponentList& Components, IN PCWSTR mszComponents, OUT VECTOR_OF_GUIDS* pvector) { CComponent* pComponent; PCWSTR pszScan; const GUID* pguid; GUID guidTemp;
Assert (mszComponents); Assert (pvector);
for (pszScan = mszComponents; *pszScan; pszScan += wcslen (pszScan) + 1) {
TraceTag (ttidNetcfgBase, " Looking for af component %S", pszScan);
// Look for the component in our installed components list.
//
pComponent = Components.PFindComponentByInfId (pszScan, NULL);
if (pComponent) { pguid = &pComponent->m_InstanceGuid; } else { TraceTag (ttidNetcfgBase, " Id did not match installed ids. " "Checking af map");
// The component wasn't listed in our installed list. The inf
// id might be something that the answerfile processor has mapped
// to the component's instance guid. This happens for adapters.
// e.g. Id is listed as Adapter01 so netsetup uses an alogrithm
// to determine which adapter it is and then save off its
// instance guid in a map.
//
if (FGetInstanceGuidOfComponentFromAnswerFileMap ( pszScan, &guidTemp)) { pComponent = Components.PFindComponentByInstanceGuid ( &guidTemp); } else { TraceTag (ttidError, " Component %S not found in answerfile " "map", pszScan); }
// If we found the component, store a reference to its
// instance guid
//
if (pComponent) { TraceTag (ttidNetcfgBase, " Found component"); pguid = &pComponent->m_InstanceGuid; } else { // We didn't find the component. Store GUID_NULL.
pguid = &GUID_NULL; } } TraceTag (ttidNetcfgBase, " Using GUID %lX", pguid->Data1);
pvector->push_back (pguid); } }
HRESULT HrConvertAnswerFileParamsToLanaBindSet ( IN INFCONTEXT& ctxLana, IN const CComponentList& Components, IN DWORD cPaths, OUT LANA_BIND_PATH* pBindSet) { DWORD cchField = _MAX_PATH; DWORD cchRequired; INT LanaCode; PWSTR mszComponents; HRESULT hr; DWORD dw; INFCONTEXT ctx = ctxLana; LANA_BIND_PATH* pPath;
hr = S_OK; mszComponents = (PWSTR)MemAlloc (cchField * sizeof (WCHAR));
pPath = pBindSet; for (dw = 0; dw < cPaths; dw++) { if (mszComponents && (S_OK == hr)) { hr = HrSetupGetMultiSzField (ctx, 1, mszComponents, cchField, &cchRequired);
if (S_OK == hr) { TraceTag (ttidNetcfgBase, "Path %ld", dw); ConvertAnswerFileComponentsToGuids (Components, mszComponents, &(pPath->GuidsOfComponentsOnPath));
hr = HrSetupFindNextLine (ctx, &ctx);
if (S_OK == hr) { hr = HrSetupGetIntField (ctx, 1, &LanaCode);
if (S_OK == hr) { pPath->LanaNumber = LanaCode & 0xff;
TraceTag (ttidNetcfgBase, " Using LanaNumber %X for " "path", pPath->LanaNumber); } else { TraceTag (ttidNetcfgBase, " Bad lana code"); // Bad lana number, clear the guids so we won't match
// this path and use this info.
//
pPath->GuidsOfComponentsOnPath.erase( pPath->GuidsOfComponentsOnPath.begin(), pPath->GuidsOfComponentsOnPath.end()); } }
hr = HrSetupFindNextMatchLine (ctx, L"LanaPath", &ctx);
if (S_FALSE == hr) { break; }
pPath++; } else if (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER) == hr) { // Reallocate the buffer.
//
hr = S_OK; MemFree (mszComponents); mszComponents = (PWSTR)MemAlloc (cchRequired * sizeof(WCHAR)); cchField = cchRequired; } } else { hr = E_OUTOFMEMORY; break; } }
if (S_FALSE == hr) { // Check to see if we were really finished.
if ((dw + 1) < cPaths) { TraceTag (ttidError, "Answerfile specified %d lana paths " "but only %d were found", cPaths, (dw + 1)); }
// This fcn only returns S_OK on success.
hr = S_OK; }
TraceHr (ttidError, FAL, hr, FALSE, "HrConvertAnswerFileParamsToLanaBindSet"); return hr; }
HRESULT HrProcessAnswerFile ( IN PCWSTR pszAnswerFile, IN PCWSTR pszSection, IN const CComponentList& Components, OUT LANA_BIND_PATH** ppBindSet, OUT DWORD* pcPaths) { HINF hinf; PCWSTR pszBindPath; WCHAR szBindName[_MAX_PATH]; HRESULT hr;
Assert (pszAnswerFile); Assert (pszSection); Assert (ppBindSet); Assert (pcPaths);
*pcPaths = 0; *ppBindSet = NULL;
hr = HrSetupOpenInfFile (pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL, &hinf);
if (S_OK == hr) { hr = HrSetupGetFirstDword (hinf, pszSection, L"NumberOfPaths", pcPaths);
if (S_OK == hr) { TraceTag (ttidNetcfgBase, "\n\n"); TraceTag (ttidNetcfgBase, "%d paths found in answerfile", *pcPaths);
hr = E_OUTOFMEMORY; *ppBindSet = new LANA_BIND_PATH[*pcPaths]; if (*ppBindSet) { hr = S_OK; } }
if (S_OK == hr) { INFCONTEXT ctx; hr = HrSetupFindFirstLine (hinf, pszSection, L"LanaPath", &ctx);
if (S_OK == hr) { hr = HrConvertAnswerFileParamsToLanaBindSet (ctx, Components, *pcPaths, *ppBindSet); } } }
TraceHr (ttidError, FAL, hr, FALSE, "HrProcessAnswerFile"); return hr; }
HRESULT HrConvertBindingsToLanaBindSet ( IN const CComponentList& Components, IN const CLanaMap& LanaMap, OUT LANA_BIND_PATH** ppBindSet) {
PCWSTR pszBindPath; WCHAR szBindName[_MAX_PATH]; HRESULT hr; DWORD cPaths;
Assert (ppBindSet);
cPaths = LanaMap.CountEntries();
TraceTag (ttidNetcfgBase, "%d paths in system", cPaths);
hr = E_OUTOFMEMORY; *ppBindSet = new LANA_BIND_PATH[cPaths];
if (*ppBindSet) { LANA_BIND_PATH* pBindPath = *ppBindSet; CComponent* pComponent; PCWSTR pszCompStart; PCWSTR pszCompEnd; DWORD cchComp;
hr = S_OK;
const CLanaEntry* pEntry; for (pEntry = LanaMap.begin(); pEntry != LanaMap.end(); pEntry++) { pszBindPath = pEntry->pszBindPath;
TraceTag (ttidNetcfgBase, "BindPath %S", pszBindPath);
pBindPath->LanaNumber = pEntry->RegLanaEntry.LanaNumber; TraceTag (ttidNetcfgBase, "Lana %X", pBindPath->LanaNumber);
GetFirstComponentFromBindPath (pszBindPath, &pszCompStart, &cchComp);
while (*pszCompStart) { wcsncpy (szBindName, pszCompStart, cchComp); szBindName[cchComp] = L'\0';
TraceTag (ttidNetcfgBase, " Searching for component with bind name %S", szBindName);
pComponent = Components.PFindComponentByBindName (NC_INVALID, szBindName);
if (pComponent) { TraceTag (ttidNetcfgBase, " Found component. Guid = %lX", pComponent->m_InstanceGuid.Data1); pBindPath->GuidsOfComponentsOnPath.push_back (&pComponent->m_InstanceGuid); } else { if (*pszCompEnd) { AssertSz (FALSE, " Bind Name not found in component list"); pBindPath->GuidsOfComponentsOnPath.push_back (&GUID_NULL); } }
pszCompStart = pszCompStart + cchComp;
if (*pszCompStart) { pszCompStart++;
pszCompEnd = wcschr (pszCompStart, L'_'); if (!pszCompEnd) { // There is no underscore so set the end pointer
// to the end of the string.
pszCompEnd = pszBindPath + wcslen (pszBindPath); } }
cchComp = pszCompEnd - pszCompStart; } pBindPath++; } }
TraceHr (ttidError, FAL, hr, FALSE, "HrConvertBindingsToLanaBindSet"); return hr; }
HRESULT HrUpdateLanaConfig ( IN const CComponentList& Components, IN PCWSTR pszBindPaths, IN UINT cPaths) { CLanaMap CurrentLanaMap; CLanaMap NewLanaMap; HRESULT hr;
hr = CurrentLanaMap.HrLoadLanaMap();
if (S_OK == hr) { hr = NewLanaMap.HrReserveRoomForEntries (cPaths);
if (S_OK == hr) { PCWSTR pszScan; CLanaEntry LanaEntry;
for (pszScan = pszBindPaths; *pszScan; pszScan += wcslen (pszScan) + 1) { LanaEntry.pszBindPath = pszScan; CurrentLanaMap.GetLanaEntry (Components, &LanaEntry);
hr = NewLanaMap.HrAppendEntry (&LanaEntry);
if (S_OK != hr) { break; } }
if (S_OK == hr) { hr = NewLanaMap.HrWriteLanaConfiguration (Components); } } }
TraceHr (ttidError, FAL, hr, FALSE, "HrUpdateLanaConfig"); return hr;
}
EXTERN_C VOID WINAPI UpdateLanaConfigUsingAnswerfile ( IN PCWSTR pszAnswerFile, IN PCWSTR pszSection) { HRESULT hr; CLanaMap LanaMap;
// Load the current lanamap information.
hr = LanaMap.HrLoadLanaMap();
if (S_OK == hr) { TraceTag (ttidNetcfgBase, "Answerfile params %S:%S", pszAnswerFile, pszSection);
// Load up the current network configuration.
//
CNetConfig NetConfig; hr = HrLoadNetworkConfigurationFromRegistry (KEY_READ, &NetConfig);
if (S_OK == hr) { hr = NetConfig.HrEnsureExternalDataLoadedForAllComponents();
if (S_OK == hr) { // Convert our current lana bind paths to a lana bind set.
//
LANA_BIND_PATH* pBindSet; hr = HrConvertBindingsToLanaBindSet ( NetConfig.Core.Components, LanaMap, &pBindSet);
if (S_OK == hr) { // Convert the answerfile lana bind paths
// to a lana bind set.
//
LANA_BIND_PATH* pAnswerFileBindSet; DWORD cAnswerFilePaths;
hr = HrProcessAnswerFile ( pszAnswerFile, pszSection, NetConfig.Core.Components, &pAnswerFileBindSet, &cAnswerFilePaths);
if (S_OK == hr) { // Now update the config using the answerfile info.
//
UpdateLanaConfigWithAnswerFileInfo ( &LanaMap, cAnswerFilePaths, pBindSet, pAnswerFileBindSet);
// Write out the information.
hr = LanaMap.HrWriteLanaConfiguration ( NetConfig.Core.Components);
delete [] pAnswerFileBindSet; } delete [] pBindSet; } } } }
TraceHr (ttidError, FAL, hr, FALSE, "UpdateLanaConfigUsingAnswerfile"); }
|