Leaked source code of windows server 2003
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.

454 lines
16 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 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. // David Potter (DavidP) 25-MAR-2002
  16. // Vij Vasu (Vvasu) 18-APR-2000
  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. LogMsg( "Return Value is %#x.", dwReturnValue );
  110. RETURN( dwReturnValue );
  111. } //*** CTaskUpgradeNT4::DwOcQueueFileOps()
  112. /////////////////////////////////////////////////////////////////////////////
  113. //++
  114. //
  115. // DWORD
  116. // CTaskUpgradeNT4::DwOcCompleteInstallation
  117. //
  118. // Description:
  119. // This function handles the OC_COMPLETE_INSTALLATION messages from the
  120. // Optional Components Manager during an upgrade from Windows 2000.
  121. //
  122. // Registry operations, COM component registrations, creation of servies
  123. // etc. are performed in this function.
  124. //
  125. // Arguments:
  126. // None.
  127. //
  128. // Return Value:
  129. // NO_ERROR if all went well.
  130. // Other Win32 error codes on failure.
  131. //
  132. //--
  133. /////////////////////////////////////////////////////////////////////////////
  134. DWORD
  135. CTaskUpgradeNT4::DwOcCompleteInstallation( void )
  136. {
  137. TraceFunc( "" );
  138. LogMsg( "Entering " __FUNCTION__ "()" );
  139. DWORD dwReturnValue = NO_ERROR;
  140. // Call the base class helper function to perform some registry and service
  141. // related configuration from the INF file.
  142. dwReturnValue = TW32( BaseClass::DwOcCompleteInstallation( INF_SECTION_NT4_UPGRADE ) );
  143. //
  144. // Change the cluster service display name, description, dependencies, failure actions
  145. // and executable name.
  146. //
  147. while( dwReturnValue == NO_ERROR )
  148. {
  149. // Pointer the the cluster service directory.
  150. const WCHAR * pcszInstallDir = NULL;
  151. // Smart pointer to the cluster service display name string.
  152. SmartSz sszClusSvcDispName;
  153. // Smart pointer to the cluster service description string.
  154. SmartSz sszClusSvcDesc;
  155. // Smart pointer to the cluster service binary path string.
  156. SmartSz sszClusSvcBinPath;
  157. // Smart pointer to the cluster service.
  158. SmartServiceHandle shClusSvc;
  159. // Connect to the Service Control Manager
  160. SmartServiceHandle shServiceMgr( OpenSCManager( NULL, NULL, GENERIC_READ | GENERIC_WRITE ) );
  161. if ( shServiceMgr.HHandle() == NULL )
  162. {
  163. dwReturnValue = TW32( GetLastError() );
  164. LogMsg( "Error %#x occurred trying to open a connection to the local service control manager.", dwReturnValue );
  165. break;
  166. } // if: opening the SCM was unsuccessful
  167. // Open a handle to the Cluster Service.
  168. shClusSvc.Assign( OpenService( shServiceMgr, L"ClusSvc", SERVICE_ALL_ACCESS ) );
  169. if ( shClusSvc.HHandle() == NULL )
  170. {
  171. dwReturnValue = TW32( GetLastError() );
  172. LogMsg( "Error %#x occurred trying to open a handle to the cluster service.", dwReturnValue );
  173. break;
  174. } // if: the handle could not be opened
  175. // Load the cluster service name string.
  176. dwReturnValue = DwLoadString( IDS_CLUSSVC_DISPLAY_NAME, sszClusSvcDispName );
  177. if ( dwReturnValue != ERROR_SUCCESS )
  178. {
  179. LogMsg( "Error %#x occurred trying load the display name of the cluster service.", dwReturnValue );
  180. break;
  181. } // if: we could not load the cluster service display name string
  182. LogMsg( "The new cluster service display name is '%ws'.", sszClusSvcDispName.PMem() );
  183. // Load the cluster service description string.
  184. dwReturnValue = DwLoadString( IDS_CLUSSVC_SERVICE_DESC, sszClusSvcDesc );
  185. if ( dwReturnValue != ERROR_SUCCESS )
  186. {
  187. LogMsg( "Error %#x occurred trying load the description of the cluster service.", dwReturnValue );
  188. break;
  189. } // if: we could not load the cluster service description string
  190. LogMsg( "The new cluster service description is '%ws'.", sszClusSvcDesc.PMem() );
  191. //
  192. // Form the service binary path by appending the name of the cluster service executable to
  193. // the cluster service directory.
  194. //
  195. // Do not free the pointer returned by this call.
  196. dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) );
  197. if ( dwReturnValue != NO_ERROR )
  198. {
  199. LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  200. break;
  201. } // if: we could not get the cluster service installation directory
  202. LogMsg( "The cluster service directory is '%ws'.", pcszInstallDir );
  203. {
  204. WCHAR * pszTempPtr;
  205. // Length of the the install directory string, not including the terminating L'\0'
  206. size_t cchInstallDirLen = wcslen( pcszInstallDir );
  207. // Length of the cluster service executable name, including the terminating L'\0'
  208. size_t cchClusSvcExeLen = RTL_NUMBER_OF( CLUSSVC_EXECUTABLE_NAME );
  209. size_t cchRemaining = cchInstallDirLen + 1 + cchClusSvcExeLen;
  210. // Allocate memory for the cluster service binary path (the extra character is for the intervening L'\\'.
  211. sszClusSvcBinPath.Assign( new WCHAR[ cchInstallDirLen + 1 + cchClusSvcExeLen ] );
  212. if ( sszClusSvcBinPath.FIsEmpty() )
  213. {
  214. dwReturnValue = TW32( ERROR_NOT_ENOUGH_MEMORY );
  215. LogMsg( "An error occurred trying to allocate memory for the cluster service binary path." );
  216. break;
  217. } // if: an error occurred trying to allocate memory for the cluster service binary path
  218. pszTempPtr = sszClusSvcBinPath.PMem();
  219. // Copy the install directory string to the newly allocated buffer.
  220. THR( StringCchCopyNExW( pszTempPtr, cchRemaining, pcszInstallDir, cchInstallDirLen, &pszTempPtr, &cchRemaining, 0 ) );
  221. // Copy the trailing L'\\' character
  222. *(pszTempPtr++) = L'\\';
  223. cchRemaining--;
  224. // Copy the cluster service executable name.
  225. THR( StringCchCopyNW( pszTempPtr, cchRemaining, CLUSSVC_EXECUTABLE_NAME, cchClusSvcExeLen ) );
  226. LogMsg( "The new cluster service binary path is '%ws'.", sszClusSvcBinPath.PMem() );
  227. }
  228. // Change the binary path, dependency list and display name.
  229. if ( ChangeServiceConfig(
  230. shClusSvc.HHandle() // handle to service
  231. , SERVICE_NO_CHANGE // type of service
  232. , SERVICE_NO_CHANGE // when to start service
  233. , SERVICE_NO_CHANGE // severity of start failure
  234. , sszClusSvcBinPath.PMem() // service binary file name
  235. , NULL // load ordering group name
  236. , NULL // tag identifier
  237. , CLUSSVC_DEPENDENCY_MULTISZ // array of dependency names
  238. , NULL // account name
  239. , NULL // account password
  240. , sszClusSvcDispName.PMem() // display name
  241. )
  242. == FALSE
  243. )
  244. {
  245. dwReturnValue = TW32( GetLastError() );
  246. LogMsg( "Error %#x occurred trying to change the cluster service configuration.", dwReturnValue );
  247. break;
  248. } // if: ChangeServiceConfig() failed
  249. LogMsg( "The cluster service binary path, dependency list and display name have been changed." );
  250. // Change the service description
  251. {
  252. SERVICE_DESCRIPTION sdServiceDescription;
  253. sdServiceDescription.lpDescription = sszClusSvcDesc.PMem();
  254. if ( ChangeServiceConfig2(
  255. shClusSvc.HHandle() // handle to service
  256. , SERVICE_CONFIG_DESCRIPTION // information level
  257. , &sdServiceDescription // new data
  258. )
  259. == FALSE
  260. )
  261. {
  262. dwReturnValue = TW32( GetLastError() );
  263. LogMsg( "Error %#x occurred trying to change the cluster service description.", dwReturnValue );
  264. break;
  265. } // if: ChangeServiceConfig2() failed
  266. }
  267. LogMsg( "The cluster service description has been changed." );
  268. // Change the cluster service failure actions.
  269. dwReturnValue = TW32( ClRtlSetSCMFailureActions( NULL ) );
  270. if ( dwReturnValue != ERROR_SUCCESS )
  271. {
  272. LogMsg( "Error %#x occurred trying to set the cluster service failure actions.", dwReturnValue );
  273. break;
  274. } // if: ClRtlSetSCMFailureActions() failed
  275. LogMsg( "The cluster service failure actions have been changed." );
  276. LogMsg( "The cluster service configuration has been changed." );
  277. break;
  278. } // while: the call to the base class function has succeeded
  279. LogMsg( "Return Value is %#x.", dwReturnValue );
  280. RETURN( dwReturnValue );
  281. } //*** CTaskUpgradeNT4::DwOcCompleteInstallation()
  282. /////////////////////////////////////////////////////////////////////////////
  283. //++
  284. //
  285. // DWORD
  286. // CTaskUpgradeNT4::DwOcCleanup
  287. //
  288. // Description:
  289. // This function handles the OC_CLEANUP messages from the
  290. // Optional Components Manager during an upgrade from Windows 2000.
  291. //
  292. // If an error has previously occurred during this task, cleanup operations
  293. // are performed. Otherwise nothing is done by this function.
  294. //
  295. // Arguments:
  296. // None.
  297. //
  298. // Return Value:
  299. // NO_ERROR if all went well.
  300. // Other Win32 error codes on failure.
  301. //
  302. //--
  303. /////////////////////////////////////////////////////////////////////////////
  304. DWORD
  305. CTaskUpgradeNT4::DwOcCleanup( void )
  306. {
  307. TraceFunc( "" );
  308. LogMsg( "Entering " __FUNCTION__ "()" );
  309. DWORD dwReturnValue = NO_ERROR;
  310. // The base class helper function does everything that we need to do here.
  311. // So, just call it.
  312. dwReturnValue = TW32( BaseClass::DwOcCleanup( INF_SECTION_NT4_UPGRADE_CLEANUP ) );
  313. LogMsg( "Return Value is %#x.", dwReturnValue );
  314. RETURN( dwReturnValue );
  315. } //*** CTaskUpgradeNT4::DwOcCleanup()
  316. /////////////////////////////////////////////////////////////////////////////
  317. //++
  318. //
  319. // DWORD
  320. // CTaskUpgradeNT4::DwSetDirectoryIds
  321. //
  322. // Description:
  323. // This function maps ids specified in the INF file to directories.
  324. // The cluster installation directory is got from the service control
  325. // manager, since it is possible the the cluster binaries are installed
  326. // in a non-default location.
  327. //
  328. // Arguments:
  329. // None.
  330. //
  331. // Return Value:
  332. // NO_ERROR if all went well.
  333. // Other Win32 error codes on failure.
  334. //
  335. //--
  336. /////////////////////////////////////////////////////////////////////////////
  337. DWORD
  338. CTaskUpgradeNT4::DwSetDirectoryIds()
  339. {
  340. TraceFunc( "" );
  341. LogMsg( "Entering " __FUNCTION__ "()" );
  342. DWORD dwReturnValue = NO_ERROR;
  343. do
  344. {
  345. const WCHAR * pcszInstallDir = NULL;
  346. // If we are here, the this node is already a part of a cluster. So, get the
  347. // installation directory from SCM.
  348. LogMsg( "This node is part of a cluster. Trying to determine the installation directory." );
  349. // Do not free the pointer returned by this call.
  350. dwReturnValue = TW32( DwGetClusterServiceDirectory( pcszInstallDir ) );
  351. if ( dwReturnValue != NO_ERROR )
  352. {
  353. LogMsg( "Error %#x occurred trying to determine the directory in which the cluster binaries are installed.", dwReturnValue );
  354. break;
  355. } // if: we could not get the cluster service installation directory
  356. LogMsg( "The cluster binaries are installed in the directory '%ws'.", pcszInstallDir );
  357. // Create the mapping between the directory id and the path
  358. if ( SetupSetDirectoryId(
  359. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  360. , CLUSTER_DEFAULT_INSTALL_DIRID
  361. , pcszInstallDir
  362. )
  363. == FALSE
  364. )
  365. {
  366. dwReturnValue = TW32( GetLastError() );
  367. LogMsg( "Error %#x occurred trying set the cluster install directory id.", dwReturnValue );
  368. break;
  369. } // if: SetupSetDirectoryId() failed
  370. LogMsg( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, pcszInstallDir );
  371. }
  372. while ( false ); // dummy do-while loop to avoid gotos
  373. LogMsg( "Return Value is %#x.", dwReturnValue );
  374. RETURN( dwReturnValue );
  375. } //*** CTaskUpgradeNT4::DwSetDirectoryIds()