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.

572 lines
22 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2000-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CClusOCMTask.cpp
  7. //
  8. // Description:
  9. // Implementation file for the CClusOCMTask class.
  10. //
  11. // Header File:
  12. // CClusOCMTask.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 "CClusOCMTask.h"
  26. // For CClusOCMApp
  27. #include "CClusOCMApp.h"
  28. //////////////////////////////////////////////////////////////////////////////
  29. // Macro Definitions
  30. //////////////////////////////////////////////////////////////////////////////
  31. // Needed for tracing.
  32. DEFINE_THISCLASS( "CClusOCMTask" )
  33. /////////////////////////////////////////////////////////////////////////////
  34. //++
  35. //
  36. // CClusOCMTask::CClusOCMTask
  37. //
  38. // Description:
  39. // Constructor of the CClusOCMTask class.
  40. //
  41. // Arguments:
  42. // const CClusOCMApp & rAppIn
  43. // Reference to the CClusOCMApp object that is hosting this task.
  44. //
  45. // Return Value:
  46. // None.
  47. //
  48. //--
  49. /////////////////////////////////////////////////////////////////////////////
  50. CClusOCMTask::CClusOCMTask( const CClusOCMApp & rAppIn )
  51. : m_rApp( rAppIn )
  52. {
  53. TraceFunc( "" );
  54. TraceFuncExit();
  55. } //*** CClusOCMTask::CClusOCMTask()
  56. /////////////////////////////////////////////////////////////////////////////
  57. //++
  58. //
  59. // CClusOCMTask::~CClusOCMTask
  60. //
  61. // Description:
  62. // Destructor of the CClusOCMTask class.
  63. //
  64. // Arguments:
  65. // None.
  66. //
  67. // Return Value:
  68. // None.
  69. //
  70. //--
  71. /////////////////////////////////////////////////////////////////////////////
  72. CClusOCMTask::~CClusOCMTask( void )
  73. {
  74. TraceFunc( "" );
  75. TraceFuncExit();
  76. } //*** CClusOCMTask::CClusOCMTask()
  77. /////////////////////////////////////////////////////////////////////////////
  78. //++
  79. //
  80. // DWORD
  81. // CClusOCMTask::DwOcCalcDiskSpace
  82. //
  83. // Description:
  84. // This funcion handles the OC_CALC_DISK_SPACE messages from the Optional
  85. // Components Manager. It either adds or removes disk space requirements
  86. // from the disk space list maintained by the OC Manager.
  87. //
  88. // Note that it is important that components should report disk space
  89. // consistently, and they should not report disk space differently if the
  90. // component is being installed or uninstalled. As a result, the clean
  91. // install section of the INF file is always used by this function to
  92. // calculate disk space.
  93. //
  94. // Arguments:
  95. // bool fAddFilesIn
  96. // If true space requirements are added to the OC Manager disk space
  97. // list. Requirements are removed from the list otherwise.
  98. //
  99. // HDSKSPC hDiskSpaceListIn
  100. // Handle to the OC Manager disk space list.
  101. //
  102. // Return Value:
  103. // NO_ERROR if all went well.
  104. // Other Win32 error codes on failure.
  105. //
  106. //--
  107. /////////////////////////////////////////////////////////////////////////////
  108. DWORD
  109. CClusOCMTask::DwOcCalcDiskSpace(
  110. bool fAddFilesIn
  111. , HDSKSPC hDiskSpaceListIn
  112. )
  113. {
  114. TraceFunc( "" );
  115. LogMsg( "Entering " __FUNCTION__ "()" );
  116. DWORD dwReturnValue = NO_ERROR;
  117. if ( fAddFilesIn )
  118. {
  119. TraceFlow( "Adding space requirements to disk space list." );
  120. LogMsg( "Adding space requirements to disk space list." );
  121. if ( SetupAddInstallSectionToDiskSpaceList(
  122. hDiskSpaceListIn
  123. , RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  124. , NULL
  125. , INF_SECTION_CLEAN_INSTALL
  126. , 0
  127. , 0
  128. ) == FALSE )
  129. {
  130. dwReturnValue = TW32( GetLastError() );
  131. TraceFlow1( "Error %#x occurred while trying to add to disk space requirements list.", dwReturnValue );
  132. LogMsg( "Error %#x occurred while trying to add to disk space requirements list.", dwReturnValue );
  133. } // if: SetupAddInstallSectionToDiskSpaceList failed
  134. } // if: the space requirements are to be added
  135. else
  136. {
  137. TraceFlow( "Removing space requirements from disk space list." );
  138. LogMsg( "Removing space requirements from disk space list." );
  139. if ( SetupRemoveInstallSectionFromDiskSpaceList(
  140. hDiskSpaceListIn
  141. , RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  142. , NULL
  143. , INF_SECTION_CLEAN_INSTALL
  144. , 0
  145. , 0
  146. ) == FALSE )
  147. {
  148. // See Note: above
  149. dwReturnValue = TW32( GetLastError() );
  150. TraceFlow1( "Error %#x occurred while trying to remove disk space requirements from list.", dwReturnValue );
  151. LogMsg( "Error %#x occurred while trying to remove disk space requirements from list.", dwReturnValue );
  152. } // if: SetupRemoveInstallSectionFromDiskSpaceList failed
  153. } // else: the space requirements are to be deleted.
  154. TraceFlow1( "Return Value is 0x%X.", dwReturnValue );
  155. LogMsg( "Return Value is 0x%X.", dwReturnValue );
  156. RETURN( dwReturnValue );
  157. } //*** CClusOCMTask::DwOcCalcDiskSpace()
  158. /////////////////////////////////////////////////////////////////////////////
  159. //++
  160. //
  161. // DWORD
  162. // CClusOCMTask::DwOcQueueFileOps
  163. //
  164. // Description:
  165. // This is a helper function that performs some of the more common
  166. // operations done by handlers of the OC_QUEUE_FILE_OPS message.
  167. //
  168. // This function calls the DwSetDirectoryIds() function to set the
  169. // directory ids and processes the files listed in the input section.
  170. // It is meant to be called by derived classes only.
  171. //
  172. // Arguments:
  173. // HSPFILEQ hSetupFileQueueIn
  174. // Handle to the file queue to operate upon.
  175. //
  176. // const WCHAR * pcszInstallSectionNameIn
  177. // Name of the section which contains details of the files to be
  178. // set up.
  179. //
  180. // Return Value:
  181. // NO_ERROR if all went well.
  182. // E_POINTER if the input section name is NULL.
  183. // Other Win32 error codes on failure.
  184. //
  185. //--
  186. /////////////////////////////////////////////////////////////////////////////
  187. DWORD
  188. CClusOCMTask::DwOcQueueFileOps(
  189. HSPFILEQ hSetupFileQueueIn
  190. , const WCHAR * pcszInstallSectionNameIn
  191. )
  192. {
  193. TraceFunc( "" );
  194. LogMsg( "Entering " __FUNCTION__ "()" );
  195. DWORD dwReturnValue = NO_ERROR;
  196. do
  197. {
  198. // Validate the parameters
  199. if ( pcszInstallSectionNameIn == NULL )
  200. {
  201. TraceFlow( "Error: The input section name cannot be NULL." );
  202. LogMsg( "Error: The input section name cannot be NULL." );
  203. dwReturnValue = TW32( ERROR_INVALID_PARAMETER );
  204. break;
  205. } // if: the input section name is NULL
  206. dwReturnValue = TW32( DwSetDirectoryIds() );
  207. if ( dwReturnValue != NO_ERROR )
  208. {
  209. TraceFlow1( "Error %#x occurred while trying to set the directory ids.", dwReturnValue );
  210. LogMsg( "Error %#x occurred while trying to set the directory ids.", dwReturnValue );
  211. break;
  212. } // if: DwSetDirectoryIds() failed
  213. TraceFlow1( "Attempting to queue file operations using section '%ws'.", pcszInstallSectionNameIn );
  214. LogMsg( "Attempting to queue file operations using section '%ws'.", pcszInstallSectionNameIn );
  215. if ( SetupInstallFilesFromInfSection(
  216. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle // handle to the INF file
  217. , NULL // optional, layout INF handle
  218. , hSetupFileQueueIn // handle to the file queue
  219. , pcszInstallSectionNameIn // name of the Install section
  220. , NULL // optional, root path to source files
  221. , SP_COPY_NEWER // optional, specifies copy behavior
  222. ) == FALSE )
  223. {
  224. dwReturnValue = TW32( GetLastError() );
  225. TraceFlow1( "Error %#x occurred while trying to install files.", dwReturnValue );
  226. LogMsg( "Error %#x occurred while trying to install files.", dwReturnValue );
  227. break;
  228. } // if: SetupInstallFilesFromInfSection() failed
  229. TraceFlow( "File ops successfully queued." );
  230. LogMsg( "File ops successfully queued." );
  231. }
  232. while( false ); // dummy do-while loop to avoid gotos
  233. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  234. LogMsg( "Return Value is %#x.", dwReturnValue );
  235. RETURN( dwReturnValue );
  236. } //*** CClusOCMTask::DwOcQueueFileOps()
  237. /////////////////////////////////////////////////////////////////////////////
  238. //++
  239. //
  240. // DWORD
  241. // CClusOCMTask::DwOcCompleteInstallation
  242. //
  243. // Description:
  244. // This is a helper function that performs some of the more common
  245. // operations done by handlers of the OC_COMPLETE_INSTALLATION message.
  246. //
  247. // Registry operations, COM component registrations, creation of servies
  248. // etc. listed in the input section are processed by this function.
  249. // This function is meant to be called by derived classes only.
  250. //
  251. // Arguments:
  252. // const WCHAR * pcszInstallSectionNameIn
  253. // Name of the section which contains details registry entries,
  254. // COM components, etc., that need to be set up.
  255. //
  256. // Return Value:
  257. // NO_ERROR if all went well.
  258. // E_POINTER if the input section name is NULL.
  259. // Other Win32 error codes on failure.
  260. //
  261. //--
  262. /////////////////////////////////////////////////////////////////////////////
  263. DWORD
  264. CClusOCMTask::DwOcCompleteInstallation( const WCHAR * pcszInstallSectionNameIn )
  265. {
  266. TraceFunc( "" );
  267. LogMsg( "Entering " __FUNCTION__ "()" );
  268. DWORD dwReturnValue = NO_ERROR;
  269. do
  270. {
  271. // Validate the parameters
  272. if ( pcszInstallSectionNameIn == NULL )
  273. {
  274. TraceFlow( "Error: The input section name cannot be NULL." );
  275. LogMsg( "Error: The input section name cannot be NULL." );
  276. dwReturnValue = TW32( ERROR_INVALID_PARAMETER );
  277. break;
  278. } // if: the input section name is NULL
  279. TraceFlow1( "Attempting to setup using the section '%ws'.", pcszInstallSectionNameIn );
  280. LogMsg( "Attempting to setup using the section '%ws'.", pcszInstallSectionNameIn );
  281. // Create the required registry entries, register the COM components and
  282. // create the profile items.
  283. if ( SetupInstallFromInfSection(
  284. NULL // optional, handle of a parent window
  285. , RGetApp().RsicGetSetupInitComponent().ComponentInfHandle // handle to the INF file
  286. , pcszInstallSectionNameIn // name of the Install section
  287. , SPINST_REGISTRY | SPINST_REGSVR | SPINST_PROFILEITEMS // which lines to install from section
  288. , NULL // optional, key for registry installs
  289. , NULL // optional, path for source files
  290. , NULL // optional, specifies copy behavior
  291. , NULL // optional, specifies callback routine
  292. , NULL // optional, callback routine context
  293. , NULL // optional, device information set
  294. , NULL // optional, device info structure
  295. ) == FALSE )
  296. {
  297. dwReturnValue = TW32( GetLastError() );
  298. TraceFlow1( "Error %#x occurred while trying to create registry entries.", dwReturnValue );
  299. LogMsg( "Error %#x occurred while trying to create registry entries.", dwReturnValue );
  300. break;
  301. } // if: SetupInstallFromInfSection() failed
  302. // Create the required services.
  303. if ( SetupInstallServicesFromInfSection(
  304. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle // handle to the open INF file
  305. , pcszInstallSectionNameIn // name of the Service section
  306. , 0 // controls installation procedure
  307. ) == FALSE )
  308. {
  309. dwReturnValue = TW32( GetLastError() );
  310. TraceFlow1( "Error %#x occurred while trying to create the required services.", dwReturnValue );
  311. LogMsg( "Error %#x occurred while trying to create the required services.", dwReturnValue );
  312. break;
  313. } // if: SetupInstallServicesFromInfSection() failed
  314. TraceFlow( "Registry entries and services successfully configured." );
  315. LogMsg( "Registry entries and services successfully configured." );
  316. }
  317. while( false ); // dummy do-while loop to avoid gotos
  318. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  319. LogMsg( "Return Value is %#x.", dwReturnValue );
  320. RETURN( dwReturnValue );
  321. } //*** CClusOCMTask::DwOcCompleteInstallation()
  322. /////////////////////////////////////////////////////////////////////////////
  323. //++
  324. //
  325. // DWORD
  326. // CClusOCMTask::DwOcCleanup
  327. //
  328. // Description:
  329. // This is a helper function that performs some of the more common
  330. // operations done by handlers of the OC_CLEANUP message.
  331. //
  332. // This function processes the registry, COM and profile registration and
  333. // service entries in the input section. It is meant to be used by derived
  334. // classes only.
  335. //
  336. // Arguments:
  337. // const WCHAR * pcszInstallSectionNameIn
  338. // Name of the section which contains the entries to be processed
  339. // during cleanup.
  340. //
  341. // Return Value:
  342. // NO_ERROR if all went well.
  343. // E_POINTER if the input section name is NULL.
  344. // Other Win32 error codes on failure.
  345. //
  346. //--
  347. /////////////////////////////////////////////////////////////////////////////
  348. DWORD
  349. CClusOCMTask::DwOcCleanup( const WCHAR * pcszInstallSectionNameIn )
  350. {
  351. TraceFunc( "" );
  352. LogMsg( "Entering " __FUNCTION__ "()" );
  353. DWORD dwReturnValue = NO_ERROR;
  354. do
  355. {
  356. // Validate the parameters
  357. if ( pcszInstallSectionNameIn == NULL )
  358. {
  359. TraceFlow( "Error: The input section name cannot be NULL." );
  360. LogMsg( "Error: The input section name cannot be NULL." );
  361. dwReturnValue = TW32( ERROR_INVALID_PARAMETER );
  362. break;
  363. } // if: the input section name is NULL
  364. if ( RGetApp().DwGetError() == NO_ERROR )
  365. {
  366. TraceFlow( "No errors have occurred during this task. There is nothing to do during cleanup." );
  367. LogMsg( "No errors have occurred during this task. There is nothing to do during cleanup." );
  368. break;
  369. } // if: this task was error-free
  370. TraceFlow1( "Attempting to cleanup using section '%ws'.", pcszInstallSectionNameIn );
  371. LogMsg( "Attempting to cleanup using section '%ws'.", pcszInstallSectionNameIn );
  372. // Create the required registry entries, register the COM components and
  373. // create the profile items.
  374. if ( SetupInstallFromInfSection(
  375. NULL // optional, handle of a parent window
  376. , RGetApp().RsicGetSetupInitComponent().ComponentInfHandle // handle to the INF file
  377. , pcszInstallSectionNameIn // name of the Install section
  378. , SPINST_REGISTRY | SPINST_REGSVR | SPINST_PROFILEITEMS // which lines to install from section
  379. , NULL // optional, key for registry installs
  380. , NULL // optional, path for source files
  381. , NULL // optional, specifies copy behavior
  382. , NULL // optional, specifies callback routine
  383. , NULL // optional, callback routine context
  384. , NULL // optional, device information set
  385. , NULL // optional, device info structure
  386. ) == FALSE )
  387. {
  388. dwReturnValue = TW32( GetLastError() );
  389. TraceFlow1( "Error %#x occurred while trying to setup registry entries.", dwReturnValue );
  390. LogMsg( "Error %#x occurred while trying to setup registry entries.", dwReturnValue );
  391. break;
  392. } // if: SetupInstallFromInfSection() failed
  393. // Delete the created services.
  394. if ( SetupInstallServicesFromInfSection(
  395. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle // handle to the open INF file
  396. , pcszInstallSectionNameIn // name of the Service section
  397. , 0 // controls installation procedure
  398. ) == FALSE )
  399. {
  400. dwReturnValue = TW32( GetLastError() );
  401. TraceFlow1( "Error %#x occurred while trying to setup the services.", dwReturnValue );
  402. LogMsg( "Error %#x occurred while trying to setup the services.", dwReturnValue );
  403. break;
  404. } // if: SetupInstallServicesFromInfSection() failed
  405. TraceFlow( "Cleanup was successful." );
  406. LogMsg( "Cleanup was successful." );
  407. }
  408. while( false ); // dummy do-while loop to avoid gotos
  409. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  410. LogMsg( "Return Value is %#x.", dwReturnValue );
  411. RETURN( dwReturnValue );
  412. } //*** CClusOCMTask::DwOcCleanup()
  413. /////////////////////////////////////////////////////////////////////////////
  414. //++
  415. //
  416. // DWORD
  417. // CClusOCMTask::DwSetDirectoryIds
  418. //
  419. // Description:
  420. // This is a helper function that maps the directory id
  421. // CLUSTER_DEFAULT_INSTALL_DIRID to the default cluster installation
  422. // directory CLUSTER_DEFAULT_INSTALL_DIR.
  423. //
  424. // Arguments:
  425. // None.
  426. //
  427. // Return Value:
  428. // NO_ERROR if all went well.
  429. // Other Win32 error codes on failure.
  430. //
  431. //--
  432. /////////////////////////////////////////////////////////////////////////////
  433. DWORD
  434. CClusOCMTask::DwSetDirectoryIds( void )
  435. {
  436. TraceFunc( "" );
  437. LogMsg( "Entering " __FUNCTION__ "()" );
  438. DWORD dwReturnValue = NO_ERROR;
  439. do
  440. {
  441. DWORD dwRequiredSize = 0;
  442. // Determine the size of the buffer needed to hold the cluster directory name.
  443. dwRequiredSize = ExpandEnvironmentStringsW(
  444. CLUSTER_DEFAULT_INSTALL_DIR
  445. , NULL
  446. , 0
  447. );
  448. // Did we get the required size?
  449. if ( dwRequiredSize == 0 )
  450. {
  451. dwReturnValue = TW32( GetLastError() );
  452. TraceFlow1( "Error %#x occurred trying to determine the required size of the expanded environment string.", dwReturnValue );
  453. LogMsg( "Error %#x occurred trying to determine the required size of the expanded environment string.", dwReturnValue );
  454. break;
  455. } // if: we could not determine the required size of the buffer
  456. // Allocate memory for the buffer.
  457. SmartSz sszDirName( new WCHAR[ dwRequiredSize ] );
  458. if ( sszDirName.FIsEmpty() )
  459. {
  460. dwReturnValue = TW32( ERROR_NOT_ENOUGH_MEMORY );
  461. TraceFlow1( "Error: Could not allocate %d bytes for the directory name.", dwRequiredSize );
  462. LogMsg( "Error: Could not allocate %d bytes for the directory name.", dwRequiredSize );
  463. break;
  464. } // if: memory allocation failed
  465. // Expand any variables in the cluster directory name string.
  466. dwRequiredSize = ExpandEnvironmentStringsW(
  467. CLUSTER_DEFAULT_INSTALL_DIR
  468. , sszDirName.PMem()
  469. , dwRequiredSize
  470. );
  471. // Did we get the required size?
  472. if ( dwRequiredSize == 0 )
  473. {
  474. dwReturnValue = TW32( GetLastError() );
  475. TraceFlow1( "Error %#x occurred trying expand environment variables in the cluster directory name.", dwReturnValue );
  476. LogMsg( "Error %#x occurred trying expand environment variables in the cluster directory name.", dwReturnValue );
  477. break;
  478. } // if: we could not determine the required size of the buffer
  479. if ( SetupSetDirectoryId(
  480. RGetApp().RsicGetSetupInitComponent().ComponentInfHandle
  481. , CLUSTER_DEFAULT_INSTALL_DIRID
  482. , sszDirName.PMem()
  483. )
  484. == FALSE
  485. )
  486. {
  487. dwReturnValue = TW32( GetLastError() );
  488. TraceFlow1( "Error %#x occurred trying set the default cluster install directory id.", dwReturnValue );
  489. LogMsg( "Error %#x occurred trying set the default cluster install directory id.", dwReturnValue );
  490. break;
  491. } // if: SetupSetDirectoryId() failed
  492. TraceFlow2( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, sszDirName.PMem() );
  493. LogMsg( "The id %d maps to '%ws'.", CLUSTER_DEFAULT_INSTALL_DIRID, sszDirName.PMem() );
  494. }
  495. while ( false ); // dummy do-while loop to avoid gotos
  496. TraceFlow1( "Return Value is %#x.", dwReturnValue );
  497. LogMsg( "Return Value is %#x.", dwReturnValue );
  498. RETURN( dwReturnValue );
  499. } //*** CClusOCMTask::DwSetDirectoryIds()