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.

843 lines
25 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1999-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // CClusDBJoin.cpp
  7. //
  8. // Description:
  9. // Contains the definition of the CClusDBJoin 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. // The header for this file
  21. #include "CClusDBJoin.h"
  22. // For the CBaseClusterJoin class.
  23. #include "CBaseClusterJoin.h"
  24. // For the CImpersonateUser class.
  25. #include "CImpersonateUser.h"
  26. // For ClRtlGetSuiteType()
  27. #include "clusrtl.h"
  28. //////////////////////////////////////////////////////////////////////////////
  29. //++
  30. //
  31. // CClusDBJoin::CClusDBJoin()
  32. //
  33. // Description:
  34. // Constructor of the CClusDBJoin class
  35. //
  36. // Arguments:
  37. // m_pcjClusterJoinIn
  38. // Pointer to the base cluster action of which this action is a part.
  39. //
  40. // Return Value:
  41. // None.
  42. //
  43. // Exceptions Thrown:
  44. // Any exceptions thrown by underlying functions
  45. //
  46. //--
  47. //////////////////////////////////////////////////////////////////////////////
  48. CClusDBJoin::CClusDBJoin( CBaseClusterJoin * pcjClusterJoinIn )
  49. : BaseClass( pcjClusterJoinIn )
  50. , m_pcjClusterJoin( pcjClusterJoinIn )
  51. , m_fHasNodeBeenAddedToSponsorDB( false )
  52. {
  53. BCATraceScope( "" );
  54. SetRollbackPossible( true );
  55. } //*** CClusDBJoin::CClusDBJoin()
  56. //////////////////////////////////////////////////////////////////////////////
  57. //++
  58. //
  59. // CClusDBJoin::~CClusDBJoin()
  60. //
  61. // Description:
  62. // Destructor of the CClusDBJoin class.
  63. //
  64. // Arguments:
  65. // None.
  66. //
  67. // Return Value:
  68. // None.
  69. //
  70. // Exceptions Thrown:
  71. // Any exceptions thrown by underlying functions
  72. //
  73. //--
  74. //////////////////////////////////////////////////////////////////////////////
  75. CClusDBJoin::~CClusDBJoin()
  76. {
  77. BCATraceScope( "" );
  78. } //*** CClusDBJoin::~CClusDBJoin()
  79. //////////////////////////////////////////////////////////////////////////////
  80. //++
  81. //
  82. // void
  83. // CClusDBJoin::Commit()
  84. //
  85. // Description:
  86. // Create the cluster database. If anything goes wrong with the creation,
  87. // cleanup the tasks already done.
  88. //
  89. // Arguments:
  90. // None.
  91. //
  92. // Return Value:
  93. // None.
  94. //
  95. // Exceptions Thrown:
  96. // Any that are thrown by the contained actions.
  97. //
  98. //--
  99. //////////////////////////////////////////////////////////////////////////////
  100. void
  101. CClusDBJoin::Commit( void )
  102. {
  103. BCATraceScope( "" );
  104. // Call the base class commit method.
  105. BaseClass::Commit();
  106. //
  107. // Perform a ClusDB cleanup just to make sure that we do not use some files left over
  108. // from a previous install, aborted uninstall, etc.
  109. //
  110. LogMsg( "Cleaning up old cluster database files that may already exist before starting creation." );
  111. {
  112. CStatusReport srCleanDB(
  113. PbcaGetParent()->PBcaiGetInterfacePointer()
  114. , TASKID_Major_Configure_Cluster_Services
  115. , TASKID_Minor_Cleaning_Up_Cluster_Database
  116. , 0, 1
  117. , IDS_TASK_CLEANINGUP_CLUSDB
  118. );
  119. // Send the next step of this status report.
  120. srCleanDB.SendNextStep( S_OK );
  121. CleanupHive();
  122. // Send the last step of this status report.
  123. srCleanDB.SendNextStep( S_OK );
  124. }
  125. try
  126. {
  127. // Create the cluster database
  128. Create();
  129. } // try:
  130. catch( ... )
  131. {
  132. // If we are here, then something went wrong with the create.
  133. BCATraceMsg( "Caught exception during commit." );
  134. //
  135. // Cleanup anything that the failed join might have done.
  136. // Catch any exceptions thrown during Cleanup to make sure that there
  137. // is no collided unwind.
  138. //
  139. try
  140. {
  141. // Cleanup the database.
  142. Cleanup();
  143. }
  144. catch( ... )
  145. {
  146. //
  147. // The rollback of the committed action has failed.
  148. // There is nothing that we can do.
  149. // We certainly cannot rethrow this exception, since
  150. // the exception that caused the rollback is more important.
  151. //
  152. THR( E_UNEXPECTED );
  153. BCATraceMsg( "Caught exception during cleanup." );
  154. LogMsg( "THIS COMPUTER MAY BE IN AN INVALID STATE. An error has occurred during cleanup." );
  155. } // catch: all
  156. // Rethrow the exception thrown by commit.
  157. throw;
  158. } // catch: all
  159. // If we are here, then everything went well.
  160. SetCommitCompleted( true );
  161. } //*** CClusDBJoin::Commit()
  162. //////////////////////////////////////////////////////////////////////////////
  163. //++
  164. //
  165. // void
  166. // CClusDBJoin::Rollback()
  167. //
  168. // Description:
  169. // Unload the cluster hive and cleanup any associated files.
  170. //
  171. // Arguments:
  172. // None.
  173. //
  174. // Return Value:
  175. // None.
  176. //
  177. // Exceptions Thrown:
  178. // Any that are thrown by the underlying functions.
  179. //
  180. //--
  181. //////////////////////////////////////////////////////////////////////////////
  182. void
  183. CClusDBJoin::Rollback( void )
  184. {
  185. BCATraceScope( "" );
  186. // Call the base class rollback method.
  187. BaseClass::Rollback();
  188. // Undo the actions performed by.
  189. Cleanup();
  190. SetCommitCompleted( false );
  191. } //*** CClusDBJoin::Rollback()
  192. //////////////////////////////////////////////////////////////////////////////
  193. //++
  194. //
  195. // void
  196. // CClusDBJoin::Create()
  197. //
  198. // Description:
  199. // Create the cluster database.
  200. //
  201. // Arguments:
  202. // None.
  203. //
  204. // Return Value:
  205. // None.
  206. //
  207. // Exceptions Thrown:
  208. // CRuntimeError
  209. // If any of the APIs fail.
  210. //
  211. // Any that are thrown by the called functions.
  212. //
  213. //--
  214. //////////////////////////////////////////////////////////////////////////////
  215. void
  216. CClusDBJoin::Create( void )
  217. {
  218. BCATraceScope( "" );
  219. LogMsg( "Attempting to create the cluster database required to join a cluster." );
  220. DWORD dwError = ERROR_SUCCESS;
  221. SmartFileHandle sfhClusDBFile;
  222. {
  223. //
  224. // Get the full path and name of the cluster database file.
  225. //
  226. CStr strClusterHiveFileName( PbcaGetParent()->RStrGetClusterInstallDirectory() );
  227. strClusterHiveFileName += L"\\" CLUSTER_DATABASE_NAME;
  228. BCATraceMsg1( "The cluster hive backing file is '%s'.", strClusterHiveFileName.PszData() );
  229. //
  230. // Create the cluster database file.
  231. //
  232. sfhClusDBFile.Assign(
  233. CreateFile(
  234. strClusterHiveFileName.PszData()
  235. , GENERIC_READ | GENERIC_WRITE
  236. , 0
  237. , NULL
  238. , CREATE_ALWAYS
  239. , 0
  240. , NULL
  241. )
  242. );
  243. if ( sfhClusDBFile.FIsInvalid() )
  244. {
  245. dwError = TW32( GetLastError() );
  246. LogMsg( "Error %#08x occurred trying to create the cluster database file.", dwError );
  247. BCATraceMsg1( "Error %#08x occurred trying to create the cluster database file. Throwing exception.", dwError );
  248. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_JOIN_SYNC_DB );
  249. } // if: CreateFile() failed
  250. // Store the file handle just obtained in a member variable so that it can be used during Synchronize()
  251. // Note, this file is closed when sfhClusDBFile goes out of scope, so m_hClusDBFile should not be used
  252. // outside this function or any function that this function calls.
  253. m_hClusDBFile = sfhClusDBFile.HHandle();
  254. }
  255. //
  256. // In the scope below, the cluster service account is impersonated, so that we can communicate with the
  257. // sponsor cluster
  258. //
  259. {
  260. BCATraceMsg( "Attempting to impersonate the cluster service account." );
  261. // Impersonate the cluster service account, so that we can contact the sponsor cluster.
  262. // The impersonation is automatically ended when this object is destroyed.
  263. CImpersonateUser ciuImpersonateClusterServiceAccount( m_pcjClusterJoin->HGetClusterServiceAccountToken() );
  264. // Add this node to the sponsor cluster database
  265. do
  266. {
  267. DWORD dwSuiteType = ClRtlGetSuiteType();
  268. m_fHasNodeBeenAddedToSponsorDB = false;
  269. BCATraceMsg2( "Trying to add node '%s' (suite type %d) to the sponsor cluster database.",
  270. m_pcjClusterJoin->PszGetNodeName()
  271. , dwSuiteType
  272. );
  273. dwError = TW32( JoinAddNode3(
  274. m_pcjClusterJoin->RbhGetJoinBindingHandle()
  275. , m_pcjClusterJoin->PszGetNodeName()
  276. , m_pcjClusterJoin->DwGetNodeHighestVersion()
  277. , m_pcjClusterJoin->DwGetNodeLowestVersion()
  278. , dwSuiteType
  279. ) );
  280. if ( dwError != ERROR_SUCCESS )
  281. {
  282. BCATraceMsg( "JoinAddNode3 has failed." );
  283. break;
  284. } // if: JoinAddNode3() failed
  285. // Set the flag that indicates that the sponsor database has been modified, so that
  286. // we can undo this if we need to rollback or cleanup.
  287. m_fHasNodeBeenAddedToSponsorDB = true;
  288. }
  289. while( false ); // dummy do while loop to avoid gotos.
  290. if ( dwError != ERROR_SUCCESS )
  291. {
  292. LogMsg( "Error %#08x occurred trying to add this node to the sponsor cluster database.", dwError );
  293. BCATraceMsg1( "Error %#08x occurred trying to add this node to the sponsor cluster database. Throwing exception.", dwError );
  294. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_JOINING_SPONSOR_DB );
  295. } // if: something has gone wrong
  296. BCATraceMsg( "This node has been successfully added to the sponsor cluster database." );
  297. // Get the node id of the newly formed node.
  298. do
  299. {
  300. // Smart handle to sponsor cluster
  301. SmartClusterHandle schSponsorCluster;
  302. // Smart handle to this node
  303. SmartNodeHandle snhThisNodeHandle;
  304. //
  305. // Get a handle to the sponsor cluster.
  306. //
  307. {
  308. BCATraceMsg( "Trying to open a handle to the sponsor cluster." );
  309. // Open a handle to the sponsor cluster.
  310. HCLUSTER hSponsorCluster = OpenCluster( m_pcjClusterJoin->RStrGetClusterBindingString().PszData() );
  311. // Assign it to a smart handle for safe release.
  312. schSponsorCluster.Assign( hSponsorCluster );
  313. }
  314. // Did we succeed in opening a handle to the sponsor cluster?
  315. if ( schSponsorCluster.FIsInvalid() )
  316. {
  317. dwError = TW32( GetLastError() );
  318. BCATraceMsg( "An error occurred trying to open a handle to the sponsor cluster." );
  319. break;
  320. } // if: OpenCluster() failed
  321. //
  322. // Get a handle to this node.
  323. //
  324. {
  325. BCATraceMsg( "Trying to open a handle to this node." );
  326. // Open a handle to this node.
  327. HNODE hThisNode = OpenClusterNode( schSponsorCluster.HHandle(), m_pcjClusterJoin->PszGetNodeName() );
  328. // Assign it to a smart handle for safe release.
  329. snhThisNodeHandle.Assign( hThisNode );
  330. }
  331. // Did we succeed in opening a handle to this node?
  332. if ( snhThisNodeHandle.FIsInvalid() )
  333. {
  334. dwError = TW32( GetLastError() );
  335. BCATraceMsg( "An error occurred trying to open a handle to this node." );
  336. break;
  337. } // if: OpenClusterNode() failed
  338. // Get the node id string.
  339. {
  340. DWORD cchIdSize = 0;
  341. SmartSz sszNodeId;
  342. dwError = GetClusterNodeId(
  343. snhThisNodeHandle.HHandle()
  344. , NULL
  345. , &cchIdSize
  346. );
  347. if ( ( dwError != ERROR_SUCCESS ) && ( dwError != ERROR_MORE_DATA ) )
  348. {
  349. TW32( dwError );
  350. BCATraceMsg( "GetClusterNodeId() could not get the required length of the node id buffer.");
  351. break;
  352. } // if: GetClusterNodeId() failed
  353. // cchIdSize returned by the above call is the count of characters and does not include the space for
  354. // the terminating NULL.
  355. ++cchIdSize;
  356. sszNodeId.Assign( new WCHAR[ cchIdSize ] );
  357. if ( sszNodeId.FIsEmpty() )
  358. {
  359. dwError = TW32( ERROR_OUTOFMEMORY );
  360. BCATraceMsg1( "A memory allocation failure occurred trying to allocate %d characters.", cchIdSize );
  361. break;
  362. } // if: memory allocation failed
  363. dwError = TW32( GetClusterNodeId(
  364. snhThisNodeHandle.HHandle()
  365. , sszNodeId.PMem()
  366. , &cchIdSize
  367. ) );
  368. if ( dwError != ERROR_SUCCESS )
  369. {
  370. BCATraceMsg( "GetClusterNodeId() failed to get the node id of this node.");
  371. break;
  372. } // if: GetClusterNodeId() failed
  373. BCATraceMsg1( "The node id of this node is '%s'.", sszNodeId.PMem() );
  374. // Set the node id for later use.
  375. m_pcjClusterJoin->SetNodeIdString( sszNodeId.PMem() );
  376. }
  377. }
  378. while( false ); // dummy do while loop to avoid gotos.
  379. if ( dwError != ERROR_SUCCESS )
  380. {
  381. LogMsg( "Error %#08x occurred trying to get the node id of this node.", dwError );
  382. BCATraceMsg1( "Error %#08x occurred trying to get the node id of this node. Throwing exception.", dwError );
  383. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_GET_NEW_NODE_ID );
  384. } // if: something has gone wrong
  385. {
  386. CStatusReport srSyncDB(
  387. PbcaGetParent()->PBcaiGetInterfacePointer()
  388. , TASKID_Major_Configure_Cluster_Services
  389. , TASKID_Minor_Join_Sync_Cluster_Database
  390. , 0, 1
  391. , IDS_TASK_JOIN_SYNC_CLUSDB
  392. );
  393. // Send the next step of this status report.
  394. srSyncDB.SendNextStep( S_OK );
  395. // Synchronize the cluster database.
  396. Synchronize();
  397. // Send the last step of this status report.
  398. srSyncDB.SendNextStep( S_OK );
  399. }
  400. }
  401. LogMsg( "The cluster database has been successfully created and synchronized with the sponsor cluster." );
  402. } //*** CClusDBJoin::Create()
  403. //////////////////////////////////////////////////////////////////////////////
  404. //++
  405. //
  406. // void
  407. // CClusDBJoin::Cleanup()
  408. //
  409. // Description:
  410. // Cleanup the effects of Create()
  411. //
  412. // Arguments:
  413. // None.
  414. //
  415. // Return Value:
  416. // None.
  417. //
  418. // Exceptions Thrown:
  419. // CRuntimeError
  420. // If any of the APIs fail.
  421. //
  422. // Any that are thrown by the called functions.
  423. //
  424. //--
  425. //////////////////////////////////////////////////////////////////////////////
  426. void
  427. CClusDBJoin::Cleanup( void )
  428. {
  429. BCATraceScope( "" );
  430. LogMsg( "Attempting to cleanup the cluster database." );
  431. DWORD dwError = ERROR_SUCCESS;
  432. //
  433. // Check if we added this node to the sponsor cluster database. If so, remove it from there.
  434. //
  435. if ( m_fHasNodeBeenAddedToSponsorDB )
  436. {
  437. BCATraceMsg( "Attempting to impersonate the cluster service account." );
  438. // Impersonate the cluster service account, so that we can contact the sponsor cluster.
  439. // The impersonation is automatically ended when this object is destroyed.
  440. CImpersonateUser ciuImpersonateClusterServiceAccount( m_pcjClusterJoin->HGetClusterServiceAccountToken() );
  441. // Remove this node from the sponsor cluster database
  442. do
  443. {
  444. // Smart handle to sponsor cluster
  445. SmartClusterHandle schSponsorCluster;
  446. // Smart handle to this node
  447. SmartNodeHandle snhThisNodeHandle;
  448. //
  449. // Get a handle to the sponsor cluster.
  450. //
  451. {
  452. BCATraceMsg( "Trying to open a handle to the sponsor cluster." );
  453. // Open a handle to the sponsor cluster.
  454. HCLUSTER hSponsorCluster = OpenCluster( m_pcjClusterJoin->RStrGetClusterBindingString().PszData() );
  455. // Assign it to a smart handle for safe release.
  456. schSponsorCluster.Assign( hSponsorCluster );
  457. }
  458. // Did we succeed in opening a handle to the sponsor cluster?
  459. if ( schSponsorCluster.FIsInvalid() )
  460. {
  461. dwError = TW32( GetLastError() );
  462. BCATraceMsg( "An error occurred trying to open a handle to the sponsor cluster." );
  463. break;
  464. } // if: OpenCluster() failed
  465. //
  466. // Get a handle to this node.
  467. //
  468. {
  469. BCATraceMsg( "Trying to open a handle to this node." );
  470. // Open a handle to this node.
  471. HNODE hThisNode = OpenClusterNode( schSponsorCluster.HHandle(), m_pcjClusterJoin->PszGetNodeName() );
  472. if ( hThisNode == NULL )
  473. {
  474. dwError = TW32( GetLastError() );
  475. BCATraceMsg( "An error has occurred trying to open a handle to this node." );
  476. break;
  477. } // if: OpenClusterNode() failed.
  478. // Assign it to a smart handle for safe release.
  479. snhThisNodeHandle.Assign( hThisNode );
  480. }
  481. dwError = TW32( EvictClusterNode( snhThisNodeHandle.HHandle() ) );
  482. if ( dwError != ERROR_SUCCESS )
  483. {
  484. BCATraceMsg( "An error has occurred trying to evict this node from the sponsor cluster." );
  485. break;
  486. } // if: EvictClusterNode() failed
  487. }
  488. while( false ); // dummy do while loop to avoid gotos.
  489. if ( dwError != ERROR_SUCCESS )
  490. {
  491. LogMsg( "Error %#08x occurred trying to remove this node from the sponsor cluster database.", dwError );
  492. BCATraceMsg1( "Error %#08x occurred trying to remove this node from the sponsor cluster database. Throwing exception.", dwError );
  493. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_EVICTING_NODE );
  494. } // if: something has gone wrong
  495. BCATraceMsg( "This node has been successfully removed from the sponsor cluster database." );
  496. } // if: we had added this node to the sponsor cluster database
  497. // Cleanup the cluster hive
  498. CleanupHive();
  499. } //*** Cleanup()
  500. //////////////////////////////////////////////////////////////////////////////
  501. //++
  502. //
  503. // void
  504. // CClusDBJoin::Synchronize()
  505. //
  506. // Description:
  507. // Synchronize the cluster database with the sponsor cluster.
  508. //
  509. // Arguments:
  510. // None.
  511. //
  512. // Return Value:
  513. // None.
  514. //
  515. // Exceptions Thrown:
  516. // CRuntimeError
  517. // If any of the APIs fail.
  518. //
  519. // Any that are thrown by the called functions.
  520. //
  521. //--
  522. //////////////////////////////////////////////////////////////////////////////
  523. void
  524. CClusDBJoin::Synchronize( void )
  525. {
  526. BCATraceScope( "" );
  527. LogMsg( "Attempting to synchronize the cluster database with the sponsor cluster." );
  528. DWORD dwError = ERROR_SUCCESS;
  529. do
  530. {
  531. //
  532. // Initialize the byte pipe.
  533. //
  534. m_bpBytePipe.state = reinterpret_cast< char * >( this );
  535. m_bpBytePipe.alloc = S_BytePipeAlloc;
  536. m_bpBytePipe.push = S_BytePipePush;
  537. m_bpBytePipe.pull = S_BytePipePull;
  538. //
  539. // Synchronize the database
  540. //
  541. dwError = TW32( DmSyncDatabase( m_pcjClusterJoin->RbhGetJoinBindingHandle(), m_bpBytePipe ) );
  542. if ( dwError != ERROR_SUCCESS )
  543. {
  544. BCATraceMsg( "An error occurred trying to suck the database down from the sponsor cluster." );
  545. break;
  546. } // if: DmSyncDatabase() failed
  547. }
  548. while( false ); // Dummy do-while loop to avoid gotos.
  549. if ( dwError != ERROR_SUCCESS )
  550. {
  551. LogMsg( "Error %#08x occurred trying to synchronize the cluster database with the sponsor cluster.", dwError );
  552. BCATraceMsg1( "Error %#08x occurred trying trying to synchronize the cluster database with the sponsor cluster. Throwing exception.", dwError );
  553. THROW_RUNTIME_ERROR( HRESULT_FROM_WIN32( dwError ), IDS_ERROR_JOIN_SYNC_DB );
  554. } // if: something has gone wrong
  555. LogMsg( "The cluster database has been synchronized with the sponsor cluster." );
  556. } //*** Synchronize()
  557. //////////////////////////////////////////////////////////////////////////////
  558. //++
  559. //
  560. // static void
  561. // CClusDBJoin::S_BytePipePush()
  562. //
  563. // Description:
  564. // Callback function used by RPC to push data.
  565. //
  566. // Arguments:
  567. // pchStateIn
  568. // State of the byte pipe
  569. //
  570. // pchBufferIn
  571. // ulBufferSizeIn
  572. // Buffer contained the pushed data and its size.
  573. //
  574. // Return Value:
  575. // None.
  576. //
  577. // Exceptions Thrown:
  578. // RPC Exceptions.
  579. //
  580. //--
  581. //////////////////////////////////////////////////////////////////////////////
  582. void
  583. CClusDBJoin::S_BytePipePush(
  584. char * pchStateIn
  585. , unsigned char * pchBufferIn
  586. , unsigned long ulBufferSizeIn
  587. )
  588. {
  589. CClusDBJoin * pThis = reinterpret_cast< CClusDBJoin * >( pchStateIn );
  590. if ( ulBufferSizeIn != 0 )
  591. {
  592. DWORD dwBytesWritten;
  593. if ( WriteFile(
  594. pThis->m_hClusDBFile
  595. , pchBufferIn
  596. , ulBufferSizeIn
  597. , &dwBytesWritten
  598. , NULL
  599. )
  600. == 0
  601. )
  602. {
  603. DWORD dwError = GetLastError();
  604. RpcRaiseException( dwError );
  605. } // if: WriteFile() failed
  606. } // if: the buffer is non-empty
  607. } //*** CClusDBJoin::S_BytePipePush()
  608. //////////////////////////////////////////////////////////////////////////////
  609. //++
  610. //
  611. // static void
  612. // CClusDBJoin::S_BytePipePull()
  613. //
  614. // Description:
  615. // Callback function used by RPC to pull data.
  616. //
  617. // Arguments:
  618. // pchStateIn
  619. // State of the byte pipe
  620. //
  621. // pchBufferIn
  622. // ulBufferSizeIn
  623. // Buffer contained the pushed data and its size.
  624. //
  625. // pulWrittenOut
  626. // Pointer to the number of bytes actually filled into the buffer.
  627. //
  628. // Return Value:
  629. // None.
  630. //
  631. // Exceptions Thrown:
  632. // RPC Exceptions.
  633. //
  634. //--
  635. //////////////////////////////////////////////////////////////////////////////
  636. void
  637. CClusDBJoin::S_BytePipePull(
  638. char * pchStateIn
  639. , unsigned char * pchBufferIn
  640. , unsigned long ulBufferSizeIn
  641. , unsigned long * pulWrittenOut
  642. )
  643. {
  644. CClusDBJoin * pThis = reinterpret_cast< CClusDBJoin * >( pchStateIn );
  645. if ( ulBufferSizeIn != 0 )
  646. {
  647. if ( ReadFile(
  648. pThis->m_hClusDBFile
  649. , pchBufferIn
  650. , ulBufferSizeIn
  651. , pulWrittenOut
  652. , NULL
  653. )
  654. == 0
  655. )
  656. {
  657. DWORD dwError = TW32( GetLastError() );
  658. RpcRaiseException( dwError );
  659. } // if: ReadFile() failed
  660. } // if: the buffer is non-empty
  661. } //*** CClusDBJoin::S_BytePipePull()
  662. //////////////////////////////////////////////////////////////////////////////
  663. //++
  664. //
  665. // static void
  666. // CClusDBJoin::S_BytePipeAlloc()
  667. //
  668. // Description:
  669. // Callback function used by RPC to allocate a buffer.
  670. //
  671. // Arguments:
  672. // pchStateIn
  673. // State of the file pipe
  674. //
  675. // ulRequestedSizeIn
  676. // Requested size of the buffer
  677. // ppchBufferOut
  678. // Pointer to the buffer pointer
  679. //
  680. // pulActualSizeOut
  681. // Pointer to the actual size of the allocated buffer
  682. //
  683. // Return Value:
  684. // None.
  685. //
  686. // Exceptions Thrown:
  687. // None.
  688. //
  689. //--
  690. //////////////////////////////////////////////////////////////////////////////
  691. void
  692. CClusDBJoin::S_BytePipeAlloc(
  693. char * pchStateIn
  694. , unsigned long ulRequestedSizeIn
  695. , unsigned char ** ppchBufferOut
  696. , unsigned long * pulActualSizeOut
  697. )
  698. {
  699. CClusDBJoin * pThis = reinterpret_cast< CClusDBJoin * >( pchStateIn );
  700. *ppchBufferOut = reinterpret_cast< unsigned char * >( pThis->m_rgbBytePipeBuffer );
  701. *pulActualSizeOut = ( ulRequestedSizeIn < pThis->ms_nFILE_PIPE_BUFFER_SIZE ) ? ulRequestedSizeIn : pThis->ms_nFILE_PIPE_BUFFER_SIZE;
  702. } //*** CClusDBJoin::S_BytePipeAlloc()