Source code of Windows XP (NT5)
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.

222 lines
5.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: L O C K D O W N . C P P
  7. //
  8. // Contents: Routines to get and set components that are in a lockdown
  9. // state. A component goes into lockdown when it requires a
  10. // reboot on removal. When a component is locked down, it
  11. // cannot be installed until after the next reboot.
  12. //
  13. // Notes: Because a component comes out of lockdown after a reboot,
  14. // a natural choice for implementation is to use a volatile
  15. // registry key to keep track of the state. Each component
  16. // that is locked down is represented by a volatile registry
  17. // key the name of which is the same as the INF ID of the
  18. // component. These keys exist under
  19. // SYSTEM\CurrentControlSet\Control\Network\Lockdown.
  20. //
  21. // Author: shaunco 24 May 1999
  22. //
  23. //----------------------------------------------------------------------------
  24. #include "pch.h"
  25. #pragma hdrstop
  26. #include "diagctx.h"
  27. #include "lockdown.h"
  28. #include "ncreg.h"
  29. #define REGSTR_KEY_LOCKDOWN \
  30. L"SYSTEM\\CurrentControlSet\\Control\\Network\\Lockdown"
  31. //+---------------------------------------------------------------------------
  32. //
  33. // Function: EnumLockedDownComponents
  34. //
  35. // Purpose: Enumerate the currently locked down components via a
  36. // caller-supplied callback.
  37. //
  38. // Arguments:
  39. // pfnCallback [in] pointer to callback function
  40. // OPTIONAL [in] optional caller-supplied data to pass back
  41. //
  42. // Returns: nothing
  43. //
  44. // Author: shaunco 24 May 1999
  45. //
  46. VOID
  47. EnumLockedDownComponents (
  48. IN PFN_ELDC_CALLBACK pfnCallback,
  49. IN PVOID pvCallerData OPTIONAL)
  50. {
  51. HRESULT hr;
  52. HKEY hkey;
  53. hr = HrRegOpenKeyEx (
  54. HKEY_LOCAL_MACHINE,
  55. REGSTR_KEY_LOCKDOWN,
  56. KEY_READ,
  57. &hkey);
  58. if (S_OK == hr)
  59. {
  60. WCHAR szInfId [_MAX_PATH];
  61. FILETIME ft;
  62. DWORD dwSize;
  63. DWORD dwRegIndex;
  64. for (dwRegIndex = 0, dwSize = celems(szInfId);
  65. S_OK == HrRegEnumKeyEx(hkey, dwRegIndex, szInfId,
  66. &dwSize, NULL, NULL, &ft);
  67. dwRegIndex++, dwSize = celems(szInfId))
  68. {
  69. pfnCallback (szInfId, pvCallerData);
  70. }
  71. RegCloseKey (hkey);;
  72. }
  73. }
  74. //+---------------------------------------------------------------------------
  75. //
  76. // Function: FGetOrSetComponentLockDown
  77. //
  78. // Purpose: Gets or sets the state of whether a component is locked down.
  79. //
  80. // Arguments:
  81. // fSet [in] TRUE to set into the lockdown state, FALSE to get.
  82. // pszInfId [in] the INF ID of the component in question.
  83. //
  84. // Returns: TRUE if non-zero fSet and component is locked down.
  85. // FALSE otherwise.
  86. //
  87. // Author: shaunco 24 May 1999
  88. //
  89. BOOL
  90. FGetOrSetComponentLockDown (
  91. IN BOOL fSet,
  92. IN PCWSTR pszInfId)
  93. {
  94. Assert (pszInfId);
  95. HRESULT hr;
  96. HKEY hkey;
  97. BOOL fRet;
  98. WCHAR szKey [_MAX_PATH];
  99. fRet = FALSE;
  100. hkey = NULL;
  101. wcscpy (szKey, REGSTR_KEY_LOCKDOWN);
  102. wcscat (szKey, L"\\");
  103. wcscat (szKey, pszInfId);
  104. if (fSet)
  105. {
  106. g_pDiagCtx->Printf (ttidBeDiag, " %S is being locked "
  107. "down to prevent re-install until the next reboot\n",
  108. pszInfId);
  109. hr = HrRegCreateKeyEx (
  110. HKEY_LOCAL_MACHINE,
  111. szKey,
  112. REG_OPTION_VOLATILE,
  113. KEY_WRITE,
  114. NULL,
  115. &hkey,
  116. NULL);
  117. }
  118. else
  119. {
  120. hr = HrRegOpenKeyEx (
  121. HKEY_LOCAL_MACHINE,
  122. szKey,
  123. KEY_READ,
  124. &hkey);
  125. if (S_OK == hr)
  126. {
  127. fRet = TRUE;
  128. }
  129. }
  130. RegSafeCloseKey (hkey);
  131. return fRet;
  132. }
  133. BOOL
  134. FIsComponentLockedDown (
  135. IN PCWSTR pszInfId)
  136. {
  137. return FGetOrSetComponentLockDown (FALSE, pszInfId);
  138. }
  139. struct LOCKDOWN_DEPENDENCY_ENTRY
  140. {
  141. PCWSTR pszInfId;
  142. const PCWSTR* ppszDependentInfIds;
  143. };
  144. extern const WCHAR c_szInfId_MS_NWIPX[];
  145. extern const WCHAR c_szInfId_MS_FPNW[];
  146. extern const WCHAR c_szInfId_MS_NWClient[];
  147. extern const WCHAR c_szInfId_MS_NwSapAgent[];
  148. static const PCWSTR c_apszNwlnkIpxDependentInfIds [] =
  149. {
  150. c_szInfId_MS_FPNW,
  151. c_szInfId_MS_NWClient,
  152. c_szInfId_MS_NwSapAgent,
  153. NULL,
  154. };
  155. static const LOCKDOWN_DEPENDENCY_ENTRY c_LockdownDependencyMap [] =
  156. {
  157. { c_szInfId_MS_NWIPX, c_apszNwlnkIpxDependentInfIds },
  158. { NULL, NULL }
  159. };
  160. VOID
  161. LockdownComponentUntilNextReboot (
  162. IN PCWSTR pszInfId)
  163. {
  164. (VOID) FGetOrSetComponentLockDown (TRUE, pszInfId);
  165. // Lock down dependents of the component as well.
  166. //
  167. const LOCKDOWN_DEPENDENCY_ENTRY* pEntry;
  168. UINT ipsz;
  169. // Search for the matching entry in c_LockdownDependencyMap.
  170. //
  171. for (pEntry = c_LockdownDependencyMap;
  172. pEntry->pszInfId;
  173. pEntry++)
  174. {
  175. if (0 != _wcsicmp (pEntry->pszInfId, pszInfId))
  176. {
  177. continue;
  178. }
  179. // Found a matching entry. Now lock down all of its
  180. // dependent INF ids. The array of const PCWSTR pointers is
  181. // terminated with a NULL pointer.
  182. //
  183. Assert (pEntry->ppszDependentInfIds);
  184. for (ipsz = 0;
  185. pEntry->ppszDependentInfIds [ipsz];
  186. ipsz++)
  187. {
  188. (VOID) FGetOrSetComponentLockDown (
  189. TRUE, pEntry->ppszDependentInfIds [ipsz]);
  190. }
  191. break;
  192. }
  193. }