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.

398 lines
14 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CTaskUpgradeWhistler.cpp
  7. //
  8. // Description:
  9. // Implementation file for the CTaskUpgradeWhistler class.
  10. //
  11. // Header File:
  12. // CTaskUpgradeWhistler.h
  13. //
  14. // Maintained By:
  15. // Vij Vasu (Vvasu) 18-APR-2000
  16. // Created this file.
  17. //
  18. //////////////////////////////////////////////////////////////////////////////
  19. //////////////////////////////////////////////////////////////////////////////
  20. // Include Files
  21. //////////////////////////////////////////////////////////////////////////////
  22. // Precompiled header for this DLL.
  23. #include "pch.h"
  24. // The header file for this module.
  25. #include "CTaskUpgradeWhistler.h"
  26. //////////////////////////////////////////////////////////////////////////////
  27. // Macro Definitions
  28. //////////////////////////////////////////////////////////////////////////////
  29. // Needed for tracing.
  30. DEFINE_THISCLASS( "CTaskUpgradeWhistler" )
  31. /////////////////////////////////////////////////////////////////////////////
  32. //++
  33. //
  34. // CTaskUpgradeWhistler::CTaskUpgradeWhistler
  35. //
  36. // Description:
  37. // Constructor of the CTaskUpgradeWhistler class.
  38. //
  39. // Arguments:
  40. // const CClusOCMApp & rAppIn
  41. // Reference to the CClusOCMApp object that is hosting this task.
  42. //
  43. // Return Value:
  44. // None.
  45. //
  46. //--
  47. /////////////////////////////////////////////////////////////////////////////
  48. CTaskUpgradeWhistler::CTaskUpgradeWhistler( const CClusOCMApp & rAppIn )
  49. : BaseClass( rAppIn )
  50. {
  51. TraceFunc( "" );
  52. TraceFuncExit();
  53. } //*** CTaskUpgradeWhistler::CTaskUpgradeWhistler()
  54. /////////////////////////////////////////////////////////////////////////////
  55. //++
  56. //
  57. // CTaskUpgradeWhistler::~CTaskUpgradeWhistler
  58. //
  59. // Description:
  60. // Destructor of the CTaskUpgradeWhistler class.
  61. //
  62. // Arguments:
  63. // None.
  64. //
  65. // Return Value:
  66. // None.
  67. //
  68. //--
  69. /////////////////////////////////////////////////////////////////////////////
  70. CTaskUpgradeWhistler::~CTaskUpgradeWhistler( void )
  71. {
  72. TraceFunc( "" );
  73. TraceFuncExit();
  74. } //*** CTaskUpgradeWhistler::~CTaskUpgradeWhistler()
  75. /////////////////////////////////////////////////////////////////////////////
  76. //++
  77. //
  78. // DWORD
  79. // CTaskUpgradeWhistler::DwOcQueueFileOps
  80. //
  81. // Description:
  82. // This function handles the OC_QUEUE_FILE_OPS messages from the Optional
  83. // Components Manager. It installs the files needed for an upgrade from
  84. // Windows 2000.
  85. //
  86. // Arguments:
  87. // HSPFILEQ hSetupFileQueueIn
  88. // Handle to the file queue to operate upon.
  89. //
  90. // Return Value:
  91. // NO_ERROR if all went well.
  92. // Other Win32 error codes on failure.
  93. //
  94. //--
  95. /////////////////////////////////////////////////////////////////////////////
  96. DWORD
  97. CTaskUpgradeWhistler::DwOcQueueFileOps( HSPFILEQ hSetupFileQueueIn )
  98. {
  99. TraceFunc( "" );
  100. LogMsg( "Entering " __FUNCTION__ "()" );
  101. DWORD dwReturnValue = NO_ERROR;
  102. // Do different things based on whether this node is already part of a cluster or not.
  103. if ( RGetApp().CisGetClusterInstallState() == eClusterInstallStateFilesCopied )
  104. {
  105. TraceFlow( "The cluster binaries are installed, but this node is not part of a cluster." );
  106. LogMsg( "The cluster binaries are installed, but this node is not part of a cluster." );
  107. // The base class helper function does everything that we need to do here.
  108. // So, just call it.
  109. dwReturnValue = TW32( BaseClass::DwOcQueueFileOps( hSetupFileQueueIn, INF_SECTION_WHISTLER_UPGRADE_UNCLUSTERED_NODE ) );
  110. } // if: the node is not part of a cluster
  111. else
  112. {
  113. TraceFlow( "This node is part of a cluster." );
  114. LogMsg( "This node is part of a cluster." );
  115. // The base class helper function does everything that we need to do here.
  116. // So, just call it.
  117. dwReturnValue = TW32( BaseClass::DwOcQueueFileOps( hSetupFileQueueIn, INF_SECTION_WHISTLER_UPGRADE ) );
  118. } // else: the node is part of a cluster
  119. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  120. LogMsg( "Return Value is %#x.", dwReturnValue );
  121. RETURN( dwReturnValue );
  122. } //*** CTaskUpgradeWhistler::DwOcQueueFileOps()
  123. /////////////////////////////////////////////////////////////////////////////
  124. //++
  125. //
  126. // DWORD
  127. // CTaskUpgradeWhistler::DwOcCompleteInstallation
  128. //
  129. // Description:
  130. // This function handles the OC_COMPLETE_INSTALLATION messages from the
  131. // Optional Components Manager during an upgrade from Windows 2000.
  132. //
  133. // Registry operations, COM component registrations, creation of servies
  134. // etc. are performed in this function.
  135. //
  136. // Arguments:
  137. // None.
  138. //
  139. // Return Value:
  140. // NO_ERROR if all went well.
  141. // Other Win32 error codes on failure.
  142. //
  143. //--
  144. /////////////////////////////////////////////////////////////////////////////
  145. DWORD
  146. CTaskUpgradeWhistler::DwOcCompleteInstallation( void )
  147. {
  148. TraceFunc( "" );
  149. LogMsg( "Entering " __FUNCTION__ "()" );
  150. DWORD dwReturnValue = NO_ERROR;
  151. // Do different things based on whether this node is already part of a cluster or not.
  152. if ( RGetApp().CisGetClusterInstallState() == eClusterInstallStateFilesCopied )
  153. {
  154. TraceFlow( "The cluster binaries are installed, but this node is not part of a cluster." );
  155. LogMsg( "The cluster binaries are installed, but this node is not part of a cluster." );
  156. // The base class helper function does everything that we need to do here.
  157. // So, just call it.
  158. dwReturnValue = TW32( BaseClass::DwOcCompleteInstallation( INF_SECTION_WHISTLER_UPGRADE_UNCLUSTERED_NODE ) );
  159. } // if: the node is not part of a cluster
  160. else
  161. {
  162. TraceFlow( "This node is part of a cluster." );
  163. LogMsg( "This node is part of a cluster." );
  164. // The base class helper function does everything that we need to do here.
  165. // So, just call it.
  166. dwReturnValue = TW32( BaseClass::DwOcCompleteInstallation( INF_SECTION_WHISTLER_UPGRADE ) );
  167. } // else: the node is part of a cluster
  168. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  169. LogMsg( "Return Value is %#x.", dwReturnValue );
  170. RETURN( dwReturnValue );
  171. } //*** CTaskUpgradeWhistler::DwOcCompleteInstallation()
  172. /////////////////////////////////////////////////////////////////////////////
  173. //++
  174. //
  175. // DWORD
  176. // CTaskUpgradeWhistler::DwOcCleanup
  177. //
  178. // Description:
  179. // This function handles the OC_CLEANUP messages from the
  180. // Optional Components Manager during an upgrade from Windows 2000.
  181. //
  182. // If an error has previously occurred during this task, cleanup operations
  183. // are performed. Otherwise nothing is done by this function.
  184. //
  185. // Arguments:
  186. // None.
  187. //
  188. // Return Value:
  189. // NO_ERROR if all went well.
  190. // Other Win32 error codes on failure.
  191. //
  192. //--
  193. /////////////////////////////////////////////////////////////////////////////
  194. DWORD
  195. CTaskUpgradeWhistler::DwOcCleanup( void )
  196. {
  197. TraceFunc( "" );
  198. LogMsg( "Entering " __FUNCTION__ "()" );
  199. DWORD dwReturnValue = NO_ERROR;
  200. // Do different things based on whether this node is already part of a cluster or not.
  201. if ( RGetApp().CisGetClusterInstallState() == eClusterInstallStateFilesCopied )
  202. {
  203. TraceFlow( "The cluster binaries are installed, but this node is not part of a cluster." );
  204. LogMsg( "The cluster binaries are installed, but this node is not part of a cluster." );
  205. // The base class helper function does everything that we need to do here.
  206. // So, just call it.
  207. dwReturnValue = TW32( BaseClass::DwOcCleanup( INF_SECTION_WHISTLER_UPGRADE_UNCLUSTERED_NODE_CLEANUP ) );
  208. } // if: the node is not part of a cluster
  209. else
  210. {
  211. TraceFlow( "This node is part of a cluster." );
  212. LogMsg( "This node is part of a cluster." );
  213. // The base class helper function does everything that we need to do here.
  214. // So, just call it.
  215. dwReturnValue = TW32( BaseClass::DwOcCleanup( INF_SECTION_WHISTLER_UPGRADE_CLEANUP ) );
  216. } // else: the node is part of a cluster
  217. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  218. LogMsg( "Return Value is %#x.", dwReturnValue );
  219. RETURN( dwReturnValue );
  220. } //*** CTaskUpgradeWhistler::DwOcCleanup()
  221. /////////////////////////////////////////////////////////////////////////////
  222. //++
  223. //
  224. // DWORD
  225. // CTaskUpgradeWhistler::DwSetDirectoryIds
  226. //
  227. // Description:
  228. // This function maps ids specified in the INF file to directories.
  229. // The location of the cluster binaries is read from the registry
  230. // and the cluster installation directory is mapped to this value.
  231. //
  232. // Arguments:
  233. // None.
  234. //
  235. // Return Value:
  236. // NO_ERROR if all went well.
  237. // Other Win32 error codes on failure.
  238. //
  239. //--
  240. /////////////////////////////////////////////////////////////////////////////
  241. DWORD
  242. CTaskUpgradeWhistler::DwSetDirectoryIds()
  243. {
  244. TraceFunc( "" );
  245. LogMsg( "Entering " __FUNCTION__ "()" );
  246. DWORD dwReturnValue = NO_ERROR;
  247. do
  248. {
  249. SmartRegistryKey srkNodeDataKey;
  250. SmartSz sszInstallDir;
  251. DWORD cbBufferSize = 0;
  252. DWORD dwType = REG_SZ;
  253. {
  254. HKEY hTempKey = NULL;
  255. // Open the node data registry key
  256. dwReturnValue = TW32(
  257. RegOpenKeyEx(
  258. HKEY_LOCAL_MACHINE
  259. , CLUSREG_KEYNAME_NODE_DATA
  260. , 0
  261. , KEY_READ
  262. , &hTempKey
  263. )
  264. );
  265. if ( dwReturnValue != NO_ERROR )
  266. {
  267. TraceFlow1( "Error %#x occurred trying open the registry key where the cluster install path is stored.", dwReturnValue );
  268. LogMsg( "Error %#x occurred trying open the registry key where the cluster install path is stored.", dwReturnValue );
  269. break;
  270. } // if: RegOpenKeyEx() failed
  271. // Store the opened key in a smart pointer for automatic close.
  272. srkNodeDataKey.Assign( hTempKey );
  273. }
  274. // Get the required size of the buffer.
  275. dwReturnValue = TW32(
  276. RegQueryValueEx(
  277. srkNodeDataKey.HHandle() // handle to key to query
  278. , CLUSREG_INSTALL_DIR_VALUE_NAME // name of value to query
  279. , 0 // reserved
  280. , NULL // address of buffer for value type
  281. , NULL // address of data buffer
  282. , &cbBufferSize // address of data buffer size
  283. )
  284. );
  285. if ( dwReturnValue != NO_ERROR )
  286. {
  287. TraceFlow2( "Error %#x occurred trying to read the registry value '%s'.", dwReturnValue, CLUSREG_INSTALL_DIR_VALUE_NAME );
  288. LogMsg( "Error %#x occurred trying to read the registry value '%s'.", dwReturnValue, CLUSREG_INSTALL_DIR_VALUE_NAME );
  289. break;
  290. } // if: an error occurred trying to read the CLUSREG_INSTALL_DIR_VALUE_NAME registry value
  291. // Allocate the required buffer.
  292. sszInstallDir.Assign( reinterpret_cast< WCHAR * >( new BYTE[ cbBufferSize ] ) );
  293. if ( sszInstallDir.FIsEmpty() )
  294. {
  295. TraceFlow1( "An error occurred trying to allocate %d bytes of memory.", cbBufferSize );
  296. LogMsg( "An error occurred trying to allocate %d bytes of memory.", cbBufferSize );
  297. dwReturnValue = TW32( ERROR_NOT_ENOUGH_MEMORY );
  298. break;
  299. } // if: a memory allocation failure occurred
  300. // Read the value.
  301. dwReturnValue = TW32(
  302. RegQueryValueEx(
  303. srkNodeDataKey.HHandle() // handle to key to query
  304. , CLUSREG_INSTALL_DIR_VALUE_NAME // name of value to query
  305. , 0 // reserved
  306. , &dwType // address of buffer for value type
  307. , reinterpret_cast< LPBYTE >( sszInstallDir.PMem() ) // address of data buffer
  308. , &cbBufferSize // address of data buffer size
  309. )
  310. );
  311. // Was the key read properly?
  312. if ( dwReturnValue != NO_ERROR )
  313. {
  314. TraceFlow2( "Error %#x occurred trying to read the registry value '%s'.", dwReturnValue, CLUSREG_INSTALL_DIR_VALUE_NAME );
  315. LogMsg( "Error %#x occurred trying to read the registry value '%s'.", dwReturnValue, CLUSREG_INSTALL_DIR_VALUE_NAME );
  316. break;
  317. } // if: RegQueryValueEx failed.
  318. // Create the mapping between the directory id and the path
  319. if ( SetupSetDirectoryId(
  320. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  321. , CLUSTER_DEFAULT_INSTALL_DIRID
  322. , sszInstallDir.PMem()
  323. )
  324. == FALSE
  325. )
  326. {
  327. dwReturnValue = TW32( GetLastError() );
  328. TraceFlow1( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue );
  329. LogMsg( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue );
  330. break;
  331. } // if: SetupSetDirectoryId() failed
  332. TraceFlow2( "The id %d maps to '%s'.", CLUSTER_DEFAULT_INSTALL_DIRID, sszInstallDir.PMem() );
  333. LogMsg( "The id %d maps to '%s'.", CLUSTER_DEFAULT_INSTALL_DIRID, sszInstallDir.PMem() );
  334. }
  335. while ( false ); // dummy do-while loop to avoid gotos
  336. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  337. LogMsg( "Return Value is %#x.", dwReturnValue );
  338. RETURN( dwReturnValue );
  339. } //*** CTaskUpgradeWhistler::DwSetDirectoryIds()