windows-nt/Source/XPSP1/NT/net/config/netcfg/engine/lockdown.cpp

223 lines
5.5 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1999.
//
// File: L O C K D O W N . C P P
//
// Contents: Routines to get and set components that are in a lockdown
// state. A component goes into lockdown when it requires a
// reboot on removal. When a component is locked down, it
// cannot be installed until after the next reboot.
//
// Notes: Because a component comes out of lockdown after a reboot,
// a natural choice for implementation is to use a volatile
// registry key to keep track of the state. Each component
// that is locked down is represented by a volatile registry
// key the name of which is the same as the INF ID of the
// component. These keys exist under
// SYSTEM\CurrentControlSet\Control\Network\Lockdown.
//
// Author: shaunco 24 May 1999
//
//----------------------------------------------------------------------------
#include "pch.h"
#pragma hdrstop
#include "diagctx.h"
#include "lockdown.h"
#include "ncreg.h"
#define REGSTR_KEY_LOCKDOWN \
L"SYSTEM\\CurrentControlSet\\Control\\Network\\Lockdown"
//+---------------------------------------------------------------------------
//
// Function: EnumLockedDownComponents
//
// Purpose: Enumerate the currently locked down components via a
// caller-supplied callback.
//
// Arguments:
// pfnCallback [in] pointer to callback function
// OPTIONAL [in] optional caller-supplied data to pass back
//
// Returns: nothing
//
// Author: shaunco 24 May 1999
//
VOID
EnumLockedDownComponents (
IN PFN_ELDC_CALLBACK pfnCallback,
IN PVOID pvCallerData OPTIONAL)
{
HRESULT hr;
HKEY hkey;
hr = HrRegOpenKeyEx (
HKEY_LOCAL_MACHINE,
REGSTR_KEY_LOCKDOWN,
KEY_READ,
&hkey);
if (S_OK == hr)
{
WCHAR szInfId [_MAX_PATH];
FILETIME ft;
DWORD dwSize;
DWORD dwRegIndex;
for (dwRegIndex = 0, dwSize = celems(szInfId);
S_OK == HrRegEnumKeyEx(hkey, dwRegIndex, szInfId,
&dwSize, NULL, NULL, &ft);
dwRegIndex++, dwSize = celems(szInfId))
{
pfnCallback (szInfId, pvCallerData);
}
RegCloseKey (hkey);;
}
}
//+---------------------------------------------------------------------------
//
// Function: FGetOrSetComponentLockDown
//
// Purpose: Gets or sets the state of whether a component is locked down.
//
// Arguments:
// fSet [in] TRUE to set into the lockdown state, FALSE to get.
// pszInfId [in] the INF ID of the component in question.
//
// Returns: TRUE if non-zero fSet and component is locked down.
// FALSE otherwise.
//
// Author: shaunco 24 May 1999
//
BOOL
FGetOrSetComponentLockDown (
IN BOOL fSet,
IN PCWSTR pszInfId)
{
Assert (pszInfId);
HRESULT hr;
HKEY hkey;
BOOL fRet;
WCHAR szKey [_MAX_PATH];
fRet = FALSE;
hkey = NULL;
wcscpy (szKey, REGSTR_KEY_LOCKDOWN);
wcscat (szKey, L"\\");
wcscat (szKey, pszInfId);
if (fSet)
{
g_pDiagCtx->Printf (ttidBeDiag, " %S is being locked "
"down to prevent re-install until the next reboot\n",
pszInfId);
hr = HrRegCreateKeyEx (
HKEY_LOCAL_MACHINE,
szKey,
REG_OPTION_VOLATILE,
KEY_WRITE,
NULL,
&hkey,
NULL);
}
else
{
hr = HrRegOpenKeyEx (
HKEY_LOCAL_MACHINE,
szKey,
KEY_READ,
&hkey);
if (S_OK == hr)
{
fRet = TRUE;
}
}
RegSafeCloseKey (hkey);
return fRet;
}
BOOL
FIsComponentLockedDown (
IN PCWSTR pszInfId)
{
return FGetOrSetComponentLockDown (FALSE, pszInfId);
}
struct LOCKDOWN_DEPENDENCY_ENTRY
{
PCWSTR pszInfId;
const PCWSTR* ppszDependentInfIds;
};
extern const WCHAR c_szInfId_MS_NWIPX[];
extern const WCHAR c_szInfId_MS_FPNW[];
extern const WCHAR c_szInfId_MS_NWClient[];
extern const WCHAR c_szInfId_MS_NwSapAgent[];
static const PCWSTR c_apszNwlnkIpxDependentInfIds [] =
{
c_szInfId_MS_FPNW,
c_szInfId_MS_NWClient,
c_szInfId_MS_NwSapAgent,
NULL,
};
static const LOCKDOWN_DEPENDENCY_ENTRY c_LockdownDependencyMap [] =
{
{ c_szInfId_MS_NWIPX, c_apszNwlnkIpxDependentInfIds },
{ NULL, NULL }
};
VOID
LockdownComponentUntilNextReboot (
IN PCWSTR pszInfId)
{
(VOID) FGetOrSetComponentLockDown (TRUE, pszInfId);
// Lock down dependents of the component as well.
//
const LOCKDOWN_DEPENDENCY_ENTRY* pEntry;
UINT ipsz;
// Search for the matching entry in c_LockdownDependencyMap.
//
for (pEntry = c_LockdownDependencyMap;
pEntry->pszInfId;
pEntry++)
{
if (0 != _wcsicmp (pEntry->pszInfId, pszInfId))
{
continue;
}
// Found a matching entry. Now lock down all of its
// dependent INF ids. The array of const PCWSTR pointers is
// terminated with a NULL pointer.
//
Assert (pEntry->ppszDependentInfIds);
for (ipsz = 0;
pEntry->ppszDependentInfIds [ipsz];
ipsz++)
{
(VOID) FGetOrSetComponentLockDown (
TRUE, pEntry->ppszDependentInfIds [ipsz]);
}
break;
}
}