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.
943 lines
28 KiB
943 lines
28 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1997-1999.
|
|
//
|
|
// File: M S C L I O B J . C P P
|
|
//
|
|
// Contents: Implementation of the CMSClient notify object model
|
|
//
|
|
// Notes:
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include <ncxbase.h>
|
|
#include <ncsvc.h>
|
|
#include "mscliobj.h"
|
|
#include "nb30.h"
|
|
#include "ncerror.h"
|
|
#include "ncperms.h"
|
|
#include "ncreg.h"
|
|
#include "ncsetup.h"
|
|
#include "ncsvc.h"
|
|
#include <ntsecapi.h>
|
|
#include <lm.h>
|
|
|
|
static const WCHAR c_szBrowseDomains[] = L"BrowseDomains";
|
|
static const WCHAR c_szNameServiceNetAddr[] = L"NameServiceNetworkAddress";
|
|
static const WCHAR c_szNameServiceProt[] = L"NameServiceProtocol";
|
|
|
|
extern const WCHAR c_szInfId_MS_NetBIOS[];
|
|
extern const WCHAR c_szInfId_MS_Server[];
|
|
|
|
|
|
// Defined in rpcdlg.cpp
|
|
extern const WCHAR c_szDefNetAddr[];
|
|
extern const WCHAR c_szProtWinNT[];
|
|
|
|
// Registry paths
|
|
static const WCHAR c_szRegKeyBrowser[] = L"System\\CurrentControlSet\\Services\\Browser\\Parameters";
|
|
static const WCHAR c_szRegKeyNetLogon[] = L"System\\CurrentControlSet\\Services\\NetLogon\\Parameters";
|
|
|
|
// Answer file constants
|
|
static const WCHAR c_szNetLogonParams[] = L"NetLogon.Parameters";
|
|
static const WCHAR c_szBrowserParams[] = L"Browser.Parameters";
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::CMSClient
|
|
//
|
|
// Purpose: Constructs the CMSClient object.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
CMSClient::CMSClient()
|
|
: m_pncc(NULL),
|
|
m_pnc(NULL),
|
|
m_fBrowserChanges(FALSE),
|
|
m_fRPCChanges(FALSE),
|
|
m_fOneTimeInstall(FALSE),
|
|
m_fUpgrade(FALSE),
|
|
m_fRemoving(FALSE),
|
|
m_hkeyRPCName(NULL),
|
|
m_eSrvState(eSrvNone),
|
|
m_fUpgradeFromWks(FALSE),
|
|
m_szDomainList(NULL)
|
|
{
|
|
ZeroMemory(&m_rpcData, sizeof(RPC_CONFIG_DATA));
|
|
ZeroMemory(&m_apspObj, sizeof(m_apspObj));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::~CMSClient
|
|
//
|
|
// Purpose: Destructs the CMSClient object.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: Nothing.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
CMSClient::~CMSClient()
|
|
{
|
|
ReleaseObj(m_pncc);
|
|
ReleaseObj(m_pnc);
|
|
|
|
RegSafeCloseKey(m_hkeyRPCName);
|
|
|
|
m_rpcData.strProt.erase();
|
|
m_rpcData.strNetAddr.erase();
|
|
m_rpcData.strEndPoint.erase();
|
|
|
|
CleanupPropPages();
|
|
|
|
#ifdef DBG
|
|
{
|
|
INT ipage;
|
|
|
|
for (ipage = 0; ipage < c_cPages; ipage++)
|
|
{
|
|
AssertSz(!m_apspObj[ipage], "Prop page object not cleaned up!");
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
delete [] m_szDomainList;
|
|
}
|
|
|
|
//
|
|
// INetCfgComponentControl
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::Initialize
|
|
//
|
|
// Purpose: Initializes the notify object.
|
|
//
|
|
// Arguments:
|
|
// pnccItem [in] INetCfgComponent that we are handling
|
|
// notifications for.
|
|
// pnc [in] INetCfg master object.
|
|
// fInstalling [in] TRUE if we are being installed, FALSE if not.
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::Initialize(INetCfgComponent *pnccItem, INetCfg *pnc,
|
|
BOOL fInstalling)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
INetCfgComponent * pnccServer = NULL;
|
|
|
|
Validate_INetCfgNotify_Initialize(pnccItem, pnc, fInstalling);
|
|
|
|
m_pncc = pnccItem;
|
|
m_pnc = pnc;
|
|
|
|
AssertSz(m_pncc, "Component object is NULL!");
|
|
AssertSz(m_pnc, "INetCfg object is NULL!");
|
|
|
|
// We're hanging on to these, so AddRef 'em.
|
|
AddRefObj(m_pncc);
|
|
AddRefObj(m_pnc);
|
|
|
|
// Check to see if MS_SERVER is installed. If not, set the browser service
|
|
// to be disabled.
|
|
//
|
|
hr = m_pnc->FindComponent(c_szInfId_MS_Server, &pnccServer);
|
|
if (S_FALSE == hr)
|
|
{
|
|
// Server component is not present. Set browser to be disabled on
|
|
// apply
|
|
m_eSrvState = eSrvDisable;
|
|
}
|
|
else if (S_OK == hr)
|
|
{
|
|
ReleaseObj(pnccServer);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Read in data for the RPC config dialog from the registry
|
|
hr = HrGetRPCRegistryInfo();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
// Read in data for the browser config dialog from the registry
|
|
hr = HrGetBrowserRegistryInfo();
|
|
}
|
|
}
|
|
|
|
Validate_INetCfgNotify_Initialize_Return(hr);
|
|
|
|
TraceError("CMSClient::Initialize", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::Validate()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::CancelChanges()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::ApplyRegistryChanges
|
|
//
|
|
// Purpose: Called when changes to this component should be applied.
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK if successful, S_FALSE if no changes occurred,
|
|
// NETCFG_S_REBOOT if a reboot is required, otherwise a NETCFG_E
|
|
// error code.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::ApplyRegistryChanges()
|
|
{
|
|
TraceFileFunc(ttidMSCliCfg);
|
|
HRESULT hr = S_OK;
|
|
|
|
if (m_fUpgrade)
|
|
{
|
|
m_fUpgrade = FALSE;
|
|
|
|
hr = HrRestoreRegistry();
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::ApplyRegistryChanges - HrRestoreRegistry - non-fatal",
|
|
hr);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
// Do we need to enable or disable the browser service??
|
|
//
|
|
switch (m_eSrvState)
|
|
{
|
|
case eSrvEnable:
|
|
TraceTag(ttidMSCliCfg, "Enabling the Browser service...");
|
|
hr = HrEnableBrowserService();
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::ApplyRegistryChanges - HrEnableBrowserService failed."
|
|
" non-fatal.", hr);
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
|
|
case eSrvDisable:
|
|
TraceTag(ttidMSCliCfg, "Disabling the Browser service...");
|
|
hr = HrDisableBrowserService();
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::ApplyRegistryChanges - HrDisableBrowserService failed."
|
|
" non-fatal.", hr);
|
|
hr = S_OK;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (m_fRPCChanges || m_fBrowserChanges ||
|
|
m_fOneTimeInstall || m_fUpgradeFromWks)
|
|
{
|
|
hr = HrApplyChanges();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
m_fRPCChanges = FALSE;
|
|
m_fBrowserChanges = FALSE;
|
|
m_fOneTimeInstall = FALSE;
|
|
|
|
// Make NetLogon dependend on LanmanServer for Domain Controllers, and Automatic start for Domain Members
|
|
hr = HrSetNetLogonDependencies();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// No relevant changes were detected (netbios changes do not affect
|
|
// netcfg so we can return S_FALSE even if things changed
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
Validate_INetCfgNotify_Apply_Return(hr);
|
|
|
|
TraceError("CMSClient::ApplyRegistryChanges", (hr == S_FALSE) ? S_OK : hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP
|
|
CMSClient::ApplyPnpChanges (
|
|
IN INetCfgPnpReconfigCallback* pICallback)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = S_OK;
|
|
|
|
if (m_fRemoving)
|
|
{
|
|
// Make sure Mrxsmb and Rdbss have been removed. (They are stopped
|
|
// when LanmanWorkstation stops, but the binding engine has no idea
|
|
// that Mrxsmb and Rdbss are part of this component. Hence, the
|
|
// status of the DeleteService that is performed as part of the INF
|
|
// is not communicated back out.) We make sure that these services
|
|
// do not exist here, and if they do, we report that we need a
|
|
// reboot.
|
|
//
|
|
CServiceManager scm;
|
|
CService svc;
|
|
|
|
TraceTag(ttidMSCliCfg, "Checking to see that Mrxsmb and Rdbss "
|
|
"are stopped and removed");
|
|
|
|
hr = scm.HrOpenService (&svc, L"Mrxsmb",
|
|
NO_LOCK, SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
|
|
|
|
if (HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) != hr)
|
|
{
|
|
TraceHr(ttidMSCliCfg, FAL, hr, FALSE, "OpenService(MrxSmb)");
|
|
TraceTag(ttidMSCliCfg, "Mrxsmb still exists");
|
|
hr = NETCFG_S_REBOOT;
|
|
}
|
|
else
|
|
{
|
|
// Mrxsmb does not exist. Now check Rdbss.
|
|
//
|
|
hr = scm.HrOpenService (&svc, L"Rdbss",
|
|
NO_LOCK, SC_MANAGER_CONNECT, SERVICE_QUERY_STATUS);
|
|
|
|
if (HRESULT_FROM_WIN32(ERROR_SERVICE_DOES_NOT_EXIST) != hr)
|
|
{
|
|
TraceHr(ttidMSCliCfg, FAL, hr, FALSE, "OpenService(Rdbss)");
|
|
TraceTag(ttidMSCliCfg, "Rdbss still exists");
|
|
hr = NETCFG_S_REBOOT;
|
|
}
|
|
else
|
|
{
|
|
// Rdbss does not exist. This is good.
|
|
//
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// INetCfgComponentSetup
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::Install
|
|
//
|
|
// Purpose: Called when this component is being installed
|
|
//
|
|
// Arguments:
|
|
// dwSetupFlags [in] Flags that describe the type of setup
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 30 Oct 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::Install(DWORD dwSetupFlags)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Validate_INetCfgNotify_Install (dwSetupFlags);
|
|
|
|
m_fRPCChanges = TRUE;
|
|
m_fBrowserChanges = TRUE;
|
|
m_fOneTimeInstall = TRUE;
|
|
|
|
if ((NSF_WINNT_WKS_UPGRADE & dwSetupFlags) ||
|
|
(NSF_WINNT_SBS_UPGRADE & dwSetupFlags) ||
|
|
(NSF_WINNT_SVR_UPGRADE & dwSetupFlags))
|
|
{
|
|
m_fUpgrade = TRUE;
|
|
}
|
|
|
|
// Install the NetBIOS sub-component
|
|
hr = HrInstallComponentOboComponent(m_pnc, NULL,
|
|
GUID_DEVCLASS_NETSERVICE,
|
|
c_szInfId_MS_NetBIOS,
|
|
m_pncc,
|
|
NULL);
|
|
|
|
TraceError("CMSClient::Install", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::Upgrade
|
|
//
|
|
// Purpose: Called when this component is upgraded
|
|
//
|
|
// Arguments:
|
|
// dwSetupFlags [in] Flags describing setup
|
|
// dwUpgradeFomBuildNo [in] Build number from which we are upgrading
|
|
//
|
|
// Returns: S_OK if success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 30 Oct 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::Upgrade(DWORD dwSetupFlags,
|
|
DWORD dwUpgradeFomBuildNo)
|
|
{
|
|
if (dwSetupFlags & NSF_WINNT_WKS_UPGRADE)
|
|
{
|
|
TraceTag(ttidMSCliCfg, "Upgrading from workstation...");
|
|
m_fUpgradeFromWks = TRUE;
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::ReadAnswerFile
|
|
//
|
|
// Purpose: Reads the appropriate fields from the given answer file into
|
|
// our in-memory state.
|
|
//
|
|
// Arguments:
|
|
// pszAnswerFile [in] File name of answer file
|
|
// pszAnswerSection [in] Section of answer file to look in
|
|
//
|
|
// Returns: S_OK if successful, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 30 Oct 1997
|
|
//
|
|
// Notes: IMPORTANT: During install or upgrade, this MUST be called
|
|
// *before* Upgrade() or Install()! (see bug #100995)
|
|
//
|
|
STDMETHODIMP CMSClient::ReadAnswerFile(PCWSTR pszAnswerFile,
|
|
PCWSTR pszAnswerSection)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if (pszAnswerSection && pszAnswerFile)
|
|
{
|
|
// There's an answer file. We must process it now.
|
|
hr = HrProcessAnswerFile(pszAnswerFile, pszAnswerSection);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::ReadAnswerFile- Answer file has "
|
|
"errors. Defaulting all information as if "
|
|
"answer file did not exist.",
|
|
NETSETUP_E_ANS_FILE_ERROR);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
TraceError("CMSClient::ReadAnswerFile", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::Removing
|
|
//
|
|
// Purpose: Called whent this component is being removed
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK of success, OLE or Win32 error otherwise
|
|
//
|
|
// Author: danielwe 30 Oct 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::Removing()
|
|
{
|
|
m_fRemoving = TRUE;
|
|
|
|
// Remove the NetBIOS service. This doesn't actually remove the
|
|
// component, it simply marks it as needing to be removed, and in
|
|
// Apply() it will be fully removed.
|
|
HRESULT hr = HrRemoveComponentOboComponent(m_pnc,
|
|
GUID_DEVCLASS_NETSERVICE,
|
|
c_szInfId_MS_NetBIOS,
|
|
m_pncc);
|
|
|
|
TraceError("CMSClient::Removing", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::HrRestoreRegistry
|
|
//
|
|
// Purpose: Restores the registry settings for various services on upgrade
|
|
//
|
|
// Arguments:
|
|
// (none)
|
|
//
|
|
// Returns: S_OK if success, WIN32 error otherwise
|
|
//
|
|
// Author: danielwe 8 Aug 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
HRESULT CMSClient::HrRestoreRegistry()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HKEY hkey;
|
|
TOKEN_PRIVILEGES * ptpRestore = NULL;
|
|
static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\browser.dll";
|
|
static const WCHAR c_szServiceDll[] = L"ServiceDll";
|
|
|
|
if (!m_strBrowserParamsRestoreFile.empty() ||
|
|
!m_strNetLogonParamsRestoreFile.empty())
|
|
{
|
|
hr = HrEnableAllPrivileges(&ptpRestore);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (!m_strBrowserParamsRestoreFile.empty())
|
|
{
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyBrowser,
|
|
KEY_ALL_ACCESS, &hkey);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrRegRestoreKey(hkey,
|
|
m_strBrowserParamsRestoreFile.c_str(),
|
|
0);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrRestoreRegistry - "
|
|
"HrRestoreRegistry for Browser Parameters",
|
|
hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
hr = HrRegSetValueEx(hkey, c_szServiceDll, REG_EXPAND_SZ, (const BYTE *)c_szSvcDLLName, (wcslen(c_szSvcDLLName) + 1) * sizeof(TCHAR));
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrRestoreRegistry - HrRestoreRegistry for "
|
|
"ServiceDll", hr);
|
|
hr = S_OK;
|
|
}
|
|
RegSafeCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
if (!m_strNetLogonParamsRestoreFile.empty())
|
|
{
|
|
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyNetLogon,
|
|
KEY_ALL_ACCESS, &hkey);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = HrRegRestoreKey(hkey,
|
|
m_strNetLogonParamsRestoreFile.c_str(),
|
|
0);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrRestoreRegistry - "
|
|
"HrRestoreRegistry for NetLogon Parameters",
|
|
hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
//
|
|
// The following key has to be set here because of new changes introduced
|
|
// by SCE (Security Configuration Engine). SCE runs early in GUI mode setup to
|
|
// set out-of-the-box security by setting some registry values. During NT4
|
|
// upgrades we don't see those registry values set because during NT4 upgrades,
|
|
// some services including Lanmanserver and Netlogon gets deleted and reinstalled
|
|
// for PnP requirements. To maintain the services configuration between deleting
|
|
// and reinstalling, some of their Keys including the "Parameters" keys for
|
|
// LanManServer and Netlogon get backed up early during upgrade and restored
|
|
// later with the service installation. This backing up and restoring action
|
|
// happens through the services own notify objects (like this one). The problem
|
|
// is, backing up of the Keys happens before SCE sets the values in those keys and
|
|
// they get restored after SCE sets the values. So we lose the values set. So, we
|
|
// are setting those keys here separately to the secure values.
|
|
// See Windows Raid bug #691952 for more details.
|
|
//
|
|
|
|
static const WCHAR c_szRequireSignOrSeal[] = L"RequireSignOrSeal";
|
|
DWORD value = 1;
|
|
|
|
hr = HrRegSetValueEx(hkey, c_szRequireSignOrSeal, REG_DWORD, (const BYTE *)&value, 4);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClicfg::HrRestoreRegistry - setting RequireSignOrSeal to DWORD 1 failed", hr);
|
|
hr = S_OK;
|
|
}
|
|
|
|
RegCloseKey(hkey);
|
|
}
|
|
}
|
|
|
|
hr = HrRestorePrivileges(ptpRestore);
|
|
|
|
delete [] reinterpret_cast<BYTE *>(ptpRestore);
|
|
}
|
|
}
|
|
|
|
TraceError("CMSClient::HrRestoreRegistry", hr);
|
|
return hr;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::HrProcessAnswerFile
|
|
//
|
|
// Purpose: Processes the answer file. Any parameters that have been set
|
|
// are read into our in-memory state.
|
|
//
|
|
// Arguments:
|
|
// pszAnswerFile [in] Filename of answer file.
|
|
// pszAnswerSection [in] Comma-separated list of sections in the
|
|
// file appropriate to this component.
|
|
//
|
|
// Returns: S_OK if successful, NETCFG error code otherwise.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes: Errors returned from this function should be ignored so as to
|
|
// prevent blocking the rest of network install.
|
|
//
|
|
HRESULT CMSClient::HrProcessAnswerFile(PCWSTR pszAnswerFile,
|
|
PCWSTR pszAnswerSection)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CSetupInfFile csif;
|
|
PWSTR mszDomainList = NULL;
|
|
|
|
AssertSz(pszAnswerFile, "Answer file string is NULL!");
|
|
AssertSz(pszAnswerSection, "Answer file sections string is NULL!");
|
|
|
|
// Open the answer file.
|
|
hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
|
|
if (FAILED(hr))
|
|
goto err;
|
|
|
|
if (m_fUpgrade)
|
|
{
|
|
// Restore portions of the registry based on file names from the answer
|
|
// file
|
|
|
|
// Get restore file for "Parameters" key
|
|
hr = csif.HrGetString(pszAnswerSection, c_szNetLogonParams,
|
|
&m_strNetLogonParamsRestoreFile);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrProcessAnswerFile - Error reading "
|
|
"NetLogon.Parameters from answer file", hr);
|
|
|
|
// oh well, just continue
|
|
hr = S_OK;
|
|
}
|
|
|
|
// Get restore file for "Parameters" key
|
|
hr = csif.HrGetString(pszAnswerSection, c_szBrowserParams,
|
|
&m_strBrowserParamsRestoreFile);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrProcessAnswerFile - Error reading "
|
|
"Browser.Parameters from answer file", hr);
|
|
|
|
// oh well, just continue
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
// Get the BrowseDomains field.
|
|
hr = HrSetupGetFirstMultiSzFieldWithAlloc(csif.Hinf(),
|
|
pszAnswerSection,
|
|
c_szBrowseDomains,
|
|
&mszDomainList);
|
|
if (FAILED(hr))
|
|
{
|
|
// ignore line not found errors
|
|
if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrProcessAnswerFile - Error on BrowseDomains field. "
|
|
"Using default value", hr);
|
|
}
|
|
else
|
|
{
|
|
// Set the new domain list.
|
|
SetBrowserDomainList(mszDomainList);
|
|
}
|
|
|
|
// Get the NameServiceNetworkAddress value
|
|
hr = csif.HrGetString(pszAnswerSection,
|
|
c_szNameServiceNetAddr,
|
|
&m_rpcData.strNetAddr);
|
|
if (FAILED(hr))
|
|
{
|
|
// ignore line not found errors
|
|
if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrProcessAnswerFile - Error on NetworkAddress field. "
|
|
"Defaulting value", hr);
|
|
m_rpcData.strNetAddr = c_szDefNetAddr;
|
|
}
|
|
else
|
|
{
|
|
m_fRPCChanges = TRUE;
|
|
}
|
|
|
|
// Get the NameServiceProtocol value.
|
|
hr = csif.HrGetString(pszAnswerSection,
|
|
c_szNameServiceProt,
|
|
&m_rpcData.strProt);
|
|
if (FAILED(hr))
|
|
{
|
|
// ignore line not found errors
|
|
if (hr == HRESULT_FROM_SETUPAPI(ERROR_LINE_NOT_FOUND))
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
|
|
TraceError("HrProcessAnswerFile - Error on NameServiceProtocol field. "
|
|
"Defaulting value", hr);
|
|
m_rpcData.strProt = c_szProtWinNT;
|
|
}
|
|
else
|
|
{
|
|
m_fRPCChanges = TRUE;
|
|
}
|
|
|
|
err:
|
|
TraceError("CMSClient::HrProcessAnswerFile", hr);
|
|
return hr;
|
|
}
|
|
|
|
//
|
|
// INetCfgProperties
|
|
//
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Member: CMSClient::MergePropPages
|
|
//
|
|
// Purpose: Called when this component's properties are about to be
|
|
// brought up.
|
|
//
|
|
// Arguments:
|
|
// pdwDefPages [out] Number of default pages to show.
|
|
// pahpspPrivate [out] Array of property sheet handles to pages that this
|
|
// component will show.
|
|
// pcPrivate [out] Number of pages in array.
|
|
// hwndParent [in] Parent window for any UI.
|
|
// pszStartPage [out] Pointer to start page.
|
|
//
|
|
// Returns: HRESULT, Error code.
|
|
//
|
|
// Author: danielwe 22 Feb 1997
|
|
//
|
|
// Notes:
|
|
//
|
|
STDMETHODIMP CMSClient::MergePropPages(
|
|
IN OUT DWORD* pdwDefPages,
|
|
OUT LPBYTE* pahpspPrivate,
|
|
OUT UINT* pcPages,
|
|
IN HWND hwndParent,
|
|
OUT PCWSTR* pszStartPage)
|
|
{
|
|
Validate_INetCfgProperties_MergePropPages (
|
|
pdwDefPages, pahpspPrivate, pcPages, hwndParent, pszStartPage);
|
|
|
|
HPROPSHEETPAGE *ahpsp = NULL;
|
|
HRESULT hr = HrSetupPropSheets(&ahpsp, c_cPages);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
*pahpspPrivate = (LPBYTE)ahpsp;
|
|
|
|
// We don't want any default pages to be shown
|
|
*pdwDefPages = 0;
|
|
*pcPages = c_cPages;
|
|
}
|
|
|
|
Validate_INetCfgProperties_MergePropPages_Return(hr);
|
|
|
|
TraceError("CMSClient::MergePropPages", hr);
|
|
return hr;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::ValidateProperties(HWND hwndSheet)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::CancelProperties()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::ApplyProperties()
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
//
|
|
// INetCfgSystemNotify
|
|
//
|
|
STDMETHODIMP CMSClient::GetSupportedNotifications (DWORD* pdwNotificationFlag)
|
|
{
|
|
Validate_INetCfgSystemNotify_GetSupportedNotifications(pdwNotificationFlag);
|
|
|
|
*pdwNotificationFlag = NCN_NETTRANS | NCN_NETSERVICE |
|
|
NCN_ENABLE | NCN_DISABLE |
|
|
NCN_ADD | NCN_REMOVE;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::SysQueryBindingPath (DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbp)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::SysQueryComponent (DWORD dwChangeFlag,
|
|
INetCfgComponent* pncc)
|
|
{
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::SysNotifyBindingPath (DWORD dwChangeFlag,
|
|
INetCfgBindingPath* pncbpItem)
|
|
{
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CMSClient::SysNotifyComponent(DWORD dwChangeFlag,
|
|
INetCfgComponent* pncc)
|
|
{
|
|
HRESULT hr;
|
|
|
|
Validate_INetCfgSystemNotify_SysNotifyComponent(dwChangeFlag, pncc);
|
|
|
|
// Assume we won't be dirty as a result of this notification.
|
|
//
|
|
hr = S_FALSE;
|
|
|
|
if (dwChangeFlag & (NCN_ADD | NCN_REMOVE))
|
|
{
|
|
if (FIsComponentId(c_szInfId_MS_Server, pncc))
|
|
{
|
|
if (dwChangeFlag & NCN_ADD)
|
|
{
|
|
m_eSrvState = eSrvEnable;
|
|
hr = S_OK;
|
|
}
|
|
else if (dwChangeFlag & NCN_REMOVE)
|
|
{
|
|
m_eSrvState = eSrvDisable;
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT CMSClient::HrSetNetLogonDependencies(VOID)
|
|
{
|
|
static const WCHAR c_szLanmanServer[] = L"LanmanServer";
|
|
static const WCHAR c_szNetLogon[] = L"NetLogon";
|
|
|
|
HRESULT hr = S_OK;
|
|
NT_PRODUCT_TYPE ProductType;
|
|
if (RtlGetNtProductType(&ProductType))
|
|
{
|
|
if (NtProductLanManNt == ProductType)
|
|
{
|
|
// If domain controller, make NetLogon wait for LanmanServer
|
|
CServiceManager sm;
|
|
CService svc;
|
|
hr = sm.HrOpen();
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = sm.HrAddServiceDependency(c_szNetLogon, c_szLanmanServer);
|
|
sm.Close();
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrSetNetLogonDependencies - "
|
|
"Creating dependency of NetLogon on LanmanServer",
|
|
hr);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
LSA_HANDLE h=0;
|
|
POLICY_PRIMARY_DOMAIN_INFO* ppdi;
|
|
LSA_OBJECT_ATTRIBUTES loa;
|
|
ZeroMemory (&loa, sizeof(loa));
|
|
loa.Length = sizeof(LSA_OBJECT_ATTRIBUTES);
|
|
|
|
NTSTATUS ntstatus;
|
|
ntstatus = LsaOpenPolicy(NULL, &loa, POLICY_VIEW_LOCAL_INFORMATION, &h);
|
|
if (FALSE != LSA_SUCCESS(ntstatus))
|
|
{
|
|
ntstatus = LsaQueryInformationPolicy(h, PolicyPrimaryDomainInformation, (VOID **) &ppdi);
|
|
if (LSA_SUCCESS(ntstatus))
|
|
{
|
|
if (ppdi->Sid > 0) // Domain Member
|
|
{
|
|
hr = HrChangeServiceStartType(c_szNetLogon, SERVICE_AUTO_START);
|
|
if (FAILED(hr))
|
|
{
|
|
TraceError("CMSClient::HrSetNetLogonDependencies - "
|
|
"Install for Start - NetLogon",
|
|
hr);
|
|
}
|
|
|
|
}
|
|
LsaFreeMemory(ppdi);
|
|
}
|
|
LsaClose(h);
|
|
}
|
|
}
|
|
|
|
TraceError("CMSClient::HrSetNetLogonDependencies",hr);
|
|
return hr;
|
|
}
|