Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

484 lines
12 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->CbLength(),
  175. _pProperty->Value()
  176. );
  177. break;
  178. } // case:
  179. } // end switch
  180. _pProperty->Modified( FALSE );
  181. } // else: common property was not deleted
  182. } // if: property was modified
  183. } // if: we got the property format
  184. } // for: property in the collection
  185. return _hr;
  186. } //*** CClusterObject::HrBuildPropertyList()
  187. /////////////////////////////////////////////////////////////////////////////
  188. //++
  189. //
  190. // CClusterObject::HrConvertVariantToDword
  191. //
  192. // Description:
  193. // Convert the passed in varint to a DWORD.
  194. //
  195. // Arguments:
  196. // rvarValue [IN] - The variant value to convert.
  197. // pdwValue [OUT] - Catches the converted value.
  198. //
  199. // Return Value:
  200. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  201. //
  202. //--
  203. /////////////////////////////////////////////////////////////////////////////
  204. HRESULT CClusterObject::HrConvertVariantToDword(
  205. IN const CComVariant & rvarValue,
  206. OUT PDWORD pdwValue
  207. )
  208. {
  209. HRESULT _hr = S_OK;
  210. switch ( rvarValue.vt )
  211. {
  212. case VT_I2:
  213. {
  214. *pdwValue = (DWORD) rvarValue.iVal;
  215. break;
  216. } // case:
  217. case VT_I4:
  218. {
  219. *pdwValue = (DWORD) rvarValue.lVal;
  220. break;
  221. } // case:
  222. case VT_BOOL:
  223. {
  224. *pdwValue = (DWORD) rvarValue.boolVal;
  225. break;
  226. } // case:
  227. default:
  228. {
  229. _hr = E_INVALIDARG;
  230. break;
  231. } // default:
  232. } // switch:
  233. return _hr;
  234. } //*** CClusterObject::HrConvertVariantToDword()
  235. /////////////////////////////////////////////////////////////////////////////
  236. //++
  237. //
  238. // CClusterObject::HrConvertVariantToLong
  239. //
  240. // Description:
  241. // Convert the passed in varint to a long.
  242. //
  243. // Arguments:
  244. // rvarValue [IN] - The variant value to convert.
  245. // plValue [OUT] - Catches the converted value.
  246. //
  247. // Return Value:
  248. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  249. //
  250. //--
  251. /////////////////////////////////////////////////////////////////////////////
  252. HRESULT CClusterObject::HrConvertVariantToLong(
  253. IN const CComVariant & rvarValue,
  254. OUT long * plValue
  255. )
  256. {
  257. HRESULT _hr = S_OK;
  258. switch ( rvarValue.vt )
  259. {
  260. case VT_I2:
  261. {
  262. *plValue = (long) rvarValue.iVal;
  263. break;
  264. } // case:
  265. case VT_I4:
  266. {
  267. *plValue = rvarValue.lVal;
  268. break;
  269. } // case:
  270. case VT_BOOL:
  271. {
  272. *plValue = (long) rvarValue.boolVal;
  273. break;
  274. } // case:
  275. default:
  276. {
  277. _hr = E_INVALIDARG;
  278. break;
  279. } // default:
  280. } // switch:
  281. return _hr;
  282. } //*** CClusterObject::HrConvertVariantToLong()
  283. /////////////////////////////////////////////////////////////////////////////
  284. //++
  285. //
  286. // CClusterObject::HrConvertVariantToULONGLONG
  287. //
  288. // Description:
  289. // Convert the passed in varint to a ULONGLONG.
  290. //
  291. // Arguments:
  292. // rvarValue [IN] - The variant value to convert.
  293. // pullValue [OUT] - Catches the converted value.
  294. //
  295. // Return Value:
  296. // S_OK if successful, or E_INVALIDARG if the value cannot be converted.
  297. //
  298. //--
  299. /////////////////////////////////////////////////////////////////////////////
  300. HRESULT CClusterObject::HrConvertVariantToULONGLONG(
  301. IN const CComVariant & rvarValue,
  302. OUT PULONGLONG pullValue
  303. )
  304. {
  305. HRESULT _hr = S_OK;
  306. switch ( rvarValue.vt )
  307. {
  308. case VT_I8:
  309. {
  310. *pullValue = rvarValue.ulVal;
  311. break;
  312. } // case:
  313. case VT_R8:
  314. {
  315. *pullValue = (ULONGLONG) rvarValue.dblVal;
  316. break;
  317. } // case:
  318. default:
  319. {
  320. _hr = E_INVALIDARG;
  321. break;
  322. } // default:
  323. } // switch:
  324. return _hr;
  325. } //*** CClusterObject::HrConvertVariantToULONGLONG()
  326. /////////////////////////////////////////////////////////////////////////////
  327. //++
  328. //
  329. // CClusterObject::HrAddBinaryProp
  330. //
  331. // Description:
  332. // Create a binary property from the passed in variant and add it to the
  333. // property list so it can be saved into the cluster DB.
  334. //
  335. // Arguments:
  336. // rcplPropList [IN OUT] - The property list to add the binary
  337. // property to.
  338. // pszPropName [IN] - The name of the multisz property.
  339. // cbLength [IN] - The lenght of the binary property data.
  340. // rvarPropValue [IN] - The value that is the binary property.
  341. //
  342. // Return Value:
  343. // S_OK if successful, or Win32 error as HRESULT if not.
  344. //
  345. //--
  346. /////////////////////////////////////////////////////////////////////////////
  347. HRESULT CClusterObject::HrAddBinaryProp(
  348. IN OUT CClusPropList & rcplPropList,
  349. IN LPCWSTR pszPropName,
  350. IN DWORD cbLength,
  351. IN const CComVariant & rvarPropValue
  352. )
  353. {
  354. ASSERT( rvarPropValue.vt & VT_ARRAY );
  355. HRESULT _hr = E_INVALIDARG;
  356. SAFEARRAY * _psa = rvarPropValue.parray;
  357. if ( _psa != NULL )
  358. {
  359. PBYTE _pb;
  360. _hr = ::SafeArrayAccessData( _psa, (PVOID *) &_pb );
  361. if ( SUCCEEDED( _hr ) )
  362. {
  363. DWORD _sc = rcplPropList.ScAddProp( pszPropName, _pb, cbLength, NULL, 0 );
  364. _hr = HRESULT_FROM_WIN32( _sc );
  365. //
  366. // release the pointer into the SafeArray
  367. //
  368. ::SafeArrayUnaccessData( _psa );
  369. } // if:
  370. } // if:
  371. return _hr;
  372. } //*** CClusterObject::HrAddBinaryProp()
  373. /////////////////////////////////////////////////////////////////////////////
  374. //++
  375. //
  376. // CClusterObject::HrAddMultiSzProp
  377. //
  378. // Description:
  379. // Create a multisz property from the passed in property values and add it
  380. // to the property list so it can be saved in the cluster DB.
  381. //
  382. // Arguments:
  383. // rcplPropList [IN OUT] - The property list to add the multisz to.
  384. // pszPropName [IN] - The name of the multisz property.
  385. // rPropertyValues [IN] - The values that are the multisz property.
  386. //
  387. // Return Value:
  388. // S_OK if successful, or Win32 error as HRESULT if not.
  389. //
  390. //--
  391. /////////////////////////////////////////////////////////////////////////////
  392. HRESULT CClusterObject::HrAddMultiSzProp(
  393. IN OUT CClusPropList & rcplPropList,
  394. IN LPCWSTR pszPropName,
  395. IN const CComObject< CClusPropertyValues > & rPropertyValues
  396. )
  397. {
  398. HRESULT _hr = E_INVALIDARG;
  399. const CClusPropertyValues::CClusPropertyValueVector & _rPropValuesList = rPropertyValues.ValuesList();
  400. //
  401. // KB: Only going to iterate one value and its data!!
  402. //
  403. if ( !_rPropValuesList.empty() )
  404. {
  405. CClusPropertyValues::CClusPropertyValueVector::const_iterator _itPropValue = _rPropValuesList.begin();
  406. const CComObject< CClusPropertyValueData > * _pPropertyValueData = (*_itPropValue)->Data();
  407. if ( _pPropertyValueData != NULL )
  408. {
  409. LPWSTR _psz = NULL;
  410. DWORD _sc = ERROR_SUCCESS;
  411. _hr = _pPropertyValueData->HrFillMultiSzBuffer( &_psz );
  412. if ( SUCCEEDED( _hr ) )
  413. {
  414. _sc = rcplPropList.ScAddMultiSzProp( pszPropName, _psz, NULL );
  415. _hr = HRESULT_FROM_WIN32( _sc );
  416. ::LocalFree( _psz );
  417. } // if:
  418. } // if:
  419. } // if:
  420. return _hr;
  421. } //*** CClusterObject::HrAddMultiSzProp()