Leaked source code of windows server 2003
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.
 
 
 
 
 
 

712 lines
21 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997.
//
// File: S R V R O B J . C P P
//
// Contents: Implementation of CSrvrcfg and helper functions.
//
// Notes:
//
// Author: danielwe 5 Mar 1997
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "srvrobj.h"
#include "ncerror.h"
#include "ncperms.h"
#include "ncreg.h"
#include "ncsetup.h"
#include "ncsvc.h"
#include "afilestr.h"
static const WCHAR c_szRegKeyServerParams[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Parameters";
static const WCHAR c_szRegKeyServerShares[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\Shares";
static const WCHAR c_szRegKeyServerAutoTuned[] = L"System\\CurrentControlSet\\Services\\LanmanServer\\AutotunedParameters";
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::CSrvrcfg
//
// Purpose: Constructs the CSrvrcfg object.
//
// Arguments:
// (none)
//
// Returns: Nothing.
//
// Author: danielwe 5 Mar 1997
//
// Notes:
//
CSrvrcfg::CSrvrcfg()
:
m_hkeyMM(NULL),
m_fDirty(FALSE),
m_pncc(NULL),
m_fOneTimeInstall(FALSE),
m_fRestoredRegistry(FALSE),
m_fUpgradeFromWks(FALSE),
m_fUpgrade(FALSE)
{
ZeroMemory(&m_apspObj, sizeof(m_apspObj));
ZeroMemory(&m_sdd, sizeof(m_sdd));
}
//
// INetCfgComponentControl
//
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::Initialize
//
// Purpose: Called when we are initialized.
//
// Arguments:
// pnccItem [in] Component we belong to.
// pnc [in] INetCfg master object if we need it.
// fInstalling [in] TRUE if we are being installed, FALSE otherwise.
//
// Returns: HRESULT, Error code.
//
// Author: danielwe 22 Mar 1997
//
// Notes:
//
STDMETHODIMP CSrvrcfg::Initialize(INetCfgComponent* pnccItem, INetCfg *pnc,
BOOL fInstalling)
{
Validate_INetCfgNotify_Initialize(pnccItem, pnc, fInstalling);
m_pncc = pnccItem;
AddRefObj(m_pncc);
GetProductFlavor(NULL, &m_pf);
HRESULT hr = HrOpenRegKeys(pnc);
if (SUCCEEDED(hr))
{
hr = HrGetRegistryInfo(fInstalling);
}
Validate_INetCfgNotify_Initialize_Return(hr);
TraceError("CSrvrcfg::Initialize", hr);
return hr;
}
STDMETHODIMP CSrvrcfg::Validate()
{
return S_OK;
}
STDMETHODIMP CSrvrcfg::CancelChanges()
{
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::Apply
//
// Purpose: Called when changes to this component should be applied.
//
// Arguments:
// (none)
//
// Returns: HRESULT, Error code.
//
// Author: danielwe 5 Mar 1997
//
// Notes:
//
STDMETHODIMP CSrvrcfg::ApplyRegistryChanges()
{
HRESULT hr = S_OK;
static const WCHAR c_szLicenseSvc[] = L"LicenseService";
if (m_fUpgrade)
{
TraceTag(ttidSrvrCfg, "Upgrading MS_SERVER");
if (!m_fRestoredRegistry)
{
TraceTag(ttidSrvrCfg, "Restoring registry");
hr = HrRestoreRegistry();
if (FAILED(hr))
{
TraceError("CSrvrcfg::ApplyRegistryChanges - HrRestoreRegistry - non-fatal",
hr);
hr = S_OK;
}
}
}
if (SUCCEEDED(hr))
{
if (m_fDirty)
{
hr = HrSetRegistryInfo();
}
if (SUCCEEDED(hr))
{
if (m_fOneTimeInstall)
{
/*
hr = HrChangeServiceStartTypeOptional(c_szLicenseSvc,
SERVICE_AUTO_START);
if (SUCCEEDED(hr))
{
hr = S_OK;
m_fDirty = FALSE;
m_fOneTimeInstall = FALSE;
}
*/
}
}
}
Validate_INetCfgNotify_Apply_Return(hr);
TraceError("CSrvrcfg::ApplyRegistryChanges",
(hr == S_FALSE) ? S_OK : hr);
return hr;
}
//
// INetCfgComponentSetup
//
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::Install
//
// Purpose: Called when this component is being installed
//
// Arguments:
// dwSetupFlags [in] Flags that describe the type of setup
//
// Returns: HRESULT, Error code.
//
// Author: danielwe 5 Mar 1997
//
// Notes:
//
STDMETHODIMP CSrvrcfg::Install(DWORD dwSetupFlags)
{
m_fDirty = TRUE;
m_fOneTimeInstall = TRUE;
if (dwSetupFlags & NSF_WINNT_WKS_UPGRADE)
{
m_fUpgrade = TRUE;
m_fUpgradeFromWks = TRUE;
}
else if ((dwSetupFlags & NSF_WINNT_SVR_UPGRADE) ||
(dwSetupFlags & NSF_WINNT_SBS_UPGRADE))
{
m_fUpgrade = TRUE;
}
return S_OK;
}
STDMETHODIMP CSrvrcfg::Upgrade(DWORD dwSetupFlags,
DWORD dwUpgradeFomBuildNo)
{
return S_FALSE;
}
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::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:
//
STDMETHODIMP CSrvrcfg::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("CSrvrcfg::ReadAnswerFile- Answer file has "
"errors. Defaulting all information as if "
"answer file did not exist.",
NETSETUP_E_ANS_FILE_ERROR);
hr = S_OK;
}
}
TraceError("CSrvrcfg::ReadAnswerFile", hr);
return hr;
}
STDMETHODIMP CSrvrcfg::Removing()
{
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::HrRestoreRegistry
//
// Purpose: Restores the contents of the registry for this component
//
// Arguments:
// (none)
//
// Returns: Win32 error if failed, otherwise S_OK
//
// Author: danielwe 8 Aug 1997
//
// Notes:
//
HRESULT CSrvrcfg::HrRestoreRegistry()
{
HRESULT hr = S_OK;
HKEY hkey;
TOKEN_PRIVILEGES * ptpRestore = NULL;
BOOL fRestoreSucceeded = FALSE;
if (!m_strParamsRestoreFile.empty() ||
!m_strSharesRestoreFile.empty() ||
!m_strAutoTunedRestoreFile.empty())
{
hr = HrEnableAllPrivileges(&ptpRestore);
if (SUCCEEDED(hr))
{
if (!m_strParamsRestoreFile.empty())
{
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams,
KEY_ALL_ACCESS, &hkey);
if (SUCCEEDED(hr))
{
hr = HrRegRestoreKey(hkey, m_strParamsRestoreFile.c_str(),
0);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
"Parameters", hr);
hr = S_OK;
}
else
{
fRestoreSucceeded = TRUE;
}
RegCloseKey(hkey);
}
}
if (fRestoreSucceeded)
{
// if the restore succeeded, rewrite the values that were blown
// away by the restore
static const WCHAR c_szSvcDLLName[] = L"%SystemRoot%\\System32\\srvsvc.dll";
static const WCHAR c_szServiceDll[] = L"ServiceDll";
HKEY hkResult = NULL;
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerParams, KEY_ALL_ACCESS, &hkResult);
if SUCCEEDED(hr)
{
hr = HrRegSetValueEx(hkResult, c_szServiceDll, REG_EXPAND_SZ, (const BYTE *)c_szSvcDLLName, CbOfMultiSzAndTermSafe(c_szSvcDLLName));
}
if FAILED(hr)
{
TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
"ServiceDll", 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_szRestrictNullSessAccess[] = L"RestrictNullSessAccess";
DWORD value = 1;
hr = HrRegSetValueEx(hkey, c_szRestrictNullSessAccess, REG_DWORD, (const BYTE *)&value, 4);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrRestoreRegistry - setting RestrictNullSessAccess to DWORD 1 failed", hr);
hr = S_OK;
}
RegSafeCloseKey(hkResult);
static const WCHAR c_szTrkWks[] = L"TrkWks";
static const WCHAR c_szTrkSrv[] = L"TrkSrv";
static const WCHAR c_szNullSession[] = L"NullSessionPipes";
hr = HrRegAddStringToMultiSz(c_szTrkWks,
HKEY_LOCAL_MACHINE,
c_szRegKeyServerParams,
c_szNullSession,
STRING_FLAG_ENSURE_AT_END,
0);
if (SUCCEEDED(hr))
{
hr = HrRegAddStringToMultiSz(c_szTrkSrv,
HKEY_LOCAL_MACHINE,
c_szRegKeyServerParams,
c_szNullSession,
STRING_FLAG_ENSURE_AT_END,
0);
}
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrRestoreRegistry - Error replacing "
"values for Parameters", hr);
hr = S_OK;
}
}
if (!m_strSharesRestoreFile.empty())
{
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerShares,
KEY_ALL_ACCESS, &hkey);
if (SUCCEEDED(hr))
{
hr = HrRegRestoreKey(hkey, m_strSharesRestoreFile.c_str(),
0);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
"Shares", hr);
hr = S_OK;
}
RegCloseKey(hkey);
}
}
if (!m_strAutoTunedRestoreFile.empty())
{
hr = HrRegOpenKeyEx(HKEY_LOCAL_MACHINE, c_szRegKeyServerAutoTuned,
KEY_ALL_ACCESS, &hkey);
if (SUCCEEDED(hr))
{
hr = HrRegRestoreKey(hkey, m_strAutoTunedRestoreFile.c_str(),
0);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrRestoreRegistry - HrRestoreRegistry for "
"AutotunedParameters", hr);
hr = S_OK;
}
RegCloseKey(hkey);
}
}
hr = HrRestorePrivileges(ptpRestore);
delete [] reinterpret_cast<BYTE *>(ptpRestore);
// Set a flag so we don't do this again if we are applied again
m_fRestoredRegistry = TRUE;
}
}
else
{
TraceTag(ttidSrvrCfg, "WARNING: HrRestoreRegistry() was called without"
" ReadAnswerFile() being called!");
}
TraceError("CSrvrcfg::HrRestoreRegistry", hr);
return hr;
}
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::HrProcessAnswerFile
//
// Purpose: Handles necessary processing of contents of the answer file.
//
// Arguments:
// pszAnswerFile [in] Filename of answer file for upgrade.
// pszAnswerSection [in] Comma-separated list of sections in the
// file appropriate to this component.
//
// Returns: S_OK if successful, setup API error otherwise.
//
// Author: danielwe 8 May 1997
//
// Notes:
//
HRESULT CSrvrcfg::HrProcessAnswerFile(PCWSTR pszAnswerFile,
PCWSTR pszAnswerSection)
{
HRESULT hr = S_OK;
tstring strOpt;
PCWSTR szOptDefault;
CSetupInfFile csif;
if (m_pf == PF_SERVER)
{
szOptDefault = c_szAfMaxthroughputforfilesharing;
}
else
{
szOptDefault = c_szAfMinmemoryused;
}
// Open the answer file.
hr = csif.HrOpen(pszAnswerFile, NULL, INF_STYLE_OLDNT | INF_STYLE_WIN4, NULL);
if (FAILED(hr))
{
hr = S_OK;
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_szAfLmServerParameters,
&m_strParamsRestoreFile);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
"Parameters key", hr);
// oh well, just continue
hr = S_OK;
}
// Get restore file for "Shares" key
hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerShares,
&m_strSharesRestoreFile);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
"Shares key", hr);
// oh well, just continue
hr = S_OK;
}
// Get restore file for "AutotunedParameters" key
hr = csif.HrGetString(pszAnswerSection,
c_szAfLmServerAutotunedParameters,
&m_strAutoTunedRestoreFile);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
"AutotunedParameters key", hr);
// oh well, just continue
hr = S_OK;
}
}
// Read contents Opimitzation key
hr = csif.HrGetString(pszAnswerSection, c_szAfLmServerOptimization,
&strOpt);
if (SUCCEEDED(hr))
{
m_fDirty = TRUE;
if (!lstrcmpiW(strOpt.c_str(), c_szAfMinmemoryused))
{
m_sdd.dwSize = 1;
}
else if (!lstrcmpiW(strOpt.c_str(), c_szAfBalance))
{
m_sdd.dwSize = 2;
}
else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthroughputforfilesharing))
{
m_sdd.dwSize = 3;
m_sdd.fLargeCache = TRUE;
}
else if (!lstrcmpiW(strOpt.c_str(), c_szAfMaxthrouputfornetworkapps))
{
m_sdd.dwSize = 3;
m_sdd.fLargeCache = FALSE;
}
#ifdef DBG
else
{
// NOTE: Default values for dwSize and fLargeCache will have been set
// already by registry reading function.
TraceTag(ttidSrvrCfg, "Unknown Optimization value '%S'. Using default "
"'%S'.", strOpt.c_str(), szOptDefault);
}
#endif
}
// Read contents of BroadcastsToLanman2Clients key.
hr = csif.HrGetStringAsBool(pszAnswerSection, c_szAfBroadcastToClients,
&m_sdd.fAnnounce);
if (FAILED(hr))
{
TraceError("CSrvrcfg::HrProcessAnswerFile - Error restoring "
"BroadcastsToLanman2Clients key. Using default value"
" of FALSE.", hr);
// oh well, just continue
hr = S_OK;
}
err:
TraceError("CSrvrcfg::HrProcessAnswerFile", hr);
return hr;
}
//
// INetCfgProperties
//
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::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 CSrvrcfg::MergePropPages(DWORD *pdwDefPages,
LPBYTE *pahpspPrivate,
UINT *pcPrivate, HWND hwndParent,
PCWSTR *pszStartPage)
{
HRESULT hr = S_OK;
HPROPSHEETPAGE *ahpsp = NULL;
Validate_INetCfgProperties_MergePropPages(pdwDefPages, pahpspPrivate,
pcPrivate, hwndParent,
pszStartPage);
// We don't want any default pages to be shown
*pdwDefPages = 0;
if (m_pf == PF_WORKSTATION)
{
// On workstation product, UI is not shown.
*pcPrivate = 0;
}
else
{
hr = HrSetupPropSheets(&ahpsp, c_cPages);
if (SUCCEEDED(hr))
{
*pahpspPrivate = (LPBYTE)ahpsp;
*pcPrivate = c_cPages;
}
}
Validate_INetCfgProperties_MergePropPages_Return(hr);
TraceError("CSrvrcfg::MergePropPages", hr);
return hr;
}
STDMETHODIMP CSrvrcfg::ValidateProperties(HWND hwndSheet)
{
return S_OK;
}
STDMETHODIMP CSrvrcfg::CancelProperties()
{
return S_OK;
}
STDMETHODIMP CSrvrcfg::ApplyProperties()
{
return S_OK;
}
//+---------------------------------------------------------------------------
//
// Member: CSrvrcfg::~CSrvrcfg
//
// Purpose: Destroys the CSrvrcfg object.
//
// Arguments:
// (none)
//
// Returns: Nothing.
//
// Author: danielwe 5 Mar 1997
//
// Notes:
//
CSrvrcfg::~CSrvrcfg()
{
ReleaseObj(m_pncc);
RegSafeCloseKey(m_hkeyMM);
CleanupPropPages();
#ifdef DBG
{
INT ipage;
for (ipage = 0; ipage < c_cPages; ipage++)
{
AssertSz(!m_apspObj[ipage], "Prop page object should be NULL!");
}
}
#endif
}