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.

487 lines
15 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 1998-2000 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ClusterObject.cpp
  7. //
  8. // Description:
  9. // Implementation of ClusterObject
  10. //
  11. // Author:
  12. // Galen Barbee (GalenB) 14-Dec-1998
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "ClusterObject.h"
  21. #include "property.h"
  22. //*************************************************************************//
  23. /////////////////////////////////////////////////////////////////////////////
  24. // CClusterObject class
  25. /////////////////////////////////////////////////////////////////////////////
  26. /////////////////////////////////////////////////////////////////////////////
  27. //++
  28. //
  29. // CClusterObject::HrSaveProperties
  30. //
  31. // Description:
  32. // Save the properties to the cluster database.
  33. //
  34. // Arguments:
  35. // cpvProps [IN OUT] - The properties to save.
  36. // bPrivate [IN] - Are these private properties?
  37. // pvarStatusCode [OUT] - Catches additional status.
  38. //
  39. // Return Value:
  40. // S_OK if successful, or Win32 error as HRESULT if not.
  41. //
  42. //--
  43. /////////////////////////////////////////////////////////////////////////////
  44. HRESULT CClusterObject::HrSaveProperties(
  45. IN OUT CClusProperties::CClusPropertyVector & cpvProps,
  46. IN BOOL bPrivate,
  47. OUT VARIANT * pvarStatusCode
  48. )
  49. {
  50. HRESULT _hr = S_FALSE;
  51. CClusPropList _cplPropList( TRUE ); // always add the prop...
  52. DWORD sc;
  53. sc = _cplPropList.ScAllocPropList( 8192 );
  54. _hr = HRESULT_FROM_WIN32( sc );
  55. if ( SUCCEEDED( _hr ) )
  56. {
  57. _hr = HrBuildPropertyList( cpvProps, _cplPropList );
  58. if ( SUCCEEDED( _hr ) )
  59. {
  60. DWORD _sc = ERROR_SUCCESS;
  61. _sc = ScWriteProperties( _cplPropList, bPrivate );
  62. pvarStatusCode->vt = VT_ERROR; // fill in the error code info
  63. pvarStatusCode->scode = _sc;
  64. if ( _sc == ERROR_RESOURCE_PROPERTIES_STORED )
  65. {
  66. _hr = S_OK;
  67. } // if: if ERROR_RESOURCE_PROPERTIES_STORED then convert to S_OK...
  68. else
  69. {
  70. _hr = HRESULT_FROM_WIN32( _sc );
  71. } // else: simply use the status code as is...
  72. } // if:
  73. } // if:
  74. return _hr;
  75. } //*** CClusterObject::HrSaveProperties()
  76. /////////////////////////////////////////////////////////////////////////////
  77. //++
  78. //
  79. // CClusterObject::HrBuildPropertyList
  80. //
  81. // Description:
  82. // Build a proper property list from the passed in properties collection.
  83. //
  84. // Arguments:
  85. // cpvProps [IN, OUT] - The vector that is the properties.
  86. // rcplPropList [OUT] - The property list to add to.
  87. //
  88. // Return Value:
  89. // S_OK if successful, or Win32 error as HRESULT if not.
  90. //
  91. //--
  92. /////////////////////////////////////////////////////////////////////////////
  93. HRESULT CClusterObject::HrBuildPropertyList(
  94. IN OUT CClusProperties::CClusPropertyVector & cpvProps,
  95. OUT CClusPropList & rcplPropList
  96. )
  97. {
  98. HRESULT _hr = S_OK;
  99. CComObject< CClusProperty > * _pProperty = 0;
  100. CClusProperties::CClusPropertyVector::iterator _itCurrent = cpvProps.begin();
  101. CClusProperties::CClusPropertyVector::const_iterator _itLast = cpvProps.end();
  102. DWORD _sc = ERROR_SUCCESS;
  103. CLUSTER_PROPERTY_FORMAT _cpfFormat = CLUSPROP_FORMAT_UNKNOWN;
  104. for ( ; ( _itCurrent != _itLast ) && ( SUCCEEDED( _hr ) ); _itCurrent++ )
  105. {
  106. _pProperty = *_itCurrent;
  107. _hr = _pProperty->get_Format( &_cpfFormat );
  108. if ( SUCCEEDED( _hr ) )
  109. {
  110. if ( _pProperty->Modified() )
  111. {
  112. if ( _pProperty->IsDefaultValued() )
  113. {
  114. _sc = rcplPropList.ScSetPropToDefault( _pProperty->Name(), _cpfFormat );
  115. _hr = HRESULT_FROM_WIN32( _sc );
  116. continue;
  117. } // if: property was set to its default state
  118. else
  119. {
  120. switch( _cpfFormat )
  121. {
  122. case CLUSPROP_FORMAT_DWORD :
  123. {
  124. DWORD dwValue = 0;
  125. _hr = HrConvertVariantToDword( _pProperty->Value(), &dwValue );
  126. if ( SUCCEEDED( _hr ) )
  127. {
  128. _sc = rcplPropList.ScAddProp( _pProperty->Name(), dwValue, (DWORD) 0 );
  129. _hr = HRESULT_FROM_WIN32( _sc );
  130. } // if:
  131. break;
  132. } // case:
  133. #if CLUSAPI_VERSION >= 0x0500
  134. case CLUSPROP_FORMAT_LONG :
  135. {
  136. long lValue = 0L;
  137. _hr = HrConvertVariantToLong( _pProperty->Value(), &lValue );
  138. if ( SUCCEEDED( _hr ) )
  139. {
  140. _sc = rcplPropList.ScAddProp( _pProperty->Name(), lValue, 0L );
  141. _hr = HRESULT_FROM_WIN32( _sc );
  142. } // if:
  143. break;
  144. } // case:
  145. #endif // CLUSAPI_VERSION >= 0x0500
  146. case CLUSPROP_FORMAT_ULARGE_INTEGER :
  147. {
  148. ULONGLONG ullValue = 0;
  149. _hr = HrConvertVariantToULONGLONG( _pProperty->Value(), &ullValue );
  150. if ( SUCCEEDED( _hr ) )
  151. {
  152. _sc = rcplPropList.ScAddProp( _pProperty->Name(), ullValue, 0 );
  153. _hr = HRESULT_FROM_WIN32( _sc );
  154. } // if:
  155. break;
  156. } // case:
  157. case CLUSPROP_FORMAT_SZ :
  158. case CLUSPROP_FORMAT_EXPAND_SZ :
  159. {
  160. _sc = rcplPropList.ScAddProp( _pProperty->Name(), _pProperty->Value().bstrVal );
  161. _hr = HRESULT_FROM_WIN32( _sc );
  162. break;
  163. } // case:
  164. case CLUSPROP_FORMAT_MULTI_SZ:
  165. {
  166. _hr = HrAddMultiSzProp( rcplPropList, _pProperty->Name(), _pProperty->Values() );
  167. break;
  168. } // case:
  169. case CLUSPROP_FORMAT_BINARY:
  170. {
  171. _hr = HrAddBinaryProp(
  172. rcplPropList,
  173. _pProperty->Name(),
  174. _pProperty->Value()
  175. );
  176. break;
  177. } // case:
  178. } // end switch
  179. _pProperty->Modified( FALSE );
  180. } // else: common property was not deleted
  181. } // if: property was modified
  182. } // if: we got the property format
  183. } // for: property in the collection
  184. return _hr;
  185. } //*** CClusterObject::HrBuildPropertyList()
  186. /////////////////////////////////////////////////////////////////////////////
  187. //++
  188. //
  189. // CClusterObject::HrConvertVariantToDword
  190. //
  191. // Description:
  192. // Convert the passed in varint to a DWORD.
  193. //
  194. // Arguments:
  195. // rvarValue [IN] - The variant value to convert.
  196. // pdwValue [OUT] - Catches the converted value.
  197. //
  198. // Return Value:
  199. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  200. //
  201. //--
  202. /////////////////////////////////////////////////////////////////////////////
  203. HRESULT CClusterObject::HrConvertVariantToDword(
  204. IN const CComVariant & rvarValue,
  205. OUT PDWORD pdwValue
  206. )
  207. {
  208. HRESULT _hr = S_OK;
  209. switch ( rvarValue.vt )
  210. {
  211. case VT_I2:
  212. {
  213. *pdwValue = (DWORD) rvarValue.iVal;
  214. break;
  215. } // case:
  216. case VT_I4:
  217. {
  218. *pdwValue = (DWORD) rvarValue.lVal;
  219. break;
  220. } // case:
  221. case VT_BOOL:
  222. {
  223. *pdwValue = (DWORD) rvarValue.boolVal;
  224. break;
  225. } // case:
  226. default:
  227. {
  228. _hr = E_INVALIDARG;
  229. break;
  230. } // default:
  231. } // switch:
  232. return _hr;
  233. } //*** CClusterObject::HrConvertVariantToDword()
  234. /////////////////////////////////////////////////////////////////////////////
  235. //++
  236. //
  237. // CClusterObject::HrConvertVariantToLong
  238. //
  239. // Description:
  240. // Convert the passed in varint to a long.
  241. //
  242. // Arguments:
  243. // rvarValue [IN] - The variant value to convert.
  244. // plValue [OUT] - Catches the converted value.
  245. //
  246. // Return Value:
  247. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  248. //
  249. //--
  250. /////////////////////////////////////////////////////////////////////////////
  251. HRESULT CClusterObject::HrConvertVariantToLong(
  252. IN const CComVariant & rvarValue,
  253. OUT long * plValue
  254. )
  255. {
  256. HRESULT _hr = S_OK;
  257. switch ( rvarValue.vt )
  258. {
  259. case VT_I2:
  260. {
  261. *plValue = (long) rvarValue.iVal;
  262. break;
  263. } // case:
  264. case VT_I4:
  265. {
  266. *plValue = rvarValue.lVal;
  267. break;
  268. } // case:
  269. case VT_BOOL:
  270. {
  271. *plValue = (long) rvarValue.boolVal;
  272. break;
  273. } // case:
  274. default:
  275. {
  276. _hr = E_INVALIDARG;
  277. break;
  278. } // default:
  279. } // switch:
  280. return _hr;
  281. } //*** CClusterObject::HrConvertVariantToLong()
  282. /////////////////////////////////////////////////////////////////////////////
  283. //++
  284. //
  285. // CClusterObject::HrConvertVariantToULONGLONG
  286. //
  287. // Description:
  288. // Convert the passed in varint to a ULONGLONG.
  289. //
  290. // Arguments:
  291. // rvarValue [IN] - The variant value to convert.
  292. // pullValue [OUT] - Catches the converted value.
  293. //
  294. // Return Value:
  295. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  296. //
  297. //--
  298. /////////////////////////////////////////////////////////////////////////////
  299. HRESULT CClusterObject::HrConvertVariantToULONGLONG(
  300. IN const CComVariant & rvarValue,
  301. OUT PULONGLONG pullValue
  302. )
  303. {
  304. HRESULT _hr = S_OK;
  305. switch ( rvarValue.vt )
  306. {
  307. case VT_I8:
  308. {
  309. *pullValue = rvarValue.ulVal;
  310. break;
  311. } // case:
  312. case VT_R8:
  313. {
  314. *pullValue = (ULONGLONG) rvarValue.dblVal;
  315. break;
  316. } // case:
  317. default:
  318. {
  319. _hr = E_INVALIDARG;
  320. break;
  321. } // default:
  322. } // switch:
  323. return _hr;
  324. } //*** CClusterObject::HrConvertVariantToULONGLONG()
  325. /////////////////////////////////////////////////////////////////////////////
  326. //++
  327. //
  328. // CClusterObject::HrAddBinaryProp
  329. //
  330. // Description:
  331. // Create a binary property from the passed in variant and add it to the
  332. // property list so it can be saved into the cluster DB.
  333. //
  334. // Arguments:
  335. // rcplPropList [IN OUT] - The property list to add the binary
  336. // property to.
  337. // pszPropName [IN] - The name of the multisz property.
  338. // rvarPropValue [IN] - The value that is the binary property.
  339. //
  340. // Return Value:
  341. // S_OK if successful, or Win32 error as HRESULT if not.
  342. //
  343. //--
  344. /////////////////////////////////////////////////////////////////////////////
  345. HRESULT CClusterObject::HrAddBinaryProp(
  346. IN OUT CClusPropList & rcplPropList,
  347. IN LPCWSTR pszPropName,
  348. IN const CComVariant & rvarPropValue
  349. )
  350. {
  351. ASSERT( rvarPropValue.vt & VT_ARRAY );
  352. HRESULT _hr = E_INVALIDARG;
  353. SAFEARRAY * _psa = rvarPropValue.parray;
  354. long _cb;
  355. PBYTE _pb;
  356. if ( _psa != NULL )
  357. {
  358. _hr = HrSafeArraySizeof( _psa, 1, &_cb );
  359. if ( SUCCEEDED( _hr ) )
  360. {
  361. _hr = ::SafeArrayAccessData( _psa, (PVOID *) &_pb );
  362. if ( SUCCEEDED( _hr ) )
  363. {
  364. DWORD _sc = rcplPropList.ScAddProp( pszPropName, _pb, _cb, NULL, 0 );
  365. _hr = HRESULT_FROM_WIN32( _sc );
  366. //
  367. // release the pointer into the SafeArray
  368. //
  369. ::SafeArrayUnaccessData( _psa );
  370. } // if:
  371. } // if:
  372. } // if:
  373. return _hr;
  374. } //*** CClusterObject::HrAddBinaryProp()
  375. /////////////////////////////////////////////////////////////////////////////
  376. //++
  377. //
  378. // CClusterObject::HrAddMultiSzProp
  379. //
  380. // Description:
  381. // Create a multisz property from the passed in property values and add it
  382. // to the property list so it can be saved in the cluster DB.
  383. //
  384. // Arguments:
  385. // rcplPropList [IN OUT] - The property list to add the multisz to.
  386. // pszPropName [IN] - The name of the multisz property.
  387. // rPropertyValues [IN] - The values that are the multisz property.
  388. //
  389. // Return Value:
  390. // S_OK if successful, or Win32 error as HRESULT if not.
  391. //
  392. //--
  393. /////////////////////////////////////////////////////////////////////////////
  394. HRESULT CClusterObject::HrAddMultiSzProp(
  395. IN OUT CClusPropList & rcplPropList,
  396. IN LPCWSTR pszPropName,
  397. IN const CComObject< CClusPropertyValues > & rPropertyValues
  398. )
  399. {
  400. HRESULT _hr = E_INVALIDARG;
  401. const CClusPropertyValues::CClusPropertyValueVector & _rPropValuesList = rPropertyValues.ValuesList();
  402. //
  403. // KB: Only going to iterate one value and its data!!
  404. //
  405. if ( !_rPropValuesList.empty() )
  406. {
  407. CClusPropertyValues::CClusPropertyValueVector::const_iterator _itPropValue = _rPropValuesList.begin();
  408. const CComObject< CClusPropertyValueData > * _pPropertyValueData = (*_itPropValue)->Data();
  409. if ( _pPropertyValueData != NULL )
  410. {
  411. LPWSTR _psz = NULL;
  412. DWORD _sc = ERROR_SUCCESS;
  413. _hr = _pPropertyValueData->HrFillMultiSzBuffer( &_psz );
  414. if ( SUCCEEDED( _hr ) )
  415. {
  416. _sc = rcplPropList.ScAddMultiSzProp( pszPropName, _psz, NULL );
  417. _hr = HRESULT_FROM_WIN32( _sc );
  418. ::LocalFree( _psz );
  419. } // if:
  420. } // if:
  421. } // if:
  422. return _hr;
  423. } //*** CClusterObject::HrAddMultiSzProp()