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.

2896 lines
89 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1997-2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // PropListSrc.cpp
  7. //
  8. // Header File:
  9. // PropList.h
  10. //
  11. // Description:
  12. // Implementation of the CClusPropList class.
  13. //
  14. // Maintained By:
  15. // Galen Barbee (GalenB) 31-MAY-2000
  16. //
  17. /////////////////////////////////////////////////////////////////////////////
  18. #include <StrSafe.h>
  19. #include <PropList.h>
  20. #include "clstrcmp.h"
  21. /////////////////////////////////////////////////////////////////////////////
  22. // Constant Definitions
  23. /////////////////////////////////////////////////////////////////////////////
  24. const int BUFFER_GROWTH_FACTOR = 256;
  25. /////////////////////////////////////////////////////////////////////////////
  26. //++
  27. //
  28. // CchMultiSz
  29. //
  30. // Description:
  31. // Length of all of the substrings of a multisz string minus the final NULL.
  32. //
  33. // (i.e., includes the nulls of the substrings, excludes the final null)
  34. // multiszlen( "abcd\0efgh\0\0" => 5 + 5 = 10
  35. //
  36. // Arguments:
  37. // psz [IN] The string to get the length of.
  38. //
  39. // Return Value:
  40. // Count of characters in the multisz or 0 if empty.
  41. //
  42. //--
  43. /////////////////////////////////////////////////////////////////////////////
  44. static size_t CchMultiSz(
  45. IN LPCWSTR psz
  46. )
  47. {
  48. Assert( psz != NULL );
  49. size_t _cchTotal = 0;
  50. size_t _cchChars;
  51. while ( *psz != L'\0' )
  52. {
  53. _cchChars = wcslen( psz ) + 1;
  54. _cchTotal += _cchChars;
  55. psz += _cchChars;
  56. } // while: pointer not stopped on EOS
  57. return _cchTotal;
  58. } //*** CchMultiSz
  59. /////////////////////////////////////////////////////////////////////////////
  60. //++
  61. //
  62. // NCompareMultiSz
  63. //
  64. // Description:
  65. // Compare two MULTI_SZ buffers.
  66. //
  67. // Arguments:
  68. // pszSource [IN] The source string.
  69. // pszTarget [IN] The target string.
  70. //
  71. // Return Value:
  72. // If the string pointed to by pszSource is less than the string pointed
  73. // to by pszTarget, the return value is negative. If the string pointed
  74. // to by pszSource is greater than the string pointed to by pszTarget,
  75. // the return value is positive. If the strings are equal, the return value
  76. // is zero.
  77. //
  78. //--
  79. /////////////////////////////////////////////////////////////////////////////
  80. static int NCompareMultiSz(
  81. IN LPCWSTR pszSource,
  82. IN LPCWSTR pszTarget
  83. )
  84. {
  85. Assert( pszSource != NULL );
  86. Assert( pszTarget != NULL );
  87. while ( ( *pszSource != L'\0' ) && ( *pszTarget != L'\0') )
  88. {
  89. //
  90. // Move to end of strings.
  91. //
  92. while ( ( *pszSource != L'\0' ) && ( *pszTarget != L'\0') && ( *pszSource == *pszTarget ) )
  93. {
  94. ++pszSource;
  95. ++pszTarget;
  96. } // while: pointer not stopped on EOS
  97. //
  98. // If strings are the same, skip past terminating NUL.
  99. // Otherwise exit the loop.
  100. if ( ( *pszSource == L'\0' ) && ( *pszTarget == L'\0') )
  101. {
  102. ++pszSource;
  103. ++pszTarget;
  104. } // if: both stopped on EOS
  105. else
  106. {
  107. break;
  108. } // else: stopped because something is not equal -- wr are done.
  109. } // while: pointer not stopped on EOS
  110. return *pszSource - *pszTarget;
  111. } //*** NCompareMultiSz
  112. //*************************************************************************//
  113. /////////////////////////////////////////////////////////////////////////////
  114. // CClusPropValueList class
  115. /////////////////////////////////////////////////////////////////////////////
  116. /////////////////////////////////////////////////////////////////////////////
  117. //++
  118. //
  119. // CClusPropValueList::ScMoveToFirstValue
  120. //
  121. // Description:
  122. // Move the cursor to the first value in the value list.
  123. //
  124. // Arguments:
  125. // None.
  126. //
  127. // Return Value:
  128. // ERROR_SUCCESS Position moved to the first value successfully.
  129. //
  130. //--
  131. /////////////////////////////////////////////////////////////////////////////
  132. DWORD CClusPropValueList::ScMoveToFirstValue( void )
  133. {
  134. Assert( m_cbhValueList.pb != NULL );
  135. DWORD _sc;
  136. m_cbhCurrentValue = m_cbhValueList;
  137. m_cbDataLeft = m_cbDataSize;
  138. m_fAtEnd = FALSE;
  139. if ( m_cbhCurrentValue.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK )
  140. {
  141. _sc = ERROR_NO_MORE_ITEMS;
  142. } // if: no items in the value list
  143. else
  144. {
  145. _sc = ERROR_SUCCESS;
  146. } // else: items exist in the value list
  147. return _sc;
  148. } //*** CClusPropValueList::ScMoveToFirstValue
  149. /////////////////////////////////////////////////////////////////////////////
  150. //++
  151. //
  152. // CClusPropValueList::ScMoveToNextValue
  153. //
  154. // Description:
  155. // Move the cursor to the next value in the list.
  156. //
  157. // Arguments:
  158. // None.
  159. //
  160. // Return Value:
  161. // ERROR_SUCCESS Position moved to the next value successfully.
  162. // ERROR_NO_MORE_ITEMS Already at the end of the list.
  163. // ERROR_INVALID_DATA Not enough data in the buffer.
  164. //
  165. //--
  166. /////////////////////////////////////////////////////////////////////////////
  167. DWORD CClusPropValueList::ScMoveToNextValue( void )
  168. {
  169. Assert( m_cbhCurrentValue.pb != NULL );
  170. DWORD _sc = ERROR_NO_MORE_ITEMS;
  171. size_t _cbDataSize;
  172. CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
  173. _cbhCurrentValue = m_cbhCurrentValue;
  174. //
  175. // Don't try to move if we're already at the end.
  176. //
  177. if ( m_fAtEnd )
  178. {
  179. goto Cleanup;
  180. } // if: already at the end of the list
  181. //
  182. // Make sure the buffer is big enough for the value header.
  183. //
  184. if ( m_cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
  185. {
  186. _sc = TW32( ERROR_INVALID_DATA );
  187. goto Cleanup;
  188. } // if: not enough data left
  189. //
  190. // Calculate how much to advance buffer pointer.
  191. //
  192. _cbDataSize = sizeof( *_cbhCurrentValue.pValue )
  193. + ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
  194. //
  195. // Make sure the buffer is big enough for the value header,
  196. // the data itself, and the endmark.
  197. //
  198. if ( m_cbDataLeft < _cbDataSize + sizeof( CLUSPROP_SYNTAX ) )
  199. {
  200. _sc = TW32( ERROR_INVALID_DATA );
  201. goto Cleanup;
  202. } // if: not enough data left
  203. //
  204. // Move past the current value to the next value's syntax.
  205. //
  206. _cbhCurrentValue.pb += _cbDataSize;
  207. //
  208. // This test will ensure that the value is always valid since we won't
  209. // advance if the next thing is the endmark.
  210. //
  211. if ( _cbhCurrentValue.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK )
  212. {
  213. m_cbhCurrentValue = _cbhCurrentValue;
  214. m_cbDataLeft -= _cbDataSize;
  215. _sc = ERROR_SUCCESS;
  216. } // if: next value's syntax is not the endmark
  217. else
  218. {
  219. m_fAtEnd = TRUE;
  220. } // else: next value's syntax is the endmark
  221. Cleanup:
  222. return _sc;
  223. } //*** CClusPropValueList::ScMoveToNextValue
  224. /////////////////////////////////////////////////////////////////////////////
  225. //++
  226. //
  227. // CClusPropValueList::ScCheckIfAtLastValue
  228. //
  229. // Description:
  230. // Indicate whether we are on the last value in the list or not.
  231. //
  232. // Arguments:
  233. // None.
  234. //
  235. // Return Value:
  236. // ERROR_SUCCESS Not currently at the last value in the list.
  237. // ERROR_NO_MORE_ITEMS Currently at the last value in the list.
  238. // ERROR_INVALID_DATA Not enough data in the buffer.
  239. //
  240. //--
  241. /////////////////////////////////////////////////////////////////////////////
  242. DWORD CClusPropValueList::ScCheckIfAtLastValue( void )
  243. {
  244. Assert( m_cbhCurrentValue.pb != NULL );
  245. DWORD _sc = ERROR_SUCCESS;
  246. CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
  247. size_t _cbDataSize;
  248. _cbhCurrentValue = m_cbhCurrentValue;
  249. //
  250. // Don't try to recalculate if we already know
  251. // we're at the end of the list.
  252. //
  253. if ( m_fAtEnd )
  254. {
  255. goto Cleanup;
  256. } // if: already at the end of the list
  257. //
  258. // Make sure the buffer is big enough for the value header.
  259. //
  260. if ( m_cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
  261. {
  262. _sc = TW32( ERROR_INVALID_DATA );
  263. goto Cleanup;
  264. } // if: not enough data left
  265. //
  266. // Calculate how much to advance buffer pointer.
  267. //
  268. _cbDataSize = sizeof( *_cbhCurrentValue.pValue )
  269. + ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
  270. //
  271. // Make sure the buffer is big enough for the value header,
  272. // the data itself, and the endmark.
  273. //
  274. if ( m_cbDataLeft < _cbDataSize + sizeof( CLUSPROP_SYNTAX ) )
  275. {
  276. _sc = TW32( ERROR_INVALID_DATA );
  277. goto Cleanup;
  278. } // if: not enough data left
  279. //
  280. // Move past the current value to the next value's syntax.
  281. //
  282. _cbhCurrentValue.pb += _cbDataSize;
  283. //
  284. // We are on the last value if the next thing after this value
  285. // is an endmark.
  286. //
  287. if ( _cbhCurrentValue.pSyntax->dw == CLUSPROP_SYNTAX_ENDMARK )
  288. {
  289. _sc = ERROR_NO_MORE_ITEMS;
  290. } // if: next value's syntax is the endmark
  291. Cleanup:
  292. return _sc;
  293. } //*** CClusPropValueList::ScCheckIfAtLastValue
  294. /////////////////////////////////////////////////////////////////////////////
  295. //++
  296. //
  297. // CClusPropValueList::ScAllocValueList
  298. //
  299. // Description:
  300. // Allocate a value list buffer that's big enough to hold the next
  301. // value.
  302. //
  303. // Arguments:
  304. // cbMinimum [IN] Minimum size of the value list.
  305. //
  306. // Return Value:
  307. // None.
  308. //
  309. //--
  310. /////////////////////////////////////////////////////////////////////////////
  311. DWORD CClusPropValueList::ScAllocValueList( IN size_t cbMinimum )
  312. {
  313. Assert( cbMinimum > 0 );
  314. DWORD _sc = ERROR_SUCCESS;
  315. size_t _cbTotal = 0;
  316. //
  317. // Add the size of the item count and final endmark.
  318. //
  319. cbMinimum += sizeof( CLUSPROP_VALUE );
  320. _cbTotal = m_cbDataSize + cbMinimum;
  321. if ( m_cbBufferSize < _cbTotal )
  322. {
  323. PBYTE _pbNewValuelist = NULL;
  324. cbMinimum = max( BUFFER_GROWTH_FACTOR, cbMinimum );
  325. _cbTotal = m_cbDataSize + cbMinimum;
  326. //
  327. // Allocate and zero a new buffer.
  328. //
  329. _pbNewValuelist = new BYTE[ _cbTotal ];
  330. if ( _pbNewValuelist != NULL )
  331. {
  332. ZeroMemory( _pbNewValuelist, _cbTotal );
  333. //
  334. // If there was a previous buffer, copy it and the delete it.
  335. //
  336. if ( m_cbhValueList.pb != NULL )
  337. {
  338. if ( m_cbDataSize != 0 )
  339. {
  340. CopyMemory( _pbNewValuelist, m_cbhValueList.pb, m_cbDataSize );
  341. } // if: data already exists in buffer
  342. delete [] m_cbhValueList.pb;
  343. m_cbhCurrentValue.pb = _pbNewValuelist + (m_cbhCurrentValue.pb - m_cbhValueList.pb);
  344. } // if: there was a previous buffer
  345. else
  346. {
  347. m_cbhCurrentValue.pb = _pbNewValuelist + sizeof( DWORD ); // move past prop count
  348. } // else: no previous buffer
  349. //
  350. // Save the new buffer.
  351. //
  352. m_cbhValueList.pb = _pbNewValuelist;
  353. m_cbBufferSize = _cbTotal;
  354. } // if: allocation succeeded
  355. else
  356. {
  357. _sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
  358. } // else: allocation failed
  359. } // if: buffer isn't big enough
  360. return _sc;
  361. } //*** CClusPropValueList::ScAllocValueList
  362. /////////////////////////////////////////////////////////////////////////////
  363. //++
  364. //
  365. // CClusPropValueList::ScGetResourceValueList
  366. //
  367. // Description:
  368. // Get value list of a resource.
  369. //
  370. // Arguments:
  371. // hResource [IN] Handle for the resource to get properties from.
  372. // dwControlCode [IN] Control code for the request.
  373. // hHostNode [IN] Handle for the node to direct this request to.
  374. // Defaults to NULL.
  375. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  376. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  377. //
  378. // Return Value:
  379. // None.
  380. //
  381. //--
  382. /////////////////////////////////////////////////////////////////////////////
  383. DWORD CClusPropValueList::ScGetResourceValueList(
  384. IN HRESOURCE hResource,
  385. IN DWORD dwControlCode,
  386. IN HNODE hHostNode,
  387. IN LPVOID lpInBuffer,
  388. IN size_t cbInBufferSize
  389. )
  390. {
  391. Assert( hResource != NULL );
  392. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  393. == (CLUS_OBJECT_RESOURCE << CLUSCTL_OBJECT_SHIFT) );
  394. DWORD _sc = ERROR_SUCCESS;
  395. DWORD _cb = 512;
  396. //
  397. // Overwrite anything that may be in the buffer.
  398. // Allows this class instance to be reused.
  399. //
  400. m_cbDataSize = 0;
  401. //
  402. // Get values.
  403. //
  404. _sc = ScAllocValueList( _cb );
  405. if ( _sc == ERROR_SUCCESS )
  406. {
  407. _sc = TW32E( ClusterResourceControl(
  408. hResource,
  409. hHostNode,
  410. dwControlCode,
  411. lpInBuffer,
  412. static_cast< DWORD >( cbInBufferSize ),
  413. m_cbhValueList.pb,
  414. static_cast< DWORD >( m_cbBufferSize ),
  415. &_cb
  416. ), ERROR_MORE_DATA );
  417. if ( _sc == ERROR_MORE_DATA )
  418. {
  419. _sc = TW32( ScAllocValueList( _cb ) );
  420. if ( _sc == ERROR_SUCCESS )
  421. {
  422. _sc = TW32( ClusterResourceControl(
  423. hResource,
  424. hHostNode,
  425. dwControlCode,
  426. lpInBuffer,
  427. static_cast< DWORD >( cbInBufferSize ),
  428. m_cbhValueList.pb,
  429. static_cast< DWORD >( m_cbBufferSize ),
  430. &_cb
  431. ) );
  432. } // if: ScAllocValueList succeeded
  433. } // if: buffer too small
  434. } // if: ScAllocValueList succeeded
  435. if ( _sc != ERROR_SUCCESS )
  436. {
  437. DeleteValueList();
  438. } // if: error getting properties.
  439. else
  440. {
  441. m_cbDataSize = static_cast< size_t >( _cb );
  442. m_cbDataLeft = static_cast< size_t >( _cb );
  443. } // else: no errors
  444. return _sc;
  445. } //*** CClusPropValueList::ScGetResourceValueList
  446. /////////////////////////////////////////////////////////////////////////////
  447. //++
  448. //
  449. // CClusPropValueList::ScGetResourceTypeValueList
  450. //
  451. // Description:
  452. // Get value list of a resource type.
  453. //
  454. // Arguments:
  455. // hCluster [IN] Handle for the cluster in which the resource
  456. // type resides.
  457. // pwszResTypeName [IN] Name of the resource type.
  458. // dwControlCode [IN] Control code for the request.
  459. // hHostNode [IN] Handle for the node to direct this request to.
  460. // Defaults to NULL.
  461. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  462. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  463. //
  464. // Return Value:
  465. // None.
  466. //
  467. //--
  468. /////////////////////////////////////////////////////////////////////////////
  469. DWORD CClusPropValueList::ScGetResourceTypeValueList(
  470. IN HCLUSTER hCluster,
  471. IN LPCWSTR pwszResTypeName,
  472. IN DWORD dwControlCode,
  473. IN HNODE hHostNode,
  474. IN LPVOID lpInBuffer,
  475. IN size_t cbInBufferSize
  476. )
  477. {
  478. Assert( hCluster != NULL );
  479. Assert( pwszResTypeName != NULL );
  480. Assert( *pwszResTypeName != L'\0' );
  481. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  482. == (CLUS_OBJECT_RESOURCE_TYPE << CLUSCTL_OBJECT_SHIFT) );
  483. DWORD _sc = ERROR_SUCCESS;
  484. DWORD _cb = 512;
  485. //
  486. // Overwrite anything that may be in the buffer.
  487. // Allows this class instance to be reused.
  488. //
  489. m_cbDataSize = 0;
  490. //
  491. // Get values.
  492. //
  493. _sc = ScAllocValueList( _cb );
  494. if ( _sc == ERROR_SUCCESS )
  495. {
  496. _sc = TW32E( ClusterResourceTypeControl(
  497. hCluster,
  498. pwszResTypeName,
  499. hHostNode,
  500. dwControlCode,
  501. lpInBuffer,
  502. static_cast< DWORD >( cbInBufferSize ),
  503. m_cbhValueList.pb,
  504. static_cast< DWORD >( m_cbBufferSize ),
  505. &_cb
  506. ), ERROR_MORE_DATA );
  507. if ( _sc == ERROR_MORE_DATA )
  508. {
  509. _sc = TW32( ScAllocValueList( _cb ) );
  510. if ( _sc == ERROR_SUCCESS )
  511. {
  512. _sc = TW32( ClusterResourceTypeControl(
  513. hCluster,
  514. pwszResTypeName,
  515. hHostNode,
  516. dwControlCode,
  517. lpInBuffer,
  518. static_cast< DWORD >( cbInBufferSize ),
  519. m_cbhValueList.pb,
  520. static_cast< DWORD >( m_cbBufferSize ),
  521. &_cb
  522. ) );
  523. } // if: ScAllocValueList succeeded
  524. } // if: buffer too small
  525. } // if: ScAllocValueList succeeded
  526. if ( _sc != ERROR_SUCCESS )
  527. {
  528. DeleteValueList();
  529. } // if: error getting properties.
  530. else
  531. {
  532. m_cbDataSize = static_cast< size_t >( _cb );
  533. m_cbDataLeft = static_cast< size_t >( _cb );
  534. } // else: no errors
  535. return _sc;
  536. } //*** CClusPropValueList::ScGetResourceTypeValueList
  537. //*************************************************************************//
  538. /////////////////////////////////////////////////////////////////////////////
  539. // CClusPropList class
  540. /////////////////////////////////////////////////////////////////////////////
  541. /////////////////////////////////////////////////////////////////////////////
  542. //++
  543. //
  544. // CClusPropList::ScCopy
  545. //
  546. // Description:
  547. // Copy a property list. This function is equivalent to an assignment
  548. // operator. Since this operation can fail, no assignment operator is
  549. // provided.
  550. //
  551. // Arguments:
  552. // pcplPropList [IN] The proplist to copy into this instance.
  553. // cbListSize [IN] The total size of the prop list.
  554. //
  555. // Return Value:
  556. // Win32 status code.
  557. //
  558. //--
  559. /////////////////////////////////////////////////////////////////////////////
  560. DWORD CClusPropList::ScCopy(
  561. IN const PCLUSPROP_LIST pcplPropList,
  562. IN size_t cbListSize
  563. )
  564. {
  565. Assert( pcplPropList != NULL );
  566. DWORD _sc = ERROR_SUCCESS;
  567. //
  568. // Clean up any vestiges of a previous prop list.
  569. //
  570. if ( m_cbhPropList.pb != NULL )
  571. {
  572. DeletePropList();
  573. } // if: the current list is not empty
  574. //
  575. // Allocate the new property list buffer. If successful,
  576. // copy the source list.
  577. //
  578. m_cbhPropList.pb = new BYTE[ cbListSize ];
  579. if ( m_cbhPropList.pb != NULL )
  580. {
  581. CopyMemory( m_cbhPropList.pList, pcplPropList, cbListSize );
  582. m_cbBufferSize = cbListSize;
  583. m_cbDataSize = cbListSize;
  584. m_cbDataLeft = cbListSize;
  585. _sc = ScMoveToFirstProperty();
  586. } // if: new succeeded
  587. else
  588. {
  589. _sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
  590. } // else:
  591. return _sc;
  592. } //*** CClusPropList::ScCopy
  593. /////////////////////////////////////////////////////////////////////////////
  594. //++
  595. //
  596. // CClusPropList::ScAppend
  597. //
  598. // Description:
  599. // Append to a property list.
  600. //
  601. // Arguments:
  602. // rclPropList [IN] The proplist to append onto this instance.
  603. //
  604. // Return Value:
  605. // Win32 status code.
  606. //
  607. //--
  608. /////////////////////////////////////////////////////////////////////////////
  609. DWORD CClusPropList::ScAppend( IN const CClusPropList & rclPropList )
  610. {
  611. DWORD _sc = ERROR_SUCCESS;
  612. size_t _cbPropertyCountOffset;
  613. size_t _cbIncrement;
  614. size_t _cbDataLeft;
  615. PBYTE _pbsrc = NULL;
  616. PBYTE _pbdest = NULL;
  617. //
  618. // Compute the number of bytes to get past the count of properties that
  619. // is at the head of the list. This is typically sizeof DWORD.
  620. //
  621. _cbPropertyCountOffset = sizeof( m_cbhPropList.pList->nPropertyCount );
  622. //
  623. // Compute the allocation increment. This is used when growing our buffer
  624. // and is the amount of data to copy from the passed in list. This includes
  625. // the trailing endmark. m_cbDataSize does not include the leading property
  626. // count DWORD.
  627. //
  628. _cbIncrement = rclPropList.m_cbDataSize;
  629. //
  630. // How much space remains in our current buffer?
  631. //
  632. _cbDataLeft = m_cbBufferSize - m_cbDataSize;
  633. //
  634. // If the size of the list to append is larger than what we have remaining
  635. // then we need to grow the list.
  636. //
  637. if ( _cbIncrement > _cbDataLeft )
  638. {
  639. _sc = TW32( ScAllocPropList( m_cbDataSize + _cbIncrement ) );
  640. if ( _sc != ERROR_SUCCESS )
  641. {
  642. goto Cleanup;
  643. } // if:
  644. } // if:
  645. _pbdest = (PBYTE) &m_cbhPropList.pb[ _cbPropertyCountOffset + m_cbDataSize ];
  646. _pbsrc = (PBYTE) &rclPropList.m_cbhPropList.pList->PropertyName;
  647. CopyMemory( _pbdest, _pbsrc, _cbIncrement );
  648. //
  649. // Grow our data size to match our new size.
  650. //
  651. m_cbDataSize += _cbIncrement;
  652. //
  653. // Increment our property count to include the count of properties appended to the end
  654. // of our buffer.
  655. //
  656. m_cbhPropList.pList->nPropertyCount += rclPropList.m_cbhPropList.pList->nPropertyCount;
  657. Cleanup:
  658. return _sc;
  659. } //*** CClusPropList::ScAppend
  660. ////////////////////////////////////////////////////////////////////////////
  661. //++
  662. //
  663. // CClusPropList::ScMoveToFirstProperty
  664. //
  665. // Description:
  666. // Move the cursor to the first propery in the list.
  667. //
  668. // Arguments:
  669. // None.
  670. //
  671. // Return Value:
  672. // ERROR_SUCCESS Position moved to the first property successfully.
  673. // ERROR_NO_MORE_ITEMS There are no properties in the list.
  674. // ERROR_INVALID_DATA Not enough data in the buffer.
  675. //
  676. //--
  677. /////////////////////////////////////////////////////////////////////////////
  678. DWORD CClusPropList::ScMoveToFirstProperty( void )
  679. {
  680. Assert( m_cbhPropList.pb != NULL );
  681. Assert( m_cbDataSize >= sizeof( m_cbhPropList.pList->nPropertyCount ) );
  682. DWORD _sc;
  683. size_t _cbDataLeft;
  684. size_t _cbDataSize;
  685. CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
  686. //
  687. // Make sure the buffer is big enough for the list header.
  688. //
  689. if ( m_cbDataSize < sizeof( m_cbhPropList.pList->nPropertyCount ) )
  690. {
  691. _sc = TW32( ERROR_INVALID_DATA );
  692. goto Cleanup;
  693. } // if: not enough data
  694. //
  695. // Set the property counter to the number of properties in the list.
  696. //
  697. m_nPropsRemaining = m_cbhPropList.pList->nPropertyCount;
  698. //
  699. // Point the name pointer to the first name in the list.
  700. //
  701. m_cbhCurrentPropName.pName = &m_cbhPropList.pList->PropertyName;
  702. m_cbDataLeft = m_cbDataSize - sizeof( m_cbhPropList.pList->nPropertyCount );
  703. //
  704. // Check to see if there are any properties in the list.
  705. //
  706. if ( m_nPropsRemaining == 0 )
  707. {
  708. _sc = ERROR_NO_MORE_ITEMS;
  709. goto Cleanup;
  710. } // if: no properties in the list
  711. //
  712. // Make sure the buffer is big enough for the first property name.
  713. //
  714. if ( m_cbDataLeft < sizeof( *m_cbhCurrentPropName.pName ) )
  715. {
  716. _sc = TW32( ERROR_INVALID_DATA );
  717. goto Cleanup;
  718. } // if: not enough data left
  719. //
  720. // Calculate how much to advance the buffer pointer.
  721. //
  722. _cbDataSize = sizeof( *m_cbhCurrentPropName.pName )
  723. + ALIGN_CLUSPROP( m_cbhCurrentPropName.pName->cbLength );
  724. //
  725. // Make sure the buffer is big enough for the name header
  726. // and the data itself.
  727. //
  728. if ( m_cbDataLeft < _cbDataSize )
  729. {
  730. _sc = TW32( ERROR_INVALID_DATA );
  731. goto Cleanup;
  732. } // if: not enough data left
  733. //
  734. // Point the value buffer to the first value in the list.
  735. //
  736. _cbhCurrentValue.pb = m_cbhCurrentPropName.pb + _cbDataSize;
  737. _cbDataLeft = m_cbDataLeft - _cbDataSize;
  738. m_pvlValues.Init( _cbhCurrentValue, _cbDataLeft );
  739. //
  740. // Indicate we are successful.
  741. //
  742. _sc = ERROR_SUCCESS;
  743. Cleanup:
  744. return _sc;
  745. } //*** CClusPropList::ScMoveToFirstProperty
  746. /////////////////////////////////////////////////////////////////////////////
  747. //++
  748. //
  749. // CClusPropList::ScMoveToNextProperty
  750. //
  751. // Description:
  752. // Move the cursor to the next property in the list.
  753. //
  754. // Arguments:
  755. // None.
  756. //
  757. // Return Value:
  758. // ERROR_SUCCESS Position moved to the next property successfully.
  759. // ERROR_NO_MORE_ITEMS Already at the end of the list.
  760. // ERROR_INVALID_DATA Not enough data in the buffer.
  761. //
  762. //--
  763. /////////////////////////////////////////////////////////////////////////////
  764. DWORD CClusPropList::ScMoveToNextProperty( void )
  765. {
  766. Assert( m_cbhPropList.pb != NULL );
  767. Assert( m_pvlValues.CbhValueList().pb != NULL );
  768. DWORD _sc;
  769. size_t _cbNameSize;
  770. size_t _cbDataLeft;
  771. size_t _cbDataSize;
  772. CLUSPROP_BUFFER_HELPER _cbhCurrentValue;
  773. CLUSPROP_BUFFER_HELPER _cbhPropName;
  774. _cbhCurrentValue = m_pvlValues;
  775. _cbDataLeft = m_pvlValues.CbDataLeft();
  776. //
  777. // If we aren't already at the last property, attempt to move to the next one.
  778. //
  779. _sc = TW32( ScCheckIfAtLastProperty() );
  780. if ( _sc != ERROR_SUCCESS )
  781. {
  782. goto Cleanup;
  783. } // if: already at the last property (probably)
  784. //
  785. // Make sure the buffer is big enough for the value header.
  786. //
  787. if ( _cbDataLeft < sizeof( *_cbhCurrentValue.pValue ) )
  788. {
  789. _sc = TW32( ERROR_INVALID_DATA );
  790. goto Cleanup;
  791. } // if: not enough data left
  792. //
  793. // Careful! Add offset only to cbhCurrentValue.pb. Otherwise
  794. // pointer arithmetic will give undesirable results.
  795. //
  796. while ( _cbhCurrentValue.pSyntax->dw != CLUSPROP_SYNTAX_ENDMARK )
  797. {
  798. //
  799. // Make sure the buffer is big enough for the value
  800. // and an endmark.
  801. //
  802. _cbDataSize = sizeof( *_cbhCurrentValue.pValue )
  803. + ALIGN_CLUSPROP( _cbhCurrentValue.pValue->cbLength );
  804. if ( _cbDataLeft < _cbDataSize + sizeof( *_cbhCurrentValue.pSyntax ) )
  805. {
  806. _sc = TW32( ERROR_INVALID_DATA );
  807. goto Cleanup;
  808. } // if: not enough data left
  809. //
  810. // Advance past the value.
  811. //
  812. _cbhCurrentValue.pb += _cbDataSize;
  813. _cbDataLeft -= _cbDataSize;
  814. } // while: not at endmark
  815. if ( _sc != ERROR_SUCCESS )
  816. {
  817. goto Cleanup;
  818. } // if: error occurred in loop
  819. //
  820. // Advanced past the endmark.
  821. // Size check already performed in above loop.
  822. //
  823. _cbDataSize = sizeof( *_cbhCurrentValue.pSyntax );
  824. _cbhCurrentValue.pb += _cbDataSize;
  825. _cbDataLeft -= _cbDataSize;
  826. //
  827. // Point the name pointer to the next name in the list.
  828. //
  829. _cbhPropName = _cbhCurrentValue;
  830. Assert( _cbDataLeft == m_cbDataSize - (_cbhPropName.pb - m_cbhPropList.pb) );
  831. //
  832. // Calculate the size of the name with header.
  833. // Make sure the buffer is big enough for the name and an endmark.
  834. //
  835. if ( _cbDataLeft < sizeof( *_cbhPropName.pName ) )
  836. {
  837. _sc = TW32( ERROR_INVALID_DATA );
  838. goto Cleanup;
  839. } // if: not enough data
  840. _cbNameSize = sizeof( *_cbhPropName.pName )
  841. + ALIGN_CLUSPROP( _cbhPropName.pName->cbLength );
  842. if ( _cbDataLeft < _cbNameSize + sizeof( CLUSPROP_SYNTAX ) )
  843. {
  844. _sc = TW32( ERROR_INVALID_DATA );
  845. goto Cleanup;
  846. } // if: not enough data
  847. //
  848. // Point the value buffer to the first value in the list.
  849. //
  850. _cbhCurrentValue.pb = _cbhPropName.pb + _cbNameSize;
  851. m_cbhCurrentPropName = _cbhPropName;
  852. m_cbDataLeft = _cbDataLeft - _cbNameSize;
  853. m_pvlValues.Init( _cbhCurrentValue, m_cbDataLeft );
  854. //
  855. // We've successfully advanced to the next property,
  856. // so there is now one fewer property remaining.
  857. //
  858. --m_nPropsRemaining;
  859. Assert( m_nPropsRemaining >= 1 );
  860. _sc = ERROR_SUCCESS;
  861. Cleanup:
  862. return _sc;
  863. } //*** CClusPropList::ScMoveToNextProperty
  864. /////////////////////////////////////////////////////////////////////////////
  865. //++
  866. //
  867. // CClusPropList::ScMoveToPropertyByName
  868. //
  869. // Description:
  870. // Find the passed in property name in the proplist. Note that the
  871. // cursor is reset to the beginning at the beginning of the routine and
  872. // the current state of the cursor is lost.
  873. //
  874. // Arguments:
  875. // pwszPropName [IN] Name of the property
  876. //
  877. // Return Value:
  878. // ERROR_SUCCESS if the property was found, other Win32 code if not.
  879. //
  880. //--
  881. /////////////////////////////////////////////////////////////////////////////
  882. DWORD CClusPropList::ScMoveToPropertyByName( IN LPCWSTR pwszPropName )
  883. {
  884. Assert( m_cbhPropList.pb != NULL );
  885. DWORD _sc;
  886. _sc = ScMoveToFirstProperty();
  887. if ( _sc == ERROR_SUCCESS )
  888. {
  889. do
  890. {
  891. //
  892. // See if this is the specified property. If so, we're done.
  893. //
  894. if ( ClRtlStrICmp( m_cbhCurrentPropName.pName->sz, pwszPropName ) == 0 )
  895. {
  896. break;
  897. } // if: property found
  898. //
  899. // Advance to the next property.
  900. //
  901. _sc = ScMoveToNextProperty(); // No TW32 because we expect an error when at the end
  902. } while ( _sc == ERROR_SUCCESS ); // do-while: not end of list
  903. } // if: successfully moved to the first property
  904. return _sc;
  905. } //*** ClusPropList::ScMoveToPropertyByName( LPCWSTR )
  906. /////////////////////////////////////////////////////////////////////////////
  907. //++
  908. //
  909. // CClusPropList::ScAllocPropList
  910. //
  911. // Description:
  912. // Allocate a property list buffer that's big enough to hold the next
  913. // property.
  914. //
  915. // Arguments:
  916. // cbMinimum [IN] Minimum size of the property list.
  917. //
  918. // Return Value:
  919. // ERROR_SUCCESS
  920. // ERROR_NOT_ENOUGH_MEMORY
  921. // Other Win32 error codes
  922. //
  923. //--
  924. /////////////////////////////////////////////////////////////////////////////
  925. DWORD CClusPropList::ScAllocPropList( IN size_t cbMinimum )
  926. {
  927. Assert( cbMinimum > 0 );
  928. DWORD _sc = ERROR_SUCCESS;
  929. size_t _cbTotal = 0;
  930. //
  931. // Add the size of the item count and final endmark.
  932. //
  933. cbMinimum += sizeof( CLUSPROP_VALUE );
  934. _cbTotal = m_cbDataSize + cbMinimum;
  935. if ( m_cbBufferSize < _cbTotal )
  936. {
  937. PBYTE _pbNewProplist = NULL;
  938. cbMinimum = max( BUFFER_GROWTH_FACTOR, cbMinimum );
  939. _cbTotal = m_cbDataSize + cbMinimum;
  940. //
  941. // Allocate and zero a new buffer.
  942. //
  943. _pbNewProplist = new BYTE[ _cbTotal ];
  944. if ( _pbNewProplist != NULL )
  945. {
  946. ZeroMemory( _pbNewProplist, _cbTotal );
  947. //
  948. // If there was a previous buffer, copy it and the delete it.
  949. //
  950. if ( m_cbhPropList.pb != NULL )
  951. {
  952. if ( m_cbDataSize != 0 )
  953. {
  954. CopyMemory( _pbNewProplist, m_cbhPropList.pb, m_cbDataSize );
  955. } // if: data already exists in buffer
  956. delete [] m_cbhPropList.pb;
  957. m_cbhCurrentProp.pb = _pbNewProplist + (m_cbhCurrentProp.pb - m_cbhPropList.pb);
  958. } // if: there was a previous buffer
  959. else
  960. {
  961. m_cbhCurrentProp.pb = _pbNewProplist + sizeof( DWORD ); // move past prop count
  962. } // else: no previous buffer
  963. //
  964. // Save the new buffer.
  965. //
  966. m_cbhPropList.pb = _pbNewProplist;
  967. m_cbBufferSize = _cbTotal;
  968. } // if: allocation succeeded
  969. else
  970. {
  971. _sc = TW32( ERROR_NOT_ENOUGH_MEMORY );
  972. } // else: allocation failed
  973. } // if: buffer isn't big enough
  974. return _sc;
  975. } //*** CClusPropList::ScAllocPropList
  976. /////////////////////////////////////////////////////////////////////////////
  977. //++
  978. //
  979. // CClusPropList::ScAddProp
  980. //
  981. // Description:
  982. // Add a string property to a property list if it has changed.
  983. //
  984. // Arguments:
  985. // pwszName [IN] Name of the property.
  986. // pwszValue [IN] Value of the property to set in the list.
  987. // pwszPrevValue [IN] Previous value of the property.
  988. //
  989. // Return Value:
  990. // ERROR_SUCCESS or other Win32 error code.
  991. //
  992. //--
  993. /////////////////////////////////////////////////////////////////////////////
  994. DWORD CClusPropList::ScAddProp(
  995. IN LPCWSTR pwszName,
  996. IN LPCWSTR pwszValue,
  997. IN LPCWSTR pwszPrevValue
  998. )
  999. {
  1000. Assert( pwszName != NULL );
  1001. DWORD _sc = ERROR_SUCCESS;
  1002. BOOL _fValuesDifferent = TRUE;
  1003. PCLUSPROP_PROPERTY_NAME _pName;
  1004. PCLUSPROP_SZ _pValue;
  1005. if (( pwszPrevValue != NULL ) && ( wcscmp( pwszValue, pwszPrevValue ) == 0 ))
  1006. {
  1007. _fValuesDifferent = FALSE;
  1008. } // if: we have a prev value and the values are the same
  1009. //
  1010. // If we should always add, or if the new value and the previous value
  1011. // are not equal, add the property to the property list.
  1012. //
  1013. if ( m_fAlwaysAddProp || _fValuesDifferent )
  1014. {
  1015. size_t _cbNameSize;
  1016. size_t _cbDataSize;
  1017. size_t _cbValueSize;
  1018. //
  1019. // Calculate sizes and make sure we have a property list.
  1020. //
  1021. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1022. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1023. _cbDataSize = (wcslen( pwszValue ) + 1) * sizeof( *pwszValue );
  1024. _cbValueSize = sizeof( CLUSPROP_SZ )
  1025. + ALIGN_CLUSPROP( _cbDataSize )
  1026. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1027. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1028. if ( _sc == ERROR_SUCCESS )
  1029. {
  1030. //
  1031. // Set the property name.
  1032. //
  1033. _pName = m_cbhCurrentProp.pName;
  1034. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1035. m_cbhCurrentProp.pb += _cbNameSize;
  1036. //
  1037. // Set the property value.
  1038. //
  1039. _pValue = m_cbhCurrentProp.pStringValue;
  1040. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
  1041. m_cbhCurrentProp.pb += _cbValueSize;
  1042. //
  1043. // Increment the property count and buffer size.
  1044. //
  1045. m_cbhPropList.pList->nPropertyCount++;
  1046. m_cbDataSize += _cbNameSize + _cbValueSize;
  1047. } // if: ScAllocPropList successfully grew the proplist
  1048. } // if: the value has changed
  1049. return _sc;
  1050. } //*** CClusPropList::ScAddProp( LPCWSTR )
  1051. /////////////////////////////////////////////////////////////////////////////
  1052. //++
  1053. //
  1054. // CClusPropList::ScAddMultiSzProp
  1055. //
  1056. // Description:
  1057. // Add a string property to a property list if it has changed.
  1058. //
  1059. // Arguments:
  1060. // pwszName [IN] Name of the property.
  1061. // pwszValue [IN] Value of the property to set in the list.
  1062. // pwszPrevValue [IN] Previous value of the property.
  1063. //
  1064. // Return Value:
  1065. // ERROR_SUCCESS or other Win32 error code.
  1066. //
  1067. //--
  1068. /////////////////////////////////////////////////////////////////////////////
  1069. DWORD CClusPropList::ScAddMultiSzProp(
  1070. IN LPCWSTR pwszName,
  1071. IN LPCWSTR pwszValue,
  1072. IN LPCWSTR pwszPrevValue
  1073. )
  1074. {
  1075. Assert( pwszName != NULL );
  1076. DWORD _sc = ERROR_SUCCESS;
  1077. BOOL _fValuesDifferent = TRUE;
  1078. PCLUSPROP_PROPERTY_NAME _pName;
  1079. PCLUSPROP_MULTI_SZ _pValue;
  1080. if ( ( pwszPrevValue != NULL ) && ( NCompareMultiSz( pwszValue, pwszPrevValue ) == 0 ) )
  1081. {
  1082. _fValuesDifferent = FALSE;
  1083. } // if: we have a prev value and the values are the same
  1084. //
  1085. // If we should always add, or if the new value and the previous value
  1086. // are not equal, add the property to the property list.
  1087. //
  1088. if ( m_fAlwaysAddProp || _fValuesDifferent )
  1089. {
  1090. size_t _cbNameSize;
  1091. size_t _cbDataSize;
  1092. size_t _cbValueSize;
  1093. //
  1094. // Calculate sizes and make sure we have a property list.
  1095. //
  1096. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1097. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1098. _cbDataSize = static_cast< DWORD >( (CchMultiSz( pwszValue ) + 1) * sizeof( *pwszValue ) );
  1099. _cbValueSize = sizeof( CLUSPROP_SZ )
  1100. + ALIGN_CLUSPROP( _cbDataSize )
  1101. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1102. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1103. if ( _sc == ERROR_SUCCESS )
  1104. {
  1105. //
  1106. // Set the property name.
  1107. //
  1108. _pName = m_cbhCurrentProp.pName;
  1109. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1110. m_cbhCurrentProp.pb += _cbNameSize;
  1111. //
  1112. // Set the property value.
  1113. //
  1114. _pValue = m_cbhCurrentProp.pMultiSzValue;
  1115. CopyMultiSzProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
  1116. m_cbhCurrentProp.pb += _cbValueSize;
  1117. //
  1118. // Increment the property count and buffer size.
  1119. //
  1120. m_cbhPropList.pList->nPropertyCount++;
  1121. m_cbDataSize += _cbNameSize + _cbValueSize;
  1122. } // if: ScAllocPropList successfully grew the proplist
  1123. } // if: the value has changed
  1124. return _sc;
  1125. } //*** CClusPropList::ScAddMultiSzProp( LPCWSTR )
  1126. /////////////////////////////////////////////////////////////////////////////
  1127. //++
  1128. //
  1129. // CClusPropList::ScAddExpandSzProp
  1130. //
  1131. // Description:
  1132. // Add an EXPAND_SZ string property to a property list if it has changed.
  1133. //
  1134. // Arguments:
  1135. // pwszName [IN] Name of the property.
  1136. // pwszValue [IN] Value of the property to set in the list.
  1137. // pwszPrevValue [IN] Previous value of the property.
  1138. //
  1139. // Return Value:
  1140. // None.
  1141. //
  1142. //--
  1143. /////////////////////////////////////////////////////////////////////////////
  1144. DWORD CClusPropList::ScAddExpandSzProp(
  1145. IN LPCWSTR pwszName,
  1146. IN LPCWSTR pwszValue,
  1147. IN LPCWSTR pwszPrevValue
  1148. )
  1149. {
  1150. Assert( pwszName != NULL );
  1151. DWORD _sc = ERROR_SUCCESS;
  1152. BOOL _fValuesDifferent = TRUE;
  1153. PCLUSPROP_PROPERTY_NAME _pName;
  1154. PCLUSPROP_SZ _pValue;
  1155. if ( ( pwszPrevValue != NULL ) && ( wcscmp( pwszValue, pwszPrevValue ) == 0 ) )
  1156. {
  1157. _fValuesDifferent = FALSE;
  1158. } // if: we have a prev value and the values are the same
  1159. //
  1160. // If we should always add, or if the new value and the previous value
  1161. // are not equal, add the property to the property list.
  1162. //
  1163. if ( m_fAlwaysAddProp || _fValuesDifferent )
  1164. {
  1165. size_t _cbNameSize;
  1166. size_t _cbDataSize;
  1167. size_t _cbValueSize;
  1168. //
  1169. // Calculate sizes and make sure we have a property list.
  1170. //
  1171. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1172. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1173. _cbDataSize = (wcslen( pwszValue ) + 1) * sizeof( *pwszValue );
  1174. _cbValueSize = sizeof( CLUSPROP_SZ )
  1175. + ALIGN_CLUSPROP( _cbDataSize )
  1176. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1177. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1178. if ( _sc == ERROR_SUCCESS )
  1179. {
  1180. //
  1181. // Set the property name.
  1182. //
  1183. _pName = m_cbhCurrentProp.pName;
  1184. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1185. m_cbhCurrentProp.pb += _cbNameSize;
  1186. //
  1187. // Set the property value.
  1188. //
  1189. _pValue = m_cbhCurrentProp.pStringValue;
  1190. CopyExpandSzProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pwszValue, _cbDataSize );
  1191. m_cbhCurrentProp.pb += _cbValueSize;
  1192. //
  1193. // Increment the property count and buffer size.
  1194. //
  1195. m_cbhPropList.pList->nPropertyCount++;
  1196. m_cbDataSize += _cbNameSize + _cbValueSize;
  1197. } // if: ScAllocPropList successfully grew the proplist
  1198. } // if: the value has changed
  1199. return _sc;
  1200. } //*** CClusPropList::ScAddExpandSzProp( LPCWSTR )
  1201. /////////////////////////////////////////////////////////////////////////////
  1202. //++
  1203. //
  1204. // CClusPropList::ScAddProp
  1205. //
  1206. // Description:
  1207. // Add a DWORD property to a property list if it has changed.
  1208. //
  1209. // Arguments:
  1210. // pwszName [IN] Name of the property.
  1211. // nValue [IN] Value of the property to set in the list.
  1212. // nPrevValue [IN] Previous value of the property.
  1213. //
  1214. // Return Value:
  1215. // None.
  1216. //
  1217. //--
  1218. /////////////////////////////////////////////////////////////////////////////
  1219. DWORD CClusPropList::ScAddProp(
  1220. IN LPCWSTR pwszName,
  1221. IN DWORD nValue,
  1222. IN DWORD nPrevValue
  1223. )
  1224. {
  1225. Assert( pwszName != NULL );
  1226. DWORD _sc = ERROR_SUCCESS;
  1227. PCLUSPROP_PROPERTY_NAME _pName;
  1228. PCLUSPROP_DWORD _pValue;
  1229. if ( m_fAlwaysAddProp || ( nValue != nPrevValue ) )
  1230. {
  1231. size_t _cbNameSize;
  1232. size_t _cbValueSize;
  1233. //
  1234. // Calculate sizes and make sure we have a property list.
  1235. //
  1236. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1237. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1238. _cbValueSize = sizeof( CLUSPROP_DWORD )
  1239. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1240. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1241. if ( _sc == ERROR_SUCCESS )
  1242. {
  1243. //
  1244. // Set the property name.
  1245. //
  1246. _pName = m_cbhCurrentProp.pName;
  1247. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1248. m_cbhCurrentProp.pb += _cbNameSize;
  1249. //
  1250. // Set the property value.
  1251. //
  1252. _pValue = m_cbhCurrentProp.pDwordValue;
  1253. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, nValue );
  1254. m_cbhCurrentProp.pb += _cbValueSize;
  1255. //
  1256. // Increment the property count and buffer size.
  1257. //
  1258. m_cbhPropList.pList->nPropertyCount++;
  1259. m_cbDataSize += _cbNameSize + _cbValueSize;
  1260. } // if: ScAllocPropList successfully grew the proplist
  1261. } // if: the value has changed
  1262. return _sc;
  1263. } //*** CClusPropList::ScAddProp( DWORD )
  1264. /////////////////////////////////////////////////////////////////////////////
  1265. //++
  1266. //
  1267. // CClusPropList::ScAddProp
  1268. //
  1269. // Description:
  1270. // Add a LONG property to a property list if it has changed.
  1271. //
  1272. // Arguments:
  1273. // pwszName [IN] Name of the property.
  1274. // nValue [IN] Value of the property to set in the list.
  1275. // nPrevValue [IN] Previous value of the property.
  1276. //
  1277. // Return Value:
  1278. // None.
  1279. //
  1280. //--
  1281. /////////////////////////////////////////////////////////////////////////////
  1282. DWORD CClusPropList::ScAddProp(
  1283. IN LPCWSTR pwszName,
  1284. IN LONG nValue,
  1285. IN LONG nPrevValue
  1286. )
  1287. {
  1288. Assert( pwszName != NULL );
  1289. DWORD _sc = ERROR_SUCCESS;
  1290. PCLUSPROP_PROPERTY_NAME _pName;
  1291. PCLUSPROP_LONG _pValue;
  1292. if ( m_fAlwaysAddProp || ( nValue != nPrevValue ) )
  1293. {
  1294. size_t _cbNameSize;
  1295. size_t _cbValueSize;
  1296. //
  1297. // Calculate sizes and make sure we have a property list.
  1298. //
  1299. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1300. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1301. _cbValueSize = sizeof( CLUSPROP_LONG )
  1302. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1303. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1304. if ( _sc == ERROR_SUCCESS )
  1305. {
  1306. //
  1307. // Set the property name.
  1308. //
  1309. _pName = m_cbhCurrentProp.pName;
  1310. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1311. m_cbhCurrentProp.pb += _cbNameSize;
  1312. //
  1313. // Set the property value.
  1314. //
  1315. _pValue = m_cbhCurrentProp.pLongValue;
  1316. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, nValue );
  1317. m_cbhCurrentProp.pb += _cbValueSize;
  1318. //
  1319. // Increment the property count and buffer size.
  1320. //
  1321. m_cbhPropList.pList->nPropertyCount++;
  1322. m_cbDataSize += _cbNameSize + _cbValueSize;
  1323. } // if: ScAllocPropList successfully grew the proplist
  1324. } // if: the value has changed
  1325. return _sc;
  1326. } //*** CClusPropList::ScAddProp( LONG )
  1327. /////////////////////////////////////////////////////////////////////////////
  1328. //++
  1329. //
  1330. // CClusPropList::ScAddProp
  1331. //
  1332. // Description:
  1333. // Add a binary property to a property list if it has changed.
  1334. //
  1335. // Arguments:
  1336. // pwszName [IN] Name of the property.
  1337. // pbValue [IN] Value of the property to set in the list.
  1338. // cbValue [IN] Count of bytes in pbValue.
  1339. // pbPrevValue [IN] Previous value of the property.
  1340. // cbPrevValue [IN] Count of bytes in pbPrevValue.
  1341. //
  1342. // Return Value:
  1343. // None.
  1344. //
  1345. //--
  1346. /////////////////////////////////////////////////////////////////////////////
  1347. DWORD CClusPropList::ScAddProp(
  1348. IN LPCWSTR pwszName,
  1349. IN const unsigned char * pbValue,
  1350. IN size_t cbValue,
  1351. IN const unsigned char * pbPrevValue,
  1352. IN size_t cbPrevValue
  1353. )
  1354. {
  1355. Assert( pwszName != NULL );
  1356. DWORD _sc = ERROR_SUCCESS;
  1357. BOOL _fChanged = FALSE;
  1358. PCLUSPROP_PROPERTY_NAME _pName;
  1359. PCLUSPROP_BINARY _pValue;
  1360. //
  1361. // Determine if the buffer has changed.
  1362. //
  1363. if ( m_fAlwaysAddProp || (cbValue != cbPrevValue) )
  1364. {
  1365. _fChanged = TRUE;
  1366. } // if: always adding the property or the value size changed
  1367. else if ( ( cbValue != 0 ) && ( cbPrevValue != 0 ) )
  1368. {
  1369. _fChanged = memcmp( pbValue, pbPrevValue, cbValue ) != 0;
  1370. } // else if: value length changed
  1371. if ( _fChanged )
  1372. {
  1373. size_t _cbNameSize;
  1374. size_t _cbValueSize;
  1375. //
  1376. // Calculate sizes and make sure we have a property list.
  1377. //
  1378. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1379. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1380. _cbValueSize = sizeof( CLUSPROP_BINARY )
  1381. + ALIGN_CLUSPROP( cbValue )
  1382. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1383. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1384. if ( _sc == ERROR_SUCCESS )
  1385. {
  1386. //
  1387. // Set the property name.
  1388. //
  1389. _pName = m_cbhCurrentProp.pName;
  1390. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1391. m_cbhCurrentProp.pb += _cbNameSize;
  1392. //
  1393. // Set the property value.
  1394. //
  1395. _pValue = m_cbhCurrentProp.pBinaryValue;
  1396. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, pbValue, cbValue );
  1397. m_cbhCurrentProp.pb += _cbValueSize;
  1398. //
  1399. // Increment the property count and buffer size.
  1400. //
  1401. m_cbhPropList.pList->nPropertyCount++;
  1402. m_cbDataSize += _cbNameSize + _cbValueSize;
  1403. } // if: ScAllocPropList successfully grew the proplist
  1404. } // if: the value has changed
  1405. return _sc;
  1406. } //*** CClusPropList::ScAddProp( PBYTE )
  1407. /////////////////////////////////////////////////////////////////////////////
  1408. //++
  1409. //
  1410. // CClusPropList::ScAddProp
  1411. //
  1412. // Routine Description:
  1413. // Add a ULONGLONG property to a property list if it has changed.
  1414. //
  1415. // Arguments:
  1416. // pwszName [IN] Name of the property.
  1417. // ullValue [IN] Value of the property to set in the list.
  1418. // ullPrevValue [IN] Previous value of the property.
  1419. //
  1420. // Return Value:
  1421. // ERROR_SUCCESS or other Win32 error codes.
  1422. //
  1423. //--
  1424. /////////////////////////////////////////////////////////////////////////////
  1425. DWORD CClusPropList::ScAddProp(
  1426. IN LPCWSTR pwszName,
  1427. IN ULONGLONG ullValue,
  1428. IN ULONGLONG ullPrevValue
  1429. )
  1430. {
  1431. Assert( pwszName != NULL );
  1432. DWORD _sc = ERROR_SUCCESS;
  1433. PCLUSPROP_PROPERTY_NAME _pName;
  1434. PCLUSPROP_ULARGE_INTEGER _pValue;
  1435. if ( m_fAlwaysAddProp || ( ullValue != ullPrevValue ) )
  1436. {
  1437. size_t _cbNameSize;
  1438. size_t _cbValueSize;
  1439. //
  1440. // Calculate sizes and make sure we have a property list.
  1441. //
  1442. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1443. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1444. _cbValueSize = sizeof( CLUSPROP_ULARGE_INTEGER )
  1445. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1446. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1447. if ( _sc == ERROR_SUCCESS )
  1448. {
  1449. //
  1450. // Set the property name.
  1451. //
  1452. _pName = m_cbhCurrentProp.pName;
  1453. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1454. m_cbhCurrentProp.pb += _cbNameSize;
  1455. //
  1456. // Set the property value.
  1457. //
  1458. _pValue = m_cbhCurrentProp.pULargeIntegerValue;
  1459. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, ullValue );
  1460. m_cbhCurrentProp.pb += _cbValueSize;
  1461. //
  1462. // Increment the property count and buffer size.
  1463. //
  1464. m_cbhPropList.pList->nPropertyCount++;
  1465. m_cbDataSize += _cbNameSize + _cbValueSize;
  1466. } // if: ScAllocPropList successfully grew the proplist
  1467. } // if: the value has changed
  1468. return _sc;
  1469. } //*** CClusPropList::ScAddProp( ULONGLONG )
  1470. /////////////////////////////////////////////////////////////////////////////
  1471. //++
  1472. //
  1473. // CClusPropList::ScAddProp
  1474. //
  1475. // Routine Description:
  1476. // Add a LONGLONG property to a property list if it has changed.
  1477. //
  1478. // Arguments:
  1479. // pwszName [IN] Name of the property.
  1480. // llValue [IN] Value of the property to set in the list.
  1481. // llPrevValue [IN] Previous value of the property.
  1482. //
  1483. // Return Value:
  1484. // ERROR_SUCCESS or other Win32 status codes.
  1485. //
  1486. //--
  1487. /////////////////////////////////////////////////////////////////////////////
  1488. DWORD CClusPropList::ScAddProp(
  1489. IN LPCWSTR pwszName,
  1490. IN LONGLONG llValue,
  1491. IN LONGLONG llPrevValue
  1492. )
  1493. {
  1494. Assert( pwszName != NULL );
  1495. DWORD _sc = ERROR_SUCCESS;
  1496. PCLUSPROP_PROPERTY_NAME _pName;
  1497. PCLUSPROP_ULARGE_INTEGER _pValue;
  1498. if ( m_fAlwaysAddProp || ( llValue != llPrevValue ) )
  1499. {
  1500. size_t _cbNameSize;
  1501. size_t _cbValueSize;
  1502. //
  1503. // Calculate sizes and make sure we have a property list.
  1504. //
  1505. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1506. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1507. _cbValueSize = sizeof( CLUSPROP_LARGE_INTEGER )
  1508. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1509. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1510. if ( _sc == ERROR_SUCCESS )
  1511. {
  1512. //
  1513. // Set the property name.
  1514. //
  1515. _pName = m_cbhCurrentProp.pName;
  1516. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1517. m_cbhCurrentProp.pb += _cbNameSize;
  1518. //
  1519. // Set the property value.
  1520. //
  1521. _pValue = m_cbhCurrentProp.pULargeIntegerValue;
  1522. CopyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, llValue );
  1523. m_cbhCurrentProp.pb += _cbValueSize;
  1524. //
  1525. // Increment the property count and buffer size.
  1526. //
  1527. m_cbhPropList.pList->nPropertyCount++;
  1528. m_cbDataSize += _cbNameSize + _cbValueSize;
  1529. } // if: ScAllocPropList successfully grew the proplist
  1530. } // if: the value has changed
  1531. return _sc;
  1532. } //*** CClusPropList::ScAddProp( LONGLONG )
  1533. /////////////////////////////////////////////////////////////////////////////
  1534. //++
  1535. //
  1536. // CClusPropList::ScSetPropToDefault
  1537. //
  1538. // Description:
  1539. // Add a property to the property list so that it will revert to its
  1540. // default value.
  1541. //
  1542. // Arguments:
  1543. // pwszName [IN] Name of the property.
  1544. // cpfPropFmt [IN] Format of property
  1545. //
  1546. // Return Value:
  1547. // ERROR_SUCCESS or other Win32 status codes.
  1548. //
  1549. //--
  1550. /////////////////////////////////////////////////////////////////////////////
  1551. DWORD CClusPropList::ScSetPropToDefault(
  1552. IN LPCWSTR pwszName,
  1553. IN CLUSTER_PROPERTY_FORMAT cpfPropFmt
  1554. )
  1555. {
  1556. Assert( pwszName != NULL );
  1557. DWORD _sc = ERROR_SUCCESS;
  1558. size_t _cbNameSize;
  1559. size_t _cbValueSize;
  1560. PCLUSPROP_PROPERTY_NAME _pName;
  1561. PCLUSPROP_VALUE _pValue;
  1562. // Calculate sizes and make sure we have a property list.
  1563. _cbNameSize = sizeof( CLUSPROP_PROPERTY_NAME )
  1564. + ALIGN_CLUSPROP( (wcslen( pwszName ) + 1) * sizeof( *pwszName ) );
  1565. _cbValueSize = sizeof( CLUSPROP_BINARY )
  1566. + sizeof( CLUSPROP_SYNTAX ); // value list endmark
  1567. _sc = TW32( ScAllocPropList( _cbNameSize + _cbValueSize ) );
  1568. if ( _sc == ERROR_SUCCESS )
  1569. {
  1570. //
  1571. // Set the property name.
  1572. //
  1573. _pName = m_cbhCurrentProp.pName;
  1574. CopyProp( _pName, CLUSPROP_TYPE_NAME, pwszName );
  1575. m_cbhCurrentProp.pb += _cbNameSize;
  1576. //
  1577. // Set the property value.
  1578. //
  1579. _pValue = m_cbhCurrentProp.pValue;
  1580. CopyEmptyProp( _pValue, CLUSPROP_TYPE_LIST_VALUE, cpfPropFmt );
  1581. m_cbhCurrentProp.pb += _cbValueSize;
  1582. //
  1583. // Increment the property count and buffer size.
  1584. //
  1585. m_cbhPropList.pList->nPropertyCount++;
  1586. m_cbDataSize += _cbNameSize + _cbValueSize;
  1587. } // if:
  1588. return _sc;
  1589. } //*** CClusPropList::ScSetPropToDefault
  1590. /////////////////////////////////////////////////////////////////////////////
  1591. //++
  1592. //
  1593. // CClusPropList::CopyProp
  1594. //
  1595. // Description:
  1596. // Copy a string property to a property structure.
  1597. //
  1598. // Arguments:
  1599. // pprop [OUT] Property structure to fill.
  1600. // cptPropType [IN] Type of string.
  1601. // psz [IN] String to copy.
  1602. // cbsz [IN] Count of bytes in pwsz string. If specified as 0,
  1603. // the the length will be determined by a call to strlen.
  1604. //
  1605. // Return Value:
  1606. // None.
  1607. //
  1608. //--
  1609. /////////////////////////////////////////////////////////////////////////////
  1610. void CClusPropList::CopyProp(
  1611. OUT PCLUSPROP_SZ pprop,
  1612. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1613. IN LPCWSTR psz,
  1614. IN size_t cbsz // = 0
  1615. )
  1616. {
  1617. Assert( pprop != NULL );
  1618. Assert( psz != NULL );
  1619. CLUSPROP_BUFFER_HELPER _cbhProps;
  1620. HRESULT _hr;
  1621. pprop->Syntax.wFormat = CLUSPROP_FORMAT_SZ;
  1622. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1623. if ( cbsz == 0 )
  1624. {
  1625. cbsz = (wcslen( psz ) + 1) * sizeof( *psz );
  1626. } // if: zero size specified
  1627. Assert( cbsz == (wcslen( psz ) + 1) * sizeof( *psz ) );
  1628. pprop->cbLength = static_cast< DWORD >( cbsz );
  1629. _hr = THR( StringCbCopyW( pprop->sz, cbsz, psz ) );
  1630. if ( SUCCEEDED( _hr ) )
  1631. {
  1632. //
  1633. // Set an endmark.
  1634. //
  1635. _cbhProps.pStringValue = pprop;
  1636. _cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cbsz );
  1637. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1638. }
  1639. } //*** CClusPropList::CopyProp
  1640. /////////////////////////////////////////////////////////////////////////////
  1641. //++
  1642. //
  1643. // CClusPropList::CopyMultiSzProp
  1644. //
  1645. // Description:
  1646. // Copy a MULTI_SZ string property to a property structure.
  1647. //
  1648. // Arguments:
  1649. // pprop [OUT] Property structure to fill.
  1650. // cptPropType [IN] Type of string.
  1651. // psz [IN] String to copy.
  1652. // cbsz [IN] Count of bytes in psz string. If specified as 0,
  1653. // the the length will be determined by calls to strlen.
  1654. //
  1655. // Return Value:
  1656. // None.
  1657. //
  1658. //--
  1659. /////////////////////////////////////////////////////////////////////////////
  1660. void CClusPropList::CopyMultiSzProp(
  1661. OUT PCLUSPROP_MULTI_SZ pprop,
  1662. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1663. IN LPCWSTR psz,
  1664. IN size_t cbsz
  1665. )
  1666. {
  1667. Assert( pprop != NULL );
  1668. Assert( psz != NULL );
  1669. CLUSPROP_BUFFER_HELPER _cbhProps;
  1670. pprop->Syntax.wFormat = CLUSPROP_FORMAT_MULTI_SZ;
  1671. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1672. if ( cbsz == 0 )
  1673. {
  1674. cbsz = (CchMultiSz( psz ) + 1) * sizeof( *psz );
  1675. } // if: zero size specified
  1676. Assert( cbsz == (CchMultiSz( psz ) + 1) * sizeof( *psz ) );
  1677. pprop->cbLength = static_cast< DWORD >( cbsz );
  1678. CopyMemory( pprop->sz, psz, cbsz );
  1679. //
  1680. // Set an endmark.
  1681. //
  1682. _cbhProps.pMultiSzValue = pprop;
  1683. _cbhProps.pb += sizeof( *_cbhProps.pMultiSzValue ) + ALIGN_CLUSPROP( cbsz );
  1684. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1685. } //*** CClusPropList::CopyMultiSzProp
  1686. /////////////////////////////////////////////////////////////////////////////
  1687. //++
  1688. //
  1689. // CClusPropList::CopyExpandSzProp
  1690. //
  1691. // Description:
  1692. // Copy an EXPAND_SZ string property to a property structure.
  1693. //
  1694. // Arguments:
  1695. // pprop [OUT] Property structure to fill.
  1696. // cptPropType [IN] Type of string.
  1697. // psz [IN] String to copy.
  1698. // cbsz [IN] Count of bytes in psz string.
  1699. //
  1700. // Return Value:
  1701. // None.
  1702. //
  1703. //--
  1704. /////////////////////////////////////////////////////////////////////////////
  1705. void CClusPropList::CopyExpandSzProp(
  1706. OUT PCLUSPROP_SZ pprop,
  1707. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1708. IN LPCWSTR psz,
  1709. IN size_t cbsz
  1710. )
  1711. {
  1712. Assert( pprop != NULL );
  1713. Assert( psz != NULL );
  1714. CLUSPROP_BUFFER_HELPER _cbhProps;
  1715. HRESULT _hr;
  1716. pprop->Syntax.wFormat = CLUSPROP_FORMAT_EXPAND_SZ;
  1717. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1718. if ( cbsz == 0 )
  1719. {
  1720. cbsz = (wcslen( psz ) + 1) * sizeof( *psz );
  1721. } // if: cbsz == 0
  1722. Assert( cbsz == (wcslen( psz ) + 1) * sizeof( *psz ) );
  1723. pprop->cbLength = static_cast< DWORD >( cbsz );
  1724. _hr = THR( StringCbCopyW( pprop->sz, cbsz, psz ) );
  1725. if ( SUCCEEDED( _hr ) )
  1726. {
  1727. //
  1728. // Set an endmark.
  1729. //
  1730. _cbhProps.pStringValue = pprop;
  1731. _cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cbsz );
  1732. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1733. }
  1734. } //*** CClusPropList::CopyExpandSzProp
  1735. /////////////////////////////////////////////////////////////////////////////
  1736. //++
  1737. //
  1738. // CClusPropList::CopyProp
  1739. //
  1740. // Description:
  1741. // Copy a DWORD property to a property structure.
  1742. //
  1743. // Arguments:
  1744. // pprop [OUT] Property structure to fill.
  1745. // cptPropType [IN] Type of DWORD.
  1746. // nValue [IN] Property value to copy.
  1747. //
  1748. // Return Value:
  1749. // None.
  1750. //
  1751. //--
  1752. /////////////////////////////////////////////////////////////////////////////
  1753. void CClusPropList::CopyProp(
  1754. OUT PCLUSPROP_DWORD pprop,
  1755. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1756. IN DWORD nValue
  1757. )
  1758. {
  1759. Assert( pprop != NULL );
  1760. CLUSPROP_BUFFER_HELPER _cbhProps;
  1761. pprop->Syntax.wFormat = CLUSPROP_FORMAT_DWORD;
  1762. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1763. pprop->cbLength = sizeof( DWORD );
  1764. pprop->dw = nValue;
  1765. //
  1766. // Set an endmark.
  1767. //
  1768. _cbhProps.pDwordValue = pprop;
  1769. _cbhProps.pb += sizeof( *_cbhProps.pDwordValue );
  1770. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1771. } //*** CClusPropList::CopyProp( DWORD )
  1772. /////////////////////////////////////////////////////////////////////////////
  1773. //++
  1774. //
  1775. // CClusPropList::CopyProp
  1776. //
  1777. // Description:
  1778. // Copy a LONG property to a property structure.
  1779. //
  1780. // Arguments:
  1781. // pprop [OUT] Property structure to fill.
  1782. // cptPropType [IN] Type of LONG.
  1783. // nValue [IN] Property value to copy.
  1784. //
  1785. // Return Value:
  1786. // None.
  1787. //
  1788. //--
  1789. /////////////////////////////////////////////////////////////////////////////
  1790. void CClusPropList::CopyProp(
  1791. OUT PCLUSPROP_LONG pprop,
  1792. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1793. IN LONG nValue
  1794. )
  1795. {
  1796. Assert( pprop != NULL );
  1797. CLUSPROP_BUFFER_HELPER _cbhProps;
  1798. pprop->Syntax.wFormat = CLUSPROP_FORMAT_LONG;
  1799. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1800. pprop->cbLength = sizeof( DWORD );
  1801. pprop->l = nValue;
  1802. //
  1803. // Set an endmark.
  1804. //
  1805. _cbhProps.pLongValue = pprop;
  1806. _cbhProps.pb += sizeof( *_cbhProps.pLongValue );
  1807. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1808. } //*** CClusPropList::CopyProp( LONG )
  1809. /////////////////////////////////////////////////////////////////////////////
  1810. //++
  1811. //
  1812. // CClusPropList::CopyProp
  1813. //
  1814. // Description:
  1815. // Copy a ULONGLONG property to a property structure.
  1816. //
  1817. // Arguments:
  1818. // pprop [OUT] Property structure to fill.
  1819. // proptype [IN] Type of LONG.
  1820. // ullValue [IN] Property value to copy.
  1821. //
  1822. // Return Value:
  1823. // None.
  1824. //
  1825. //--
  1826. /////////////////////////////////////////////////////////////////////////////
  1827. void CClusPropList::CopyProp(
  1828. OUT PCLUSPROP_ULARGE_INTEGER pprop,
  1829. IN CLUSTER_PROPERTY_TYPE proptype,
  1830. IN ULONGLONG ullValue
  1831. )
  1832. {
  1833. Assert( pprop != NULL );
  1834. CLUSPROP_BUFFER_HELPER _cbhProps;
  1835. pprop->Syntax.wFormat = CLUSPROP_FORMAT_ULARGE_INTEGER;
  1836. pprop->Syntax.wType = static_cast< WORD >( proptype );
  1837. pprop->cbLength = sizeof( ULONGLONG );
  1838. //
  1839. // pprop may not have the correct alignment for large ints; copy as two
  1840. // DWORDs to be safe
  1841. //
  1842. pprop->li.u = ((ULARGE_INTEGER *)&ullValue)->u;
  1843. //
  1844. // Set an endmark.
  1845. //
  1846. _cbhProps.pULargeIntegerValue = pprop;
  1847. _cbhProps.pb += sizeof( *_cbhProps.pULargeIntegerValue );
  1848. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1849. } //*** CClusPropList::CopyProp( ULONGLONG )
  1850. /////////////////////////////////////////////////////////////////////////////
  1851. //++
  1852. //
  1853. // CClusPropList::CopyProp
  1854. //
  1855. // Description:
  1856. // Copy a LONGLONG property to a property structure.
  1857. //
  1858. // Arguments:
  1859. // pprop [OUT] Property structure to fill.
  1860. // proptype [IN] Type of LONG.
  1861. // llValue [IN] Property value to copy.
  1862. //
  1863. // Return Value:
  1864. // None.
  1865. //
  1866. //--
  1867. /////////////////////////////////////////////////////////////////////////////
  1868. void CClusPropList::CopyProp(
  1869. OUT PCLUSPROP_LARGE_INTEGER pprop,
  1870. IN CLUSTER_PROPERTY_TYPE proptype,
  1871. IN LONGLONG llValue
  1872. )
  1873. {
  1874. Assert( pprop != NULL );
  1875. CLUSPROP_BUFFER_HELPER _cbhProps;
  1876. pprop->Syntax.wFormat = CLUSPROP_FORMAT_LARGE_INTEGER;
  1877. pprop->Syntax.wType = static_cast< WORD >( proptype );
  1878. pprop->cbLength = sizeof( LONGLONG );
  1879. //
  1880. // pprop may not have the correct alignment for large ints; copy as two
  1881. // DWORDs to be safe
  1882. //
  1883. pprop->li.u = ((LARGE_INTEGER *)&llValue)->u;
  1884. //
  1885. // Set an endmark.
  1886. //
  1887. _cbhProps.pLargeIntegerValue = pprop;
  1888. _cbhProps.pb += sizeof( *_cbhProps.pLargeIntegerValue );
  1889. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1890. } //*** CClusPropList::CopyProp( LONGLONG )
  1891. /////////////////////////////////////////////////////////////////////////////
  1892. //++
  1893. //
  1894. // CClusPropList::CopyProp
  1895. //
  1896. // Description:
  1897. // Copy a binary property to a property structure.
  1898. //
  1899. // Arguments:
  1900. // pprop [OUT] Property structure to fill.
  1901. // cptPropType [IN] Type of string.
  1902. // pb [IN] Block to copy.
  1903. // cbsz [IN] Count of bytes in pb buffer.
  1904. //
  1905. // Return Value:
  1906. // None.
  1907. //
  1908. //--
  1909. /////////////////////////////////////////////////////////////////////////////
  1910. void CClusPropList::CopyProp(
  1911. OUT PCLUSPROP_BINARY pprop,
  1912. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1913. IN const unsigned char * pb,
  1914. IN size_t cb
  1915. )
  1916. {
  1917. Assert( pprop != NULL );
  1918. CLUSPROP_BUFFER_HELPER _cbhProps;
  1919. pprop->Syntax.wFormat = CLUSPROP_FORMAT_BINARY;
  1920. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1921. pprop->cbLength = static_cast< DWORD >( cb );
  1922. if ( cb > 0 )
  1923. {
  1924. CopyMemory( pprop->rgb, pb, cb );
  1925. } // if: non-zero data length
  1926. //
  1927. // Set an endmark.
  1928. //
  1929. _cbhProps.pBinaryValue = pprop;
  1930. _cbhProps.pb += sizeof( *_cbhProps.pStringValue ) + ALIGN_CLUSPROP( cb );
  1931. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1932. } //*** CClusPropList::CopyProp( PBYTE )
  1933. /////////////////////////////////////////////////////////////////////////////
  1934. //++
  1935. //
  1936. // CClusPropList::CopyEmptyProp
  1937. //
  1938. // Description:
  1939. // Copy an empty property to a property structure.
  1940. //
  1941. // Arguments:
  1942. // pprop [OUT] Property structure to fill.
  1943. // cptPropType [IN] Type of property.
  1944. // cpfPropFmt [IN] Format of property.
  1945. //
  1946. // Return Value:
  1947. // None.
  1948. //
  1949. //--
  1950. /////////////////////////////////////////////////////////////////////////////
  1951. void CClusPropList::CopyEmptyProp(
  1952. OUT PCLUSPROP_VALUE pprop,
  1953. IN CLUSTER_PROPERTY_TYPE cptPropType,
  1954. IN CLUSTER_PROPERTY_FORMAT cptPropFmt
  1955. )
  1956. {
  1957. Assert( pprop != NULL );
  1958. CLUSPROP_BUFFER_HELPER _cbhProps;
  1959. pprop->Syntax.wFormat = static_cast< WORD >( cptPropFmt );
  1960. pprop->Syntax.wType = static_cast< WORD >( cptPropType );
  1961. pprop->cbLength = 0;
  1962. //
  1963. // Set an endmark.
  1964. //
  1965. _cbhProps.pValue = pprop;
  1966. _cbhProps.pb += sizeof( *_cbhProps.pValue );
  1967. _cbhProps.pSyntax->dw = CLUSPROP_SYNTAX_ENDMARK;
  1968. } //*** CClusPropList::CopyEmptyProp
  1969. /////////////////////////////////////////////////////////////////////////////
  1970. //++
  1971. //
  1972. // CClusPropList::ScGetNodeProperties
  1973. //
  1974. // Description:
  1975. // Get properties on a node.
  1976. //
  1977. // Arguments:
  1978. // hNode [IN] Handle for the node to get properties from.
  1979. // dwControlCode [IN] Control code for the request.
  1980. // hHostNode [IN] Handle for the node to direct this request to.
  1981. // Defaults to NULL.
  1982. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  1983. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  1984. //
  1985. // Return Value:
  1986. // None.
  1987. //
  1988. //--
  1989. /////////////////////////////////////////////////////////////////////////////
  1990. DWORD CClusPropList::ScGetNodeProperties(
  1991. IN HNODE hNode,
  1992. IN DWORD dwControlCode,
  1993. IN HNODE hHostNode,
  1994. IN LPVOID lpInBuffer,
  1995. IN size_t cbInBufferSize
  1996. )
  1997. {
  1998. Assert( hNode != NULL );
  1999. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2000. == (CLUS_OBJECT_NODE << CLUSCTL_OBJECT_SHIFT) );
  2001. DWORD _sc = ERROR_SUCCESS;
  2002. DWORD _cbProps = 256;
  2003. //
  2004. // Overwrite anything that may be in the buffer.
  2005. // Allows this class instance to be reused.
  2006. //
  2007. m_cbDataSize = 0;
  2008. //
  2009. // Get properties.
  2010. //
  2011. _sc = TW32( ScAllocPropList( _cbProps ) );
  2012. if ( _sc == ERROR_SUCCESS )
  2013. {
  2014. _sc = TW32E( ClusterNodeControl(
  2015. hNode,
  2016. hHostNode,
  2017. dwControlCode,
  2018. lpInBuffer,
  2019. static_cast< DWORD >( cbInBufferSize ),
  2020. m_cbhPropList.pb,
  2021. static_cast< DWORD >( m_cbBufferSize ),
  2022. &_cbProps
  2023. ), ERROR_MORE_DATA );
  2024. if ( _sc == ERROR_MORE_DATA )
  2025. {
  2026. _sc = TW32( ScAllocPropList( _cbProps ) );
  2027. if ( _sc == ERROR_SUCCESS )
  2028. {
  2029. _sc = TW32( ClusterNodeControl(
  2030. hNode,
  2031. hHostNode,
  2032. dwControlCode,
  2033. lpInBuffer,
  2034. static_cast< DWORD >( cbInBufferSize ),
  2035. m_cbhPropList.pb,
  2036. static_cast< DWORD >( m_cbBufferSize ),
  2037. &_cbProps
  2038. ) );
  2039. } // if: ScAllocPropList succeeded
  2040. } // if: buffer too small
  2041. } // if: ScAllocPropList succeeded
  2042. if ( _sc != ERROR_SUCCESS )
  2043. {
  2044. DeletePropList();
  2045. } // if: error getting properties.
  2046. else
  2047. {
  2048. m_cbDataSize = static_cast< size_t >( _cbProps );
  2049. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2050. } // else: no errors
  2051. return _sc;
  2052. } //*** CClusPropList::ScGetNodeProperties
  2053. /////////////////////////////////////////////////////////////////////////////
  2054. //++
  2055. //
  2056. // CClusPropList::ScGetGroupProperties
  2057. //
  2058. // Description:
  2059. // Get properties on a group.
  2060. //
  2061. // Arguments:
  2062. // hGroup [IN] Handle for the group to get properties from.
  2063. // dwControlCode [IN] Control code for the request.
  2064. // hHostNode [IN] Handle for the node to direct this request to.
  2065. // Defaults to NULL.
  2066. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2067. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2068. //
  2069. // Return Value:
  2070. // None.
  2071. //
  2072. //--
  2073. /////////////////////////////////////////////////////////////////////////////
  2074. DWORD CClusPropList::ScGetGroupProperties(
  2075. IN HGROUP hGroup,
  2076. IN DWORD dwControlCode,
  2077. IN HNODE hHostNode,
  2078. IN LPVOID lpInBuffer,
  2079. IN size_t cbInBufferSize
  2080. )
  2081. {
  2082. Assert( hGroup != NULL );
  2083. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2084. == (CLUS_OBJECT_GROUP << CLUSCTL_OBJECT_SHIFT) );
  2085. DWORD _sc = ERROR_SUCCESS;
  2086. DWORD _cbProps = 256;
  2087. //
  2088. // Overwrite anything that may be in the buffer.
  2089. // Allows this class instance to be reused.
  2090. //
  2091. m_cbDataSize = 0;
  2092. //
  2093. // Get properties.
  2094. //
  2095. _sc = TW32( ScAllocPropList( _cbProps ) );
  2096. if ( _sc == ERROR_SUCCESS )
  2097. {
  2098. _sc = TW32E( ClusterGroupControl(
  2099. hGroup,
  2100. hHostNode,
  2101. dwControlCode,
  2102. lpInBuffer,
  2103. static_cast< DWORD >( cbInBufferSize ),
  2104. m_cbhPropList.pb,
  2105. static_cast< DWORD >( m_cbBufferSize ),
  2106. &_cbProps
  2107. ), ERROR_MORE_DATA );
  2108. if ( _sc == ERROR_MORE_DATA )
  2109. {
  2110. _sc = TW32( ScAllocPropList( _cbProps ) );
  2111. if ( _sc == ERROR_SUCCESS )
  2112. {
  2113. _sc = TW32( ClusterGroupControl(
  2114. hGroup,
  2115. hHostNode,
  2116. dwControlCode,
  2117. lpInBuffer,
  2118. static_cast< DWORD >( cbInBufferSize ),
  2119. m_cbhPropList.pb,
  2120. static_cast< DWORD >( m_cbBufferSize ),
  2121. &_cbProps
  2122. ) );
  2123. } // if: ScAllocPropList succeeded
  2124. } // if: buffer too small
  2125. } // if: ScAllocPropList succeeded
  2126. if ( _sc != ERROR_SUCCESS )
  2127. {
  2128. DeletePropList();
  2129. } // if: error getting properties.
  2130. else
  2131. {
  2132. m_cbDataSize = static_cast< size_t >( _cbProps );
  2133. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2134. } // else: no errors
  2135. return _sc;
  2136. } //*** CClusPropList::ScGetGroupProperties
  2137. /////////////////////////////////////////////////////////////////////////////
  2138. //++
  2139. //
  2140. // CClusPropList::ScGetResourceProperties
  2141. //
  2142. // Description:
  2143. // Get properties on a resource.
  2144. //
  2145. // Arguments:
  2146. // hResource [IN] Handle for the resource to get properties from.
  2147. // dwControlCode [IN] Control code for the request.
  2148. // hHostNode [IN] Handle for the node to direct this request to.
  2149. // Defaults to NULL.
  2150. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2151. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2152. //
  2153. // Return Value:
  2154. // None.
  2155. //
  2156. //--
  2157. /////////////////////////////////////////////////////////////////////////////
  2158. DWORD CClusPropList::ScGetResourceProperties(
  2159. IN HRESOURCE hResource,
  2160. IN DWORD dwControlCode,
  2161. IN HNODE hHostNode,
  2162. IN LPVOID lpInBuffer,
  2163. IN size_t cbInBufferSize
  2164. )
  2165. {
  2166. Assert( hResource != NULL );
  2167. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2168. == (CLUS_OBJECT_RESOURCE << CLUSCTL_OBJECT_SHIFT) );
  2169. DWORD _sc = ERROR_SUCCESS;
  2170. DWORD _cbProps = 256;
  2171. //
  2172. // Overwrite anything that may be in the buffer.
  2173. // Allows this class instance to be reused.
  2174. //
  2175. m_cbDataSize = 0;
  2176. //
  2177. // Get properties.
  2178. //
  2179. _sc = TW32( ScAllocPropList( _cbProps ) );
  2180. if ( _sc == ERROR_SUCCESS )
  2181. {
  2182. _sc = TW32E( ClusterResourceControl(
  2183. hResource,
  2184. hHostNode,
  2185. dwControlCode,
  2186. lpInBuffer,
  2187. static_cast< DWORD >( cbInBufferSize ),
  2188. m_cbhPropList.pb,
  2189. static_cast< DWORD >( m_cbBufferSize ),
  2190. &_cbProps
  2191. ), ERROR_MORE_DATA );
  2192. if ( _sc == ERROR_MORE_DATA )
  2193. {
  2194. _sc = TW32( ScAllocPropList( _cbProps ) );
  2195. if ( _sc == ERROR_SUCCESS )
  2196. {
  2197. _sc = TW32( ClusterResourceControl(
  2198. hResource,
  2199. hHostNode,
  2200. dwControlCode,
  2201. lpInBuffer,
  2202. static_cast< DWORD >( cbInBufferSize ),
  2203. m_cbhPropList.pb,
  2204. static_cast< DWORD >( m_cbBufferSize ),
  2205. &_cbProps
  2206. ) );
  2207. } // if: ScAllocPropList succeeded
  2208. } // if: buffer too small
  2209. } // if: ScAllocPropList succeeded
  2210. if ( _sc != ERROR_SUCCESS )
  2211. {
  2212. DeletePropList();
  2213. } // if: error getting properties.
  2214. else
  2215. {
  2216. m_cbDataSize = static_cast< size_t >( _cbProps );
  2217. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2218. } // else: no errors
  2219. return _sc;
  2220. } //*** CClusPropList::ScGetResourceProperties
  2221. /////////////////////////////////////////////////////////////////////////////
  2222. //++
  2223. //
  2224. // CClusPropList::ScGetResourceTypeProperties
  2225. //
  2226. // Description:
  2227. // Get properties on a resource type.
  2228. //
  2229. // Arguments:
  2230. // hCluster [IN] Handle for the cluster in which the resource
  2231. // type resides.
  2232. // pwszResTypeName [IN] Name of the resource type.
  2233. // dwControlCode [IN] Control code for the request.
  2234. // hHostNode [IN] Handle for the node to direct this request to.
  2235. // Defaults to NULL.
  2236. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2237. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2238. //
  2239. // Return Value:
  2240. // None.
  2241. //
  2242. //--
  2243. /////////////////////////////////////////////////////////////////////////////
  2244. DWORD CClusPropList::ScGetResourceTypeProperties(
  2245. IN HCLUSTER hCluster,
  2246. IN LPCWSTR pwszResTypeName,
  2247. IN DWORD dwControlCode,
  2248. IN HNODE hHostNode,
  2249. IN LPVOID lpInBuffer,
  2250. IN size_t cbInBufferSize
  2251. )
  2252. {
  2253. Assert( hCluster != NULL );
  2254. Assert( pwszResTypeName != NULL );
  2255. Assert( *pwszResTypeName != L'\0' );
  2256. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2257. == (CLUS_OBJECT_RESOURCE_TYPE << CLUSCTL_OBJECT_SHIFT) );
  2258. DWORD _sc = ERROR_SUCCESS;
  2259. DWORD _cbProps = 256;
  2260. //
  2261. // Overwrite anything that may be in the buffer.
  2262. // Allows this class instance to be reused.
  2263. //
  2264. m_cbDataSize = 0;
  2265. //
  2266. // Get properties.
  2267. //
  2268. _sc = TW32( ScAllocPropList( _cbProps ) );
  2269. if ( _sc == ERROR_SUCCESS )
  2270. {
  2271. _sc = TW32E( ClusterResourceTypeControl(
  2272. hCluster,
  2273. pwszResTypeName,
  2274. hHostNode,
  2275. dwControlCode,
  2276. lpInBuffer,
  2277. static_cast< DWORD >( cbInBufferSize ),
  2278. m_cbhPropList.pb,
  2279. static_cast< DWORD >( m_cbBufferSize ),
  2280. &_cbProps
  2281. ), ERROR_MORE_DATA );
  2282. if ( _sc == ERROR_MORE_DATA )
  2283. {
  2284. _sc = TW32( ScAllocPropList( _cbProps ) );
  2285. if ( _sc == ERROR_SUCCESS )
  2286. {
  2287. _sc = TW32( ClusterResourceTypeControl(
  2288. hCluster,
  2289. pwszResTypeName,
  2290. hHostNode,
  2291. dwControlCode,
  2292. lpInBuffer,
  2293. static_cast< DWORD >( cbInBufferSize ),
  2294. m_cbhPropList.pb,
  2295. static_cast< DWORD >( m_cbBufferSize ),
  2296. &_cbProps
  2297. ) );
  2298. } // if: ScAllocPropList succeeded
  2299. } // if: buffer too small
  2300. } // if: ScAllocPropList succeeded
  2301. if ( _sc != ERROR_SUCCESS )
  2302. {
  2303. DeletePropList();
  2304. } // if: error getting properties.
  2305. else
  2306. {
  2307. m_cbDataSize = static_cast< size_t >( _cbProps );
  2308. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2309. } // else: no errors
  2310. return _sc;
  2311. } //*** CClusPropList::ScGetResourceTypeProperties
  2312. /////////////////////////////////////////////////////////////////////////////
  2313. //++
  2314. //
  2315. // CClusPropList::ScGetNetworkProperties
  2316. //
  2317. // Description:
  2318. // Get properties on a network.
  2319. //
  2320. // Arguments:
  2321. // hNetwork [IN] Handle for the network to get properties from.
  2322. // dwControlCode [IN] Control code for the request.
  2323. // hHostNode [IN] Handle for the node to direct this request to.
  2324. // Defaults to NULL.
  2325. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2326. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2327. //
  2328. // Return Value:
  2329. // None.
  2330. //
  2331. //--
  2332. /////////////////////////////////////////////////////////////////////////////
  2333. DWORD CClusPropList::ScGetNetworkProperties(
  2334. IN HNETWORK hNetwork,
  2335. IN DWORD dwControlCode,
  2336. IN HNODE hHostNode,
  2337. IN LPVOID lpInBuffer,
  2338. IN size_t cbInBufferSize
  2339. )
  2340. {
  2341. Assert( hNetwork != NULL );
  2342. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2343. == (CLUS_OBJECT_NETWORK << CLUSCTL_OBJECT_SHIFT) );
  2344. DWORD _sc = ERROR_SUCCESS;
  2345. DWORD _cbProps = 256;
  2346. //
  2347. // Overwrite anything that may be in the buffer.
  2348. // Allows this class instance to be reused.
  2349. //
  2350. m_cbDataSize = 0;
  2351. //
  2352. // Get properties.
  2353. //
  2354. _sc = TW32( ScAllocPropList( _cbProps ) );
  2355. if ( _sc == ERROR_SUCCESS )
  2356. {
  2357. _sc = TW32E( ClusterNetworkControl(
  2358. hNetwork,
  2359. hHostNode,
  2360. dwControlCode,
  2361. lpInBuffer,
  2362. static_cast< DWORD >( cbInBufferSize ),
  2363. m_cbhPropList.pb,
  2364. static_cast< DWORD >( m_cbBufferSize ),
  2365. &_cbProps
  2366. ), ERROR_MORE_DATA );
  2367. if ( _sc == ERROR_MORE_DATA )
  2368. {
  2369. _sc = TW32( ScAllocPropList( _cbProps ) );
  2370. if ( _sc == ERROR_SUCCESS )
  2371. {
  2372. _sc = TW32( ClusterNetworkControl(
  2373. hNetwork,
  2374. hHostNode,
  2375. dwControlCode,
  2376. lpInBuffer,
  2377. static_cast< DWORD >( cbInBufferSize ),
  2378. m_cbhPropList.pb,
  2379. static_cast< DWORD >( m_cbBufferSize ),
  2380. &_cbProps
  2381. ) );
  2382. } // if: ScAllocPropList succeeded
  2383. } // if: buffer too small
  2384. } // if: ScAllocPropList succeeded
  2385. if ( _sc != ERROR_SUCCESS )
  2386. {
  2387. DeletePropList();
  2388. } // if: error getting private properties.
  2389. else
  2390. {
  2391. m_cbDataSize = static_cast< size_t >( _cbProps );
  2392. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2393. } // else: no errors
  2394. return _sc;
  2395. } //*** CClusPropList::ScGetNetworkProperties
  2396. /////////////////////////////////////////////////////////////////////////////
  2397. //++
  2398. //
  2399. // CClusPropList::ScGetNetInterfaceProperties
  2400. //
  2401. // Description:
  2402. // Get properties on a network interface.
  2403. //
  2404. // Arguments:
  2405. // hNetInterface [IN] Handle for the network interface to get properties from.
  2406. // dwControlCode [IN] Control code for the request.
  2407. // hHostNode [IN] Handle for the node to direct this request to.
  2408. // Defaults to NULL.
  2409. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2410. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2411. //
  2412. // Return Value:
  2413. // None.
  2414. //
  2415. //--
  2416. /////////////////////////////////////////////////////////////////////////////
  2417. DWORD CClusPropList::ScGetNetInterfaceProperties(
  2418. IN HNETINTERFACE hNetInterface,
  2419. IN DWORD dwControlCode,
  2420. IN HNODE hHostNode,
  2421. IN LPVOID lpInBuffer,
  2422. IN size_t cbInBufferSize
  2423. )
  2424. {
  2425. Assert( hNetInterface != NULL );
  2426. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2427. == (CLUS_OBJECT_NETINTERFACE << CLUSCTL_OBJECT_SHIFT) );
  2428. DWORD _sc= ERROR_SUCCESS;
  2429. DWORD _cbProps = 256;
  2430. //
  2431. // Overwrite anything that may be in the buffer.
  2432. // Allows this class instance to be reused.
  2433. //
  2434. m_cbDataSize = 0;
  2435. //
  2436. // Get properties.
  2437. //
  2438. _sc = TW32( ScAllocPropList( _cbProps ) );
  2439. if ( _sc == ERROR_SUCCESS )
  2440. {
  2441. _sc = TW32E( ClusterNetInterfaceControl(
  2442. hNetInterface,
  2443. hHostNode,
  2444. dwControlCode,
  2445. lpInBuffer,
  2446. static_cast< DWORD >( cbInBufferSize ),
  2447. m_cbhPropList.pb,
  2448. static_cast< DWORD >( m_cbBufferSize ),
  2449. &_cbProps
  2450. ), ERROR_MORE_DATA );
  2451. if ( _sc == ERROR_MORE_DATA )
  2452. {
  2453. _sc = TW32( ScAllocPropList( _cbProps ) );
  2454. if ( _sc == ERROR_SUCCESS )
  2455. {
  2456. _sc = TW32( ClusterNetInterfaceControl(
  2457. hNetInterface,
  2458. hHostNode,
  2459. dwControlCode,
  2460. lpInBuffer,
  2461. static_cast< DWORD >( cbInBufferSize ),
  2462. m_cbhPropList.pb,
  2463. static_cast< DWORD >( m_cbBufferSize ),
  2464. &_cbProps
  2465. ) );
  2466. } // if: ScAllocPropList succeeded
  2467. } // if: buffer too small
  2468. } // if: ScAllocPropList succeeded
  2469. if ( _sc != ERROR_SUCCESS )
  2470. {
  2471. DeletePropList();
  2472. } // if: error getting private properties.
  2473. else
  2474. {
  2475. m_cbDataSize = static_cast< size_t >( _cbProps );
  2476. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2477. } // else: no errors
  2478. return _sc;
  2479. } //*** CClusPropList::ScGetNetInterfaceProperties
  2480. /////////////////////////////////////////////////////////////////////////////
  2481. //++
  2482. //
  2483. // CClusPropList::ScGetClusterProperties
  2484. //
  2485. // Description:
  2486. // Get properties on a cluster.
  2487. //
  2488. // Arguments:
  2489. // hCluster [IN] Handle for the cluster to get properties from.
  2490. // dwControlCode [IN] Control code for the request.
  2491. // hHostNode [IN] Handle for the node to direct this request to.
  2492. // Defaults to NULL.
  2493. // lpInBuffer [IN] Input buffer for the request. Defaults to NULL.
  2494. // cbInBufferSize [IN] Size of the input buffer. Defaults to 0.
  2495. //
  2496. // Return Value:
  2497. // None.
  2498. //
  2499. //--
  2500. /////////////////////////////////////////////////////////////////////////////
  2501. DWORD CClusPropList::ScGetClusterProperties(
  2502. IN HCLUSTER hCluster,
  2503. IN DWORD dwControlCode,
  2504. IN HNODE hHostNode,
  2505. IN LPVOID lpInBuffer,
  2506. IN size_t cbInBufferSize
  2507. )
  2508. {
  2509. Assert( hCluster != NULL );
  2510. Assert( (dwControlCode & (CLUSCTL_OBJECT_MASK << CLUSCTL_OBJECT_SHIFT))
  2511. == (CLUS_OBJECT_CLUSTER << CLUSCTL_OBJECT_SHIFT) );
  2512. DWORD _sc= ERROR_SUCCESS;
  2513. DWORD _cbProps = 256;
  2514. //
  2515. // Overwrite anything that may be in the buffer.
  2516. // Allows this class instance to be reused.
  2517. //
  2518. m_cbDataSize = 0;
  2519. //
  2520. // Get properties.
  2521. //
  2522. _sc = TW32( ScAllocPropList( _cbProps ) );
  2523. if ( _sc == ERROR_SUCCESS )
  2524. {
  2525. _sc = TW32E( ClusterControl(
  2526. hCluster,
  2527. hHostNode,
  2528. dwControlCode,
  2529. lpInBuffer,
  2530. static_cast< DWORD >( cbInBufferSize ),
  2531. m_cbhPropList.pb,
  2532. static_cast< DWORD >( m_cbBufferSize ),
  2533. &_cbProps
  2534. ), ERROR_MORE_DATA );
  2535. if ( _sc == ERROR_MORE_DATA )
  2536. {
  2537. _sc = TW32( ScAllocPropList( _cbProps ) );
  2538. if ( _sc == ERROR_SUCCESS )
  2539. {
  2540. _sc = TW32( ClusterControl(
  2541. hCluster,
  2542. hHostNode,
  2543. dwControlCode,
  2544. lpInBuffer,
  2545. static_cast< DWORD >( cbInBufferSize ),
  2546. m_cbhPropList.pb,
  2547. static_cast< DWORD >( m_cbBufferSize ),
  2548. &_cbProps
  2549. ) );
  2550. } // if: ScAllocPropList succeeded
  2551. } // if: buffer too small
  2552. } // if: ScAllocPropList succeeded
  2553. if ( _sc != ERROR_SUCCESS )
  2554. {
  2555. DeletePropList();
  2556. } // if: error getting private properties.
  2557. else
  2558. {
  2559. m_cbDataSize = static_cast< size_t >( _cbProps );
  2560. m_cbDataLeft = static_cast< size_t >( _cbProps );
  2561. } // else: no errors
  2562. return _sc;
  2563. } //*** CClusPropList::ScGetClusterProperties