|
|
//+---------------------------------------------------------------------------
//
// 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; } }
|