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.

396 lines
12 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CClusDB.cpp
  7. //
  8. // Description:
  9. // Contains the definition of the CClusDB class.
  10. //
  11. // Maintained By:
  12. // Vij Vasu (Vvasu) 08-MAR-2000
  13. //
  14. //////////////////////////////////////////////////////////////////////////////
  15. //////////////////////////////////////////////////////////////////////////////
  16. // Include Files
  17. //////////////////////////////////////////////////////////////////////////////
  18. // The precompiled header.
  19. #include "pch.h"
  20. // For setupapi functions
  21. #include <setupapi.h>
  22. // The header for this file
  23. #include "CClusDB.h"
  24. // For the CBaseClusterAction class
  25. #include "CBaseClusterAction.h"
  26. // For g_GenericSetupQueueCallback and other global functions
  27. #include "GlobalFuncs.h"
  28. // For CEnableThreadPrivilege
  29. #include "CEnableThreadPrivilege.h"
  30. // For ClRtlSetObjSecurityInfo() and other functions.
  31. #include "clusrtl.h"
  32. //////////////////////////////////////////////////////////////////////////
  33. // Macros definitions
  34. //////////////////////////////////////////////////////////////////////////
  35. // Section in the INF file that deals with cleaning up the cluster database
  36. #define CLUSDB_CLEANUP_INF_SECTION_NAME L"ClusDB_Cleanup"
  37. //////////////////////////////////////////////////////////////////////////////
  38. //++
  39. //
  40. // CClusDB::CClusDB()
  41. //
  42. // Description:
  43. // Constructor of the CClusDB class
  44. //
  45. // Arguments:
  46. // pbcaParentActionIn
  47. // Pointer to the base cluster action of which this action is a part.
  48. //
  49. // Return Value:
  50. // None.
  51. //
  52. // Exceptions Thrown:
  53. // CAssert
  54. // If the parameters are incorrect.
  55. //
  56. // Any exceptions thrown by underlying functions
  57. //
  58. //--
  59. //////////////////////////////////////////////////////////////////////////////
  60. CClusDB::CClusDB(
  61. CBaseClusterAction * pbcaParentActionIn
  62. )
  63. : m_pbcaParentAction( pbcaParentActionIn )
  64. {
  65. BCATraceScope( "" );
  66. if ( m_pbcaParentAction == NULL)
  67. {
  68. BCATraceMsg( "Pointers to the parent action is NULL. Throwing exception." );
  69. THROW_ASSERT(
  70. E_INVALIDARG
  71. , "CClusDB::CClusDB() => Required input pointer in NULL"
  72. );
  73. } // if: the parent action pointer is NULL
  74. } //*** CClusDB::CClusDB()
  75. //////////////////////////////////////////////////////////////////////////////
  76. //++
  77. //
  78. // CClusDB::~CClusDB()
  79. //
  80. // Description:
  81. // Destructor of the CClusDB class.
  82. //
  83. // Arguments:
  84. // None.
  85. //
  86. // Return Value:
  87. // None.
  88. //
  89. // Exceptions Thrown:
  90. // Any exceptions thrown by underlying functions
  91. //
  92. //--
  93. //////////////////////////////////////////////////////////////////////////////
  94. CClusDB::~CClusDB( void )
  95. {
  96. BCATraceScope( "" );
  97. } //*** CClusDB::~CClusDB()
  98. //////////////////////////////////////////////////////////////////////////////
  99. //++
  100. //
  101. // void
  102. // CClusDB::CreateHive()
  103. //
  104. // Description:
  105. // Creates the cluster cluster hive in the registry.
  106. //
  107. // Arguments:
  108. // pbcaClusterActionIn
  109. // Pointer to the CBaseClusterAction object which contains this object.
  110. //
  111. // Return Value:
  112. // None.
  113. //
  114. // Exceptions Thrown:
  115. // CRuntimeError
  116. // If any of the APIs fail.
  117. //
  118. // Any that are thrown by the called functions.
  119. //
  120. //--
  121. //////////////////////////////////////////////////////////////////////////////
  122. void
  123. CClusDB::CreateHive( CBaseClusterAction * pbcaClusterActionIn )
  124. {
  125. BCATraceScope( "" );
  126. LogMsg( "Attempting to create the cluster hive in the registry." );
  127. OBJECT_ATTRIBUTES oaClusterHiveKey;
  128. OBJECT_ATTRIBUTES oaClusterHiveFile;
  129. HRESULT hrStatus = STATUS_SUCCESS;
  130. do
  131. {
  132. CStr strClusterHiveFileName( pbcaClusterActionIn->RStrGetClusterInstallDirectory() );
  133. UNICODE_STRING ustrClusterHiveFileName;
  134. UNICODE_STRING ustrClusterHiveKeyName;
  135. strClusterHiveFileName += L"\\" CLUSTER_DATABASE_NAME;
  136. BCATraceMsg1( "The cluster hive backing file is '%s'.", strClusterHiveFileName.PszData() );
  137. //
  138. // Enable the SE_RESTORE_PRIVILEGE.
  139. //
  140. // What we are doing here is that we are creating an object of
  141. // type CEnableThreadPrivilege. This object enables the privilege
  142. // in the constructor and restores it to its original state in the destructor.
  143. //
  144. CEnableThreadPrivilege etpAcquireRestorePrivilege( SE_RESTORE_NAME );
  145. //
  146. // Convert the DOS file name to NT file name.
  147. // WARNING: This function call allocates memory in the RTL heap and it is not being
  148. // assigned to a smart pointer. Make sure that we do not call any functions that
  149. // could throw an exception till this memory is freed.
  150. //
  151. if ( RtlDosPathNameToNtPathName_U(
  152. strClusterHiveFileName.PszData()
  153. , &ustrClusterHiveFileName
  154. , NULL
  155. , NULL
  156. )
  157. == FALSE
  158. )
  159. {
  160. BCATraceMsg1( "RtlDosPathNameToNtPathName failed. Making up error code %#08x.", STATUS_OBJECT_PATH_INVALID );
  161. // Use the most appropriate error code.
  162. hrStatus = STATUS_OBJECT_PATH_INVALID;
  163. break;
  164. } // if: we could not convert from the dos file name to the nt file name
  165. InitializeObjectAttributes(
  166. &oaClusterHiveFile
  167. , &ustrClusterHiveFileName
  168. , OBJ_CASE_INSENSITIVE
  169. , NULL
  170. , NULL
  171. );
  172. RtlInitUnicodeString( &ustrClusterHiveKeyName, L"\\Registry\\Machine\\" CLUSREG_KEYNAME_CLUSTER );
  173. InitializeObjectAttributes(
  174. &oaClusterHiveKey
  175. , &ustrClusterHiveKeyName
  176. , OBJ_CASE_INSENSITIVE
  177. , NULL
  178. , NULL
  179. );
  180. //
  181. // This function creates an empty hive and the backing file and log. The calling thread must
  182. // have the SE_RESTORE_PRIVILEGE privilege enabled.
  183. //
  184. hrStatus = THR( NtLoadKey2( &oaClusterHiveKey, &oaClusterHiveFile, REG_NO_LAZY_FLUSH ) );
  185. // Free allocated memory before throwing exception.
  186. RtlFreeHeap( RtlProcessHeap(), 0, ustrClusterHiveFileName.Buffer );
  187. if ( NT_ERROR( hrStatus ) )
  188. {
  189. BCATraceMsg1( "NtLoadKey2 returned error code %#08x.", hrStatus );
  190. break;
  191. } // if: something went wrong with NtLoadKey2
  192. BCATraceMsg( "NtLoadKey2 was successful." );
  193. // Set the security descriptor on the hive.
  194. {
  195. DWORD dwError;
  196. // Open the cluster hive key.
  197. CRegistryKey rkClusterHive( HKEY_LOCAL_MACHINE, CLUSREG_KEYNAME_CLUSTER, KEY_ALL_ACCESS );
  198. dwError = TW32( ClRtlSetObjSecurityInfo(
  199. rkClusterHive.HGetKey()
  200. , SE_REGISTRY_KEY
  201. , KEY_ALL_ACCESS
  202. , KEY_ALL_ACCESS
  203. , KEY_READ
  204. ) );
  205. if ( dwError != ERROR_SUCCESS )
  206. {
  207. hrStatus = HRESULT_FROM_WIN32( dwError );
  208. BCATraceMsg1( "Error %#08x occurred trying set the cluster hive security.", hrStatus );
  209. break;
  210. } // if: ClRtlSetObjSecurityInfo failed
  211. // Flush the changes to the registry.
  212. RegFlushKey( rkClusterHive.HGetKey() );
  213. }
  214. // At this point, the cluster hive has been created.
  215. LogMsg( "The cluster hive has been created." );
  216. }
  217. while( false ); // dummy do-while loop to avoid gotos.
  218. if ( NT_ERROR( hrStatus ) )
  219. {
  220. LogMsg( "Error %#08x occurred trying to create the cluster hive.", hrStatus );
  221. BCATraceMsg1( "Error %#08x occurred trying to create the cluster hive. Throwing exception.", hrStatus );
  222. THROW_RUNTIME_ERROR(
  223. hrStatus
  224. , IDS_ERROR_CLUSDB_CREATE_HIVE
  225. );
  226. } // if: something went wrong.
  227. } //*** CClusDB::CreateHive()
  228. //////////////////////////////////////////////////////////////////////////////
  229. //++
  230. //
  231. // void
  232. // CClusDB::CleanupHive()
  233. //
  234. // Description:
  235. // Unload the cluster hive and delete the cluster database.
  236. //
  237. // Arguments:
  238. // None.
  239. //
  240. // Return Value:
  241. // None.
  242. //
  243. // Exceptions Thrown:
  244. // CRuntimeError
  245. // If any of the APIs fail.
  246. //
  247. //--
  248. //////////////////////////////////////////////////////////////////////////////
  249. void
  250. CClusDB::CleanupHive( void )
  251. {
  252. BCATraceScope( "" );
  253. DWORD dwError = ERROR_SUCCESS;
  254. do
  255. {
  256. HKEY hTempKey;
  257. // Check if the cluster hive is loaded before attempting to unload it.
  258. if ( RegOpenKeyEx(
  259. HKEY_LOCAL_MACHINE
  260. , CLUSREG_KEYNAME_CLUSTER
  261. , 0
  262. , KEY_READ
  263. , &hTempKey
  264. )
  265. == ERROR_SUCCESS
  266. )
  267. {
  268. RegCloseKey( hTempKey );
  269. //
  270. // Enable the SE_RESTORE_PRIVILEGE.
  271. //
  272. // What we are doing here is that we are creating an object of
  273. // type CEnableThreadPrivilege. This object enables the privilege
  274. // in the constructor and restores it to its original state in the destructor.
  275. //
  276. CEnableThreadPrivilege etpAcquireRestorePrivilege( SE_RESTORE_NAME );
  277. //
  278. // Unload the cluster hive, so that it can be deleted. Note, thread must
  279. // have SE_RESTORE_PRIVILEGE enabled.
  280. //
  281. dwError = RegUnLoadKey(
  282. HKEY_LOCAL_MACHINE
  283. , CLUSREG_KEYNAME_CLUSTER
  284. );
  285. // MUSTDO: Check if ERROR_FILE_NOT_FOUND is an acceptable return value.
  286. if ( dwError != ERROR_SUCCESS )
  287. {
  288. LogMsg( "Error %#08x occurred while trying to unload the cluster hive.", dwError );
  289. BCATraceMsg( "RegUnLoadKey returned an error while trying to unload the cluster hive." );
  290. break;
  291. } // if: the hive could not be unloaded.
  292. BCATraceMsg( "The cluster hive has been unloaded." );
  293. LogMsg( "The cluster hive has been unloaded." );
  294. } // if: the cluster hive is loaded
  295. else
  296. {
  297. LogMsg( "The cluster hive was not loaded." );
  298. BCATraceMsg( "The cluster hive was not loaded." );
  299. } // else: the cluster hive is not loaded
  300. //
  301. // Process ClusDB cleanup section in the INF file.
  302. // This will delete the cluster database file and the log file.
  303. //
  304. if ( SetupInstallFromInfSection(
  305. NULL // optional, handle of a parent window
  306. , m_pbcaParentAction->HGetMainInfFileHandle() // handle to the INF file
  307. , CLUSDB_CLEANUP_INF_SECTION_NAME // name of the Install section
  308. , SPINST_FILES // which lines to install from section
  309. , NULL // optional, key for registry installs
  310. , NULL // optional, path for source files
  311. , 0 // optional, specifies copy behavior
  312. , g_GenericSetupQueueCallback // optional, specifies callback routine
  313. , NULL // optional, callback routine context
  314. , NULL // optional, device information set
  315. , NULL // optional, device info structure
  316. ) == FALSE
  317. )
  318. {
  319. dwError = GetLastError();
  320. LogMsg( "Error %#08x occurred while trying to clean up the cluster database files.", dwError );
  321. BCATraceMsg( "Setup API returned an error while trying to cleanup the cluster database." );
  322. break;
  323. } // if: SetupInstallServicesFromInfSection failed
  324. LogMsg( "The cluster database files have been cleaned up." );
  325. }
  326. while( false ); // dummy do-while loop to avoid gotos
  327. if ( dwError != ERROR_SUCCESS )
  328. {
  329. LogMsg( "Error %#08x occurred while trying to cleanup the cluster database.", dwError );
  330. BCATraceMsg1( "Error %#08x occurred while trying to cleanup the cluster database. Throwing exception.", dwError );
  331. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_CLUSDB_CLEANUP );
  332. }
  333. } //*** CClusDB::CleanupHive()