//+--------------------------------------------------------------------------- // // 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); //ensure that the infid passed in is within required limits. Assert (wcslen (pszInfId) < MAX_DEVICE_ID_LEN); 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; } }