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.

473 lines
17 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CTaskUpgradeNT4.cpp
  7. //
  8. // Description:
  9. // Implementation file for the CTaskUpgradeNT4 class.
  10. //
  11. // Header File:
  12. // CTaskUpgradeNT4.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 "CTaskUpgradeNT4.h"
  26. //////////////////////////////////////////////////////////////////////////////
  27. // Macro Definitions
  28. //////////////////////////////////////////////////////////////////////////////
  29. // Needed for tracing.
  30. DEFINE_THISCLASS( "CTaskUpgradeNT4" )
  31. // Name of the cluster service executable
  32. #define CLUSSVC_EXECUTABLE_NAME L"ClusSvc.exe"
  33. // Multi-sz string of cluster service dependencies
  34. #define CLUSSVC_DEPENDENCY_MULTISZ L"ClusNet\0RpcSs\0W32Time\0NetMan"
  35. /////////////////////////////////////////////////////////////////////////////
  36. //++
  37. //
  38. // CTaskUpgradeNT4::CTaskUpgradeNT4
  39. //
  40. // Description:
  41. // Constructor of the CTaskUpgradeNT4 class.
  42. //
  43. // Arguments:
  44. // const CClusOCMApp & rAppIn
  45. // Reference to the CClusOCMApp object that is hosting this task.
  46. //
  47. // Return Value:
  48. // None.
  49. //
  50. //--
  51. /////////////////////////////////////////////////////////////////////////////
  52. CTaskUpgradeNT4::CTaskUpgradeNT4( const CClusOCMApp & rAppIn )
  53. : BaseClass( rAppIn )
  54. {
  55. TraceFunc( "" );
  56. TraceFuncExit();
  57. } //*** CTaskUpgradeNT4::CTaskUpgradeNT4()
  58. /////////////////////////////////////////////////////////////////////////////
  59. //++
  60. //
  61. // CTaskUpgradeNT4::~CTaskUpgradeNT4
  62. //
  63. // Description:
  64. // Destructor of the CTaskUpgradeNT4 class.
  65. //
  66. // Arguments:
  67. // None.
  68. //
  69. // Return Value:
  70. // None.
  71. //
  72. //--
  73. /////////////////////////////////////////////////////////////////////////////
  74. CTaskUpgradeNT4::~CTaskUpgradeNT4( void )
  75. {
  76. TraceFunc( "" );
  77. TraceFuncExit();
  78. } //*** CTaskUpgradeNT4::~CTaskUpgradeNT4()
  79. /////////////////////////////////////////////////////////////////////////////
  80. //++
  81. //
  82. // DWORD
  83. // CTaskUpgradeNT4::DwOcQueueFileOps
  84. //
  85. // Description:
  86. // This function handles the OC_QUEUE_FILE_OPS messages from the Optional
  87. // Components Manager. It installs the files needed for an upgrade from
  88. // Windows 2000.
  89. //
  90. // Arguments:
  91. // HSPFILEQ hSetupFileQueueIn
  92. // Handle to the file queue to operate upon.
  93. //
  94. // Return Value:
  95. // NO_ERROR if all went well.
  96. // Other Win32 error codes on failure.
  97. //
  98. //--
  99. /////////////////////////////////////////////////////////////////////////////
  100. DWORD
  101. CTaskUpgradeNT4::DwOcQueueFileOps( HSPFILEQ hSetupFileQueueIn )
  102. {
  103. TraceFunc( "" );
  104. LogMsg( "Entering " __FUNCTION__ "()" );
  105. DWORD dwReturnValue = NO_ERROR;
  106. // The base class helper function does everything that we need to do here.
  107. // So, just call it.
  108. dwReturnValue = TW32( BaseClass::DwOcQueueFileOps( hSetupFileQueueIn, INF_SECTION_NT4_UPGRADE ) );
  109. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  110. LogMsg( "Return Value is %#x.", dwReturnValue );
  111. RETURN( dwReturnValue );
  112. } //*** CTaskUpgradeNT4::DwOcQueueFileOps()
  113. /////////////////////////////////////////////////////////////////////////////
  114. //++
  115. //
  116. // DWORD
  117. // CTaskUpgradeNT4::DwOcCompleteInstallation
  118. //
  119. // Description:
  120. // This function handles the OC_COMPLETE_INSTALLATION messages from the
  121. // Optional Components Manager during an upgrade from Windows 2000.
  122. //
  123. // Registry operations, COM component registrations, creation of servies
  124. // etc. are performed in this function.
  125. //
  126. // Arguments:
  127. // None.
  128. //
  129. // Return Value:
  130. // NO_ERROR if all went well.
  131. // Other Win32 error codes on failure.
  132. //
  133. //--
  134. /////////////////////////////////////////////////////////////////////////////
  135. DWORD
  136. CTaskUpgradeNT4::DwOcCompleteInstallation( void )
  137. {
  138. TraceFunc( "" );
  139. LogMsg( "Entering " __FUNCTION__ "()" );
  140. DWORD dwReturnValue = NO_ERROR;
  141. // Call the base class helper function to perform some registry and service
  142. // related configuration from the INF file.
  143. dwReturnValue = TW32( BaseClass::DwOcCompleteInstallation( INF_SECTION_NT4_UPGRADE ) );
  144. //
  145. // Change the cluster service display name, description, dependencies, failure actions
  146. // and executable name.
  147. //
  148. while( dwReturnValue == NO_ERROR )
  149. {
  150. // Pointer the the cluster service directory.
  151. const WCHAR * pcszInstallDir = NULL;
  152. // Smart pointer to the cluster service display name string.
  153. SmartSz sszClusSvcDispName;
  154. // Smart pointer to the cluster service description string.
  155. SmartSz sszClusSvcDesc;
  156. // Smart pointer to the cluster service binary path string.
  157. SmartSz sszClusSvcBinPath;
  158. // Smart pointer to the cluster service.
  159. SmartServiceHandle shClusSvc;
  160. // Connect to the Service Control Manager
  161. SmartServiceHandle shServiceMgr( OpenSCManager( NULL, NULL, GENERIC_READ | GENERIC_WRITE ) );
  162. if ( shServiceMgr.HHandle() == NULL )
  163. {
  164. dwReturnValue = TW32( GetLastError() );
  165. TraceFlow1( "Error %#x occurred trying to open a connection to the local service control manager.", dwReturnValue );
  166. LogMsg( "Error %#x occurred trying to open a connection to the local service control manager.", dwReturnValue );
  167. break;
  168. } // if: opening the SCM was unsuccessful
  169. TraceFlow( "Opened a handle to the service control manager." );
  170. // Open a handle to the Cluster Service.
  171. shClusSvc.Assign( OpenService( shServiceMgr, L"ClusSvc", SERVICE_ALL_ACCESS ) );
  172. if ( shClusSvc.HHandle() == NULL )
  173. {
  174. dwReturnValue = TW32( GetLastError() );
  175. TraceFlow1( "Error %#x occurred trying to open a handle to the cluster service.", dwReturnValue );
  176. LogMsg( "Error %#x occurred trying to open a handle to the cluster service.", dwReturnValue );
  177. break;
  178. } // if: the handle could not be opened
  179. TraceFlow( "Opened a handle to the cluster service." );
  180. // Load the cluster service name string.
  181. dwReturnValue = DwLoadString( IDS_CLUSSVC_DISPLAY_NAME, sszClusSvcDispName );
  182. if ( dwReturnValue != ERROR_SUCCESS )
  183. {
  184. TraceFlow1( "Error %#x occurred trying load the display name of the cluster service.", dwReturnValue );
  185. LogMsg( "Error %#x occurred trying load the display name of the cluster service.", dwReturnValue );
  186. break;
  187. } // if: we could not load the cluster service display name string
  188. TraceFlow1( "The new cluster service display name is '%s'.", sszClusSvcDispName.PMem() );
  189. // Load the cluster service description string.
  190. dwReturnValue = DwLoadString( IDS_CLUSSVC_SERVICE_DESC, sszClusSvcDesc );
  191. if ( dwReturnValue != ERROR_SUCCESS )
  192. {
  193. TraceFlow1( "Error %#x occurred trying load the description of the cluster service.", dwReturnValue );
  194. LogMsg( "Error %#x occurred trying load the description of the cluster service.", dwReturnValue );
  195. break;
  196. } // if: we could not load the cluster service description string
  197. TraceFlow1( "The new cluster service description is '%s'.", sszClusSvcDesc.PMem() );
  198. //
  199. // Form the service binary path by appending the name of the cluster service executable to
  200. // the cluster service directory.
  201. //
  202. // Do not free the pointer returned by this call.
  203. dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) );
  204. if ( dwReturnValue != NO_ERROR )
  205. {
  206. TraceFlow1( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  207. LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  208. break;
  209. } // if: we could not get the cluster service installation directory
  210. TraceFlow1( "The cluster service directory is '%ws'.", pcszInstallDir );
  211. {
  212. WCHAR * pszTempPtr;
  213. // Length of the the install directory string, not including the terminating L'\0'
  214. size_t cchInstallDirLen = wcslen( pcszInstallDir );
  215. // Length of the cluster service executable name, including the terminating L'\0'
  216. size_t cchClusSvcExeLen = sizeof( CLUSSVC_EXECUTABLE_NAME ) / sizeof( WCHAR );
  217. // Allocate memory for the cluster service binary path (the extra character is for the intervening L'\\'.
  218. sszClusSvcBinPath.Assign( new WCHAR[ cchInstallDirLen + 1 + cchClusSvcExeLen ] );
  219. if ( sszClusSvcBinPath.FIsEmpty() )
  220. {
  221. dwReturnValue = TW32( ERROR_NOT_ENOUGH_MEMORY );
  222. TraceFlow( "An error occurred trying to allocate memory for the cluster service binary path." );
  223. LogMsg( "An error occurred trying to allocate memory for the cluster service binary path." );
  224. break;
  225. } // if: an error occurred trying to allocate memory for the cluster service binary path
  226. pszTempPtr = sszClusSvcBinPath.PMem();
  227. // Copy the install directory string to the newly allocated buffer.
  228. wcsncpy( pszTempPtr, pcszInstallDir, cchInstallDirLen );
  229. pszTempPtr += cchInstallDirLen;
  230. // Copy the trailing L'\\' character
  231. *pszTempPtr = L'\\';
  232. ++pszTempPtr;
  233. // Copy the cluster service executable name.
  234. wcsncpy( pszTempPtr, CLUSSVC_EXECUTABLE_NAME, cchClusSvcExeLen );
  235. TraceFlow1( "The new cluster service binary path is '%s'.", sszClusSvcBinPath.PMem() );
  236. }
  237. // Change the binary path, dependency list and display name.
  238. if ( ChangeServiceConfig(
  239. shClusSvc.HHandle() // handle to service
  240. , SERVICE_NO_CHANGE // type of service
  241. , SERVICE_NO_CHANGE // when to start service
  242. , SERVICE_NO_CHANGE // severity of start failure
  243. , sszClusSvcBinPath.PMem() // service binary file name
  244. , NULL // load ordering group name
  245. , NULL // tag identifier
  246. , CLUSSVC_DEPENDENCY_MULTISZ // array of dependency names
  247. , NULL // account name
  248. , NULL // account password
  249. , sszClusSvcDispName.PMem() // display name
  250. )
  251. == FALSE
  252. )
  253. {
  254. dwReturnValue = TW32( GetLastError() );
  255. TraceFlow1( "Error %#x occurred trying to change the cluster service configuration.", dwReturnValue );
  256. LogMsg( "Error %#x occurred trying to change the cluster service configuration.", dwReturnValue );
  257. break;
  258. } // if: ChangeServiceConfig() failed
  259. TraceFlow( "The cluster service binary path, dependency list and display name have been changed." );
  260. // Change the service description
  261. {
  262. SERVICE_DESCRIPTION sdServiceDescription;
  263. sdServiceDescription.lpDescription = sszClusSvcDesc.PMem();
  264. if ( ChangeServiceConfig2(
  265. shClusSvc.HHandle() // handle to service
  266. , SERVICE_CONFIG_DESCRIPTION // information level
  267. , &sdServiceDescription // new data
  268. )
  269. == FALSE
  270. )
  271. {
  272. dwReturnValue = TW32( GetLastError() );
  273. TraceFlow1( "Error %#x occurred trying to change the cluster service description.", dwReturnValue );
  274. LogMsg( "Error %#x occurred trying to change the cluster service description.", dwReturnValue );
  275. break;
  276. } // if: ChangeServiceConfig2() failed
  277. }
  278. TraceFlow( "The cluster service description has been changed." );
  279. // Change the cluster service failure actions.
  280. dwReturnValue = TW32( ClRtlSetSCMFailureActions( NULL ) );
  281. if ( dwReturnValue != ERROR_SUCCESS )
  282. {
  283. TraceFlow1( "Error %#x occurred trying to set the cluster service failure actions.", dwReturnValue );
  284. LogMsg( "Error %#x occurred trying to set the cluster service failure actions.", dwReturnValue );
  285. break;
  286. } // if: ClRtlSetSCMFailureActions() failed
  287. TraceFlow( "The cluster service failure actions have been changed." );
  288. LogMsg( "The cluster service configuration has been changed." );
  289. break;
  290. } // while: the call to the base class function has succeeded
  291. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  292. LogMsg( "Return Value is %#x.", dwReturnValue );
  293. RETURN( dwReturnValue );
  294. } //*** CTaskUpgradeNT4::DwOcCompleteInstallation()
  295. /////////////////////////////////////////////////////////////////////////////
  296. //++
  297. //
  298. // DWORD
  299. // CTaskUpgradeNT4::DwOcCleanup
  300. //
  301. // Description:
  302. // This function handles the OC_CLEANUP messages from the
  303. // Optional Components Manager during an upgrade from Windows 2000.
  304. //
  305. // If an error has previously occurred during this task, cleanup operations
  306. // are performed. Otherwise nothing is done by this function.
  307. //
  308. // Arguments:
  309. // None.
  310. //
  311. // Return Value:
  312. // NO_ERROR if all went well.
  313. // Other Win32 error codes on failure.
  314. //
  315. //--
  316. /////////////////////////////////////////////////////////////////////////////
  317. DWORD
  318. CTaskUpgradeNT4::DwOcCleanup( void )
  319. {
  320. TraceFunc( "" );
  321. LogMsg( "Entering " __FUNCTION__ "()" );
  322. DWORD dwReturnValue = NO_ERROR;
  323. // The base class helper function does everything that we need to do here.
  324. // So, just call it.
  325. dwReturnValue = TW32( BaseClass::DwOcCleanup( INF_SECTION_NT4_UPGRADE_CLEANUP ) );
  326. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  327. LogMsg( "Return Value is %#x.", dwReturnValue );
  328. RETURN( dwReturnValue );
  329. } //*** CTaskUpgradeNT4::DwOcCleanup()
  330. /////////////////////////////////////////////////////////////////////////////
  331. //++
  332. //
  333. // DWORD
  334. // CTaskUpgradeNT4::DwSetDirectoryIds
  335. //
  336. // Description:
  337. // This function maps ids specified in the INF file to directories.
  338. // The cluster installation directory is got from the service control
  339. // manager, since it is possible the the cluster binaries are installed
  340. // in a non-default location.
  341. //
  342. // Arguments:
  343. // None.
  344. //
  345. // Return Value:
  346. // NO_ERROR if all went well.
  347. // Other Win32 error codes on failure.
  348. //
  349. //--
  350. /////////////////////////////////////////////////////////////////////////////
  351. DWORD
  352. CTaskUpgradeNT4::DwSetDirectoryIds()
  353. {
  354. TraceFunc( "" );
  355. LogMsg( "Entering " __FUNCTION__ "()" );
  356. DWORD dwReturnValue = NO_ERROR;
  357. do
  358. {
  359. const WCHAR * pcszInstallDir = NULL;
  360. // If we are here, the this node is already a part of a cluster. So, get the
  361. // installation directory from SCM.
  362. TraceFlow( "This node is part of a cluster. Trying to determine the installation directory." );
  363. LogMsg( "This node is part of a cluster. Trying to determine the installation directory." );
  364. // Do not free the pointer returned by this call.
  365. dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) );
  366. if ( dwReturnValue != NO_ERROR )
  367. {
  368. TraceFlow1( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  369. LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  370. break;
  371. } // if: we could not get the cluster service installation directory
  372. TraceFlow1( "The cluster binaries are installed in the directory '%ws'.", pcszInstallDir );
  373. LogMsg( "The cluster binaries are installed in the directory '%ws'.", pcszInstallDir );
  374. // Create the mapping between the directory id and the path
  375. if ( SetupSetDirectoryId(
  376. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  377. , CLUSTER_DEFAULT_INSTALL_DIRID
  378. , pcszInstallDir
  379. )
  380. == FALSE
  381. )
  382. {
  383. dwReturnValue = TW32( GetLastError() );
  384. TraceFlow1( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue );
  385. LogMsg( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue );
  386. break;
  387. } // if: SetupSetDirectoryId() failed
  388. TraceFlow2( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, pcszInstallDir );
  389. LogMsg( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, pcszInstallDir );
  390. }
  391. while ( false ); // dummy do-while loop to avoid gotos
  392. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  393. LogMsg( "Return Value is %#x.", dwReturnValue );
  394. RETURN( dwReturnValue );
  395. } //*** CTaskUpgradeNT4::DwSetDirectoryIds()