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.

813 lines
20 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: cpropvar.hxx
  7. //
  8. //---------------------------------------------------------------
  9. #ifndef _CPROPVAR_HXX_
  10. #define _CPROPVAR_HXX_
  11. #include "chresult.hxx"
  12. #include "../../props/h/windef.h"
  13. #include "../../props/olechar.h"
  14. #ifndef ASSERT
  15. #if DBG==1
  16. #include <assert.h>
  17. #define ASSERT(assertion) assert(assertion)
  18. #else
  19. #define ASSERT(assertion)
  20. #endif
  21. #endif
  22. class CClipData;
  23. class CBlob;
  24. #define INVALID_SUBSCRIPT 0
  25. #define DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(Type) \
  26. CPropVariant & operator =(const Type);
  27. #define DEFINE_CPROPVARIANT_ASSIGNMENT_OPERATOR(VT, Type ) \
  28. \
  29. CPropVariant & CPropVariant::operator =(const Type pType) \
  30. { \
  31. if( INVALID_SUBSCRIPT == wReserved1 ) \
  32. { \
  33. PropVariantClear(this); \
  34. Init(pType); \
  35. return (*this); \
  36. } \
  37. else \
  38. { \
  39. if( !(vt & VT_VECTOR) \
  40. || \
  41. (vt & ~VT_VECTOR) != VT_##VT ) \
  42. { \
  43. WORD wReserved1Save = wReserved1; \
  44. PropVariantClear(this); \
  45. Init( VT_##VT, wReserved1Save ); \
  46. wReserved1 = wReserved1Save; \
  47. } \
  48. \
  49. Set##VT( pType, wReserved1 - 1); \
  50. wReserved1 = 0; \
  51. return (*this); \
  52. } \
  53. }
  54. #define DECLARE_CPROPVARIANT_CONVERSION_OPERATOR(VarType) \
  55. operator VarType();
  56. #define DEFINE_CPROPVARIANT_CONVERSION_OPERATOR(VarType,CAName,SingletonName) \
  57. CPropVariant::operator VarType() \
  58. { \
  59. if( vt & VT_VECTOR ) \
  60. { \
  61. ASSERT( vt == (VT_##VarType | VT_VECTOR) \
  62. || \
  63. vt == (VT_VARIANT | VT_VECTOR) ); \
  64. ASSERT( wReserved1 > 0 ); \
  65. \
  66. if( wReserved1 > 0 \
  67. && \
  68. ##CAName.cElems > 0 \
  69. && \
  70. wReserved1 <= (##CAName.cElems) ) \
  71. { \
  72. USHORT usSubscript = wReserved1 - 1; \
  73. wReserved1 = 0; \
  74. if( (vt & ~VT_VECTOR) == VT_VARIANT ) \
  75. return( capropvar. \
  76. pElems[ usSubscript ].##SingletonName ); \
  77. else \
  78. return( ##CAName.pElems[ usSubscript ] ); \
  79. } \
  80. else \
  81. return( NULL ); \
  82. } \
  83. else \
  84. { \
  85. ASSERT( vt == VT_##VarType ); \
  86. return( ##SingletonName ); \
  87. } \
  88. }
  89. class CPropVariant : public tagPROPVARIANT
  90. {
  91. public:
  92. //
  93. // Default Constructor & Destructor
  94. //
  95. CPropVariant()
  96. {
  97. Init();
  98. }
  99. void Init()
  100. {
  101. PropVariantInit(this);
  102. wReserved1 = INVALID_SUBSCRIPT;
  103. }
  104. ~CPropVariant()
  105. {
  106. PropVariantClear(this);
  107. }
  108. CPropVariant & operator =(CPropVariant& cpropvar)
  109. {
  110. PropVariantCopy( this, &cpropvar );
  111. return( *this );
  112. }
  113. //
  114. // Simple Constructors and assignment operators, and conversion
  115. // operators.
  116. //
  117. CPropVariant(UCHAR b)
  118. {
  119. Init();
  120. *this = b;
  121. }
  122. CPropVariant & operator =(UCHAR b)
  123. {
  124. PropVariantClear(this);
  125. Init();
  126. vt = VT_UI1;
  127. bVal = b;
  128. return (*this);
  129. }
  130. CPropVariant(short i)
  131. {
  132. Init();
  133. vt = VT_I2;
  134. iVal = i;
  135. }
  136. CPropVariant & operator =(short i)
  137. {
  138. PropVariantClear(this);
  139. Init();
  140. vt = VT_I2;
  141. iVal = i;
  142. return (*this);
  143. }
  144. CPropVariant(USHORT ui)
  145. { *this = ui; }
  146. CPropVariant & operator =(USHORT ui)
  147. {
  148. PropVariantClear(this);
  149. vt = VT_UI2;
  150. uiVal = ui;
  151. wReserved1 = INVALID_SUBSCRIPT;
  152. return (*this);
  153. }
  154. CPropVariant(long l)
  155. { vt = VT_I4; lVal = l; wReserved1 = INVALID_SUBSCRIPT; }
  156. CPropVariant & operator =(long l)
  157. {
  158. PropVariantClear(this);
  159. vt = VT_I4; lVal = l; wReserved1 = INVALID_SUBSCRIPT;
  160. return (*this);
  161. }
  162. CPropVariant(ULONG ul)
  163. { vt = VT_UI4; ulVal = ul; wReserved1 = INVALID_SUBSCRIPT; }
  164. CPropVariant & operator =(ULONG ul)
  165. {
  166. PropVariantClear(this);
  167. vt = VT_UI4; ulVal = ul; wReserved1 = INVALID_SUBSCRIPT;
  168. return (*this);
  169. }
  170. CPropVariant(LARGE_INTEGER h)
  171. { vt = VT_I8; hVal = h; wReserved1 = INVALID_SUBSCRIPT; }
  172. inline CPropVariant & operator =(LARGE_INTEGER h)
  173. {
  174. PropVariantClear(this);
  175. vt = VT_I8; hVal = h; wReserved1 = INVALID_SUBSCRIPT;
  176. return (*this);
  177. }
  178. CPropVariant(ULARGE_INTEGER uh)
  179. { vt = VT_UI8; uhVal = uh; wReserved1 = INVALID_SUBSCRIPT; }
  180. CPropVariant & operator =(ULARGE_INTEGER uh)
  181. {
  182. PropVariantClear(this);
  183. vt = VT_UI8; uhVal = uh; wReserved1 = INVALID_SUBSCRIPT;
  184. return (*this);
  185. }
  186. CPropVariant(float flt)
  187. { vt = VT_R4; fltVal = flt; wReserved1 = INVALID_SUBSCRIPT; }
  188. CPropVariant & operator =(float flt)
  189. {
  190. PropVariantClear(this);
  191. vt = VT_R4; fltVal = flt; wReserved1 = INVALID_SUBSCRIPT;
  192. return (*this);
  193. }
  194. CPropVariant(double dbl)
  195. { vt = VT_R8; dblVal = dbl; wReserved1 = INVALID_SUBSCRIPT; }
  196. CPropVariant & operator =(double dbl)
  197. {
  198. PropVariantClear(this);
  199. vt = VT_R8; dblVal = dbl; wReserved1 = INVALID_SUBSCRIPT;
  200. return (*this);
  201. }
  202. CPropVariant(CY cy)
  203. { vt = VT_CY; cyVal = cy; wReserved1 = INVALID_SUBSCRIPT; }
  204. CPropVariant & operator =(CY cy)
  205. {
  206. PropVariantClear(this);
  207. vt = VT_CY; cyVal = cy; wReserved1 = INVALID_SUBSCRIPT;
  208. return (*this);
  209. }
  210. CPropVariant(FILETIME ft)
  211. { vt = VT_FILETIME; filetime = ft; wReserved1 = INVALID_SUBSCRIPT; }
  212. CPropVariant & operator =(FILETIME ft)
  213. {
  214. PropVariantClear(this);
  215. vt = VT_FILETIME; filetime = ft; wReserved1 = INVALID_SUBSCRIPT;
  216. return (*this);
  217. }
  218. void SetCLSID( const CLSID &clsid );
  219. void SetCLSID( const CLSID &clsid, unsigned pos);
  220. CPropVariant(CLSID *pclsid)
  221. {
  222. SetCLSID( *pclsid );
  223. }
  224. CPropVariant(const CLSID &clsid)
  225. {
  226. SetCLSID( clsid );
  227. }
  228. void Init(const CLSID &clsid)
  229. {
  230. SetCLSID( clsid );
  231. }
  232. DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(CLSID);
  233. public:
  234. CPropVariant(LPSTR psz);
  235. inline void Init(LPSTR psz);
  236. void SetLPSTR( char const *psz, unsigned pos);
  237. DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(LPSTR);
  238. DECLARE_CPROPVARIANT_CONVERSION_OPERATOR(LPSTR);
  239. CPropVariant(LPWSTR pwsz);
  240. inline void Init(LPWSTR pwsz);
  241. void SetLPWSTR( WCHAR const *psz, unsigned pos);
  242. DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(LPWSTR);
  243. DECLARE_CPROPVARIANT_CONVERSION_OPERATOR(LPWSTR);
  244. CPropVariant(const CLIPDATA *p)
  245. { Init(p); }
  246. void Init(const CLIPDATA *p);
  247. void Init(const CLIPDATA& clipdata)
  248. { Init(&clipdata); }
  249. void Init( const CClipData& cclipdata )
  250. { Init( (CLIPDATA*)(void*) &cclipdata ); }
  251. void SetCF( const CLIPDATA *pclipdata, unsigned pos);
  252. void SetCF( const CLIPDATA& clipdata, unsigned pos )
  253. { SetCF( &clipdata, pos ); }
  254. void SetCF( const CClipData *pcclipdata, unsigned pos )
  255. { SetCF( (CLIPDATA*)(void*) pcclipdata, pos ); }
  256. void SetCF( const CClipData& cclipdata, unsigned pos )
  257. {
  258. SetCF( (CLIPDATA*)(void*) &cclipdata, pos );
  259. }
  260. DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(CLIPDATA&);
  261. DECLARE_CPROPVARIANT_ASSIGNMENT_OPERATOR(CClipData&);
  262. CPropVariant( const BLOB *pblob )
  263. {
  264. Init(pblob);
  265. }
  266. void Init( const BLOB *pblob )
  267. {
  268. PropVariantClear( this );
  269. blob.pBlobData = (BYTE*) CoTaskMemAlloc( pblob->cbSize );
  270. if( NULL == blob.pBlobData )
  271. {
  272. assert(FALSE && "CPropVariant couldn't alloc for VT_BLOB");
  273. return;
  274. }
  275. memcpy( blob.pBlobData, pblob->pBlobData, pblob->cbSize);
  276. blob.cbSize = pblob->cbSize;
  277. vt = VT_BLOB;
  278. }
  279. CPropVariant( BLOB& blob )
  280. {
  281. Init( &blob );
  282. }
  283. CPropVariant( const CBlob *pcblob )
  284. {
  285. Init( (BLOB*)(void*) pcblob );
  286. }
  287. CPropVariant( const CBlob& cblob )
  288. {
  289. Init( (BLOB*)&cblob );
  290. }
  291. CPropVariant &operator = (const CBlob &cblob)
  292. {
  293. Init( (BLOB*)(void*)&cblob );
  294. return( *this );
  295. }
  296. CPropVariant &operator = (BLOB &blob)
  297. {
  298. Init( &blob );
  299. return( *this );
  300. }
  301. void SetBSTR( const BSTR pwsz )
  302. {
  303. bstrVal = SysAllocString( pwsz );
  304. if( NULL == bstrVal )
  305. {
  306. vt = VT_EMPTY;
  307. }
  308. else
  309. {
  310. vt = VT_BSTR;
  311. }
  312. }
  313. void SetBSTR( const BSTR pwsz, unsigned int pos );
  314. BSTR GetBSTR()
  315. {
  316. ASSERT( vt == VT_BSTR );
  317. ASSERT( !(vt & VT_VECTOR) );
  318. return( bstrVal );
  319. }
  320. BSTR GetBSTR( int nSubscript );
  321. void SetBOOL( BOOL b)
  322. {
  323. boolVal = b;
  324. vt = VT_BOOL;
  325. }
  326. BOOL GetBOOL()
  327. {
  328. ASSERT( vt == VT_BOOL );
  329. return( boolVal );
  330. }
  331. void SetERROR( SCODE sc)
  332. {
  333. scode = sc;
  334. vt = VT_ERROR;
  335. }
  336. BOOL GetERROR()
  337. {
  338. ASSERT( vt == VT_ERROR );
  339. return( scode );
  340. }
  341. void SetDATE( DATE dt)
  342. {
  343. date = dt;
  344. vt = VT_DATE;
  345. }
  346. DATE GetDATE()
  347. {
  348. ASSERT( vt == VT_DATE );
  349. return( date );
  350. }
  351. CPropVariant & operator=(LPPROPVARIANT lppropvar);
  352. DECLARE_CPROPVARIANT_CONVERSION_OPERATOR(LPPROPVARIANT);
  353. void SetLPPROPVARIANT( LPPROPVARIANT lppropvar, unsigned pos );
  354. public:
  355. inline void *operator new(size_t size);
  356. inline void operator delete(void *p);
  357. inline void *operator new(size_t size, void *p);
  358. public:
  359. CPropVariant & operator[] (int nSubscript)
  360. {
  361. wReserved1 = (WORD) nSubscript + 1;
  362. return (*this);
  363. }
  364. LPPROPVARIANT operator&()
  365. {
  366. return( this );
  367. }
  368. public:
  369. VARTYPE VarType() const
  370. {
  371. return( vt );
  372. }
  373. void Clear()
  374. {
  375. PropVariantClear( this );
  376. }
  377. ULONG Count() const
  378. {
  379. if( vt & VT_VECTOR )
  380. return caui.cElems;
  381. else
  382. return 0;
  383. }
  384. void SetVarType(VARTYPE vtNew)
  385. {
  386. PropVariantClear( this );
  387. PropVariantInit( this );
  388. vt = vtNew;
  389. }
  390. public:
  391. CPropVariant(VARENUM vartype, ULONG cElements);
  392. void Init( VARENUM v, ULONG cElements);
  393. static HRESULT Compare( PROPVARIANT* ppropvar1, PROPVARIANT *ppropvar2 );
  394. private:
  395. VOID *_AddStringToVector(
  396. unsigned pos,
  397. VOID *pv,
  398. ULONG cb);
  399. VOID *_AddScalerToVector(
  400. unsigned pos,
  401. VOID *pv,
  402. ULONG cb);
  403. };
  404. inline CPropVariant::CPropVariant(LPWSTR pwsz)
  405. {
  406. Init(pwsz);
  407. }
  408. inline void CPropVariant::Init(LPWSTR pwsz)
  409. {
  410. pwszVal = (LPWSTR) CoTaskMemAlloc( sizeof(WCHAR) * (wcslen(pwsz) + 1) );
  411. if( pwszVal == NULL )
  412. {
  413. vt = VT_EMPTY;
  414. }
  415. else
  416. {
  417. vt = VT_LPWSTR;
  418. memcpy( pwszVal, pwsz, sizeof(WCHAR) * (wcslen(pwsz) + 1) );
  419. }
  420. }
  421. inline CPropVariant::CPropVariant(LPSTR psz)
  422. {
  423. Init(psz);
  424. }
  425. inline void CPropVariant::Init(LPSTR psz)
  426. {
  427. pszVal = (LPSTR) CoTaskMemAlloc( strlen(psz) + 1 );
  428. if( NULL == pszVal )
  429. {
  430. vt = VT_EMPTY;
  431. }
  432. else
  433. {
  434. vt = VT_LPSTR;
  435. memcpy( pszVal, psz, strlen(psz) + 1 );
  436. }
  437. }
  438. inline void *
  439. CPropVariant::operator new(size_t size)
  440. {
  441. void *p = CoTaskMemAlloc(size);
  442. return(p);
  443. }
  444. inline void *
  445. CPropVariant::operator new(size_t size, void *p)
  446. {
  447. return(p);
  448. }
  449. inline void
  450. CPropVariant::operator delete(void *p)
  451. {
  452. if (p != NULL)
  453. {
  454. CoTaskMemFree(p);
  455. }
  456. }
  457. class CClipData : private CLIPDATA
  458. {
  459. public:
  460. ~CClipData()
  461. {
  462. if( NULL != pClipData)
  463. CoTaskMemFree( pClipData);
  464. }
  465. CClipData()
  466. {
  467. Init();
  468. }
  469. void Init()
  470. {
  471. cbSize = sizeof( ulClipFmt );
  472. ulClipFmt = (ULONG) -1;
  473. pClipData = NULL;
  474. }
  475. CClipData( ULONG ul, const void *p, ULONG cb )
  476. {
  477. Init(ul, p, cb);
  478. }
  479. void Init( ULONG ul, const void *p, ULONG cb )
  480. {
  481. HRESULT hr;
  482. Init();
  483. hr = Set( ul, p, cb );
  484. ASSERT( SUCCEEDED(hr) );
  485. }
  486. CClipData( LPSTR psz )
  487. {
  488. Init( (ULONG) -1, psz, strlen(psz) + 1 );
  489. }
  490. CClipData( LPWSTR pwsz )
  491. {
  492. Init( (ULONG) -1, pwsz, sizeof(WCHAR) * (wcslen(pwsz) + 1) );
  493. }
  494. CClipData( CClipData &cClipData )
  495. {
  496. HRESULT hr;
  497. hr = Set( cClipData.ulClipFmt,
  498. cClipData.pClipData,
  499. cClipData.cbSize - sizeof(ulClipFmt));
  500. ASSERT( SUCCEEDED(hr) );
  501. }
  502. CClipData& operator =(CClipData &cClipData)
  503. {
  504. HRESULT hr;
  505. hr = Set( cClipData.ulClipFmt,
  506. cClipData.pClipData,
  507. cClipData.cbSize - sizeof(ulClipFmt));
  508. ASSERT( SUCCEEDED(hr) );
  509. return( *this );
  510. }
  511. HRESULT Set( ULONG ul, const void *p, ULONG cb )
  512. {
  513. if( NULL != pClipData )
  514. {
  515. cb = sizeof( ulClipFmt );
  516. ulClipFmt = (ULONG) -1;
  517. CoTaskMemFree( pClipData );
  518. }
  519. if( NULL != p )
  520. {
  521. pClipData = (BYTE*) CoTaskMemAlloc( cb );
  522. if( NULL == pClipData )
  523. return( E_OUTOFMEMORY );
  524. memcpy( pClipData, p, cb );
  525. }
  526. cbSize = sizeof( ulClipFmt ) + cb;
  527. ulClipFmt = ul;
  528. return( S_OK );
  529. }
  530. operator CLIPDATA*()
  531. {
  532. return( this );
  533. }
  534. };
  535. class CPropSpec : public PROPSPEC
  536. {
  537. public:
  538. CPropSpec()
  539. {
  540. Init();
  541. }
  542. void Init()
  543. {
  544. ulKind = PRSPEC_PROPID;
  545. propid = 0;
  546. }
  547. ~CPropSpec()
  548. {
  549. if( PRSPEC_LPWSTR == ulKind )
  550. CoTaskMemFree( lpwstr );
  551. Init();
  552. }
  553. operator PROPSPEC*()
  554. {
  555. return( this );
  556. }
  557. PROPSPEC* operator&()
  558. {
  559. return( this );
  560. }
  561. CPropSpec( BSTR pbstr )
  562. {
  563. memset( this, 0, sizeof(PROPSPEC) );
  564. this->operator=(pbstr);
  565. }
  566. CPropSpec & operator = (BSTR posz)
  567. {
  568. this->CPropSpec::~CPropSpec();
  569. ULONG cb = ( ocslen(posz) + 1 ) * sizeof(OLECHAR);
  570. lpwstr = (BSTR) CoTaskMemAlloc( cb );
  571. if( NULL != lpwstr )
  572. {
  573. memcpy( lpwstr, posz, cb );
  574. ulKind = PRSPEC_LPWSTR;
  575. }
  576. return( *this );
  577. }
  578. CPropSpec & operator = (PROPID propidNew)
  579. {
  580. this->CPropSpec::~CPropSpec();
  581. ulKind = PRSPEC_PROPID;
  582. propid = propidNew;
  583. return( *this );
  584. }
  585. };
  586. class CBlob : public BLOB
  587. {
  588. public:
  589. ~CBlob()
  590. {
  591. if( NULL != pBlobData )
  592. CoTaskMemFree( pBlobData );
  593. }
  594. CBlob( LPSTR psz )
  595. {
  596. ULONG cb = 0;
  597. if( NULL != psz )
  598. {
  599. cb = strlen( psz ) + sizeof(CHAR);
  600. }
  601. pBlobData = (BYTE*) CoTaskMemAlloc( cb );
  602. if( NULL == pBlobData )
  603. {
  604. assert(FALSE && "Couldn't allocate for CBlob" );
  605. return;
  606. }
  607. cbSize = cb;
  608. memcpy( pBlobData, psz, cbSize );
  609. }
  610. CBlob( LPWSTR pwsz )
  611. {
  612. ULONG cb = 0;
  613. if( NULL != pwsz )
  614. {
  615. cb = wcslen( pwsz ) + sizeof(WCHAR);
  616. }
  617. pBlobData = (BYTE*) CoTaskMemAlloc( cb + sizeof(cb) );
  618. if( NULL == pBlobData )
  619. {
  620. assert(FALSE && "Couldn't allocate for CBlob" );
  621. exit(-1);
  622. }
  623. cbSize = cb;
  624. memcpy( pBlobData, pwsz, cbSize );
  625. }
  626. CBlob( ULONG cb )
  627. { Init(cb); }
  628. void Init( ULONG cb )
  629. {
  630. pBlobData = (BYTE*) CoTaskMemAlloc( cb );
  631. if( NULL == pBlobData )
  632. {
  633. assert(FALSE && "Couldn't allocate for CBlob" );
  634. exit(-1);
  635. }
  636. cbSize = cb;
  637. memset( pBlobData, 0, cb );
  638. }
  639. CBlob( int cb )
  640. {
  641. Init( (ULONG) cb );
  642. }
  643. };
  644. inline BOOL operator == ( CPropVariant &cpropvar1, CPropVariant &cpropvar2 )
  645. {
  646. return( S_OK == CPropVariant::Compare(&cpropvar1, &cpropvar2) );
  647. }
  648. inline BOOL operator == ( CPropVariant &cpropvar, PROPVARIANT &propvar )
  649. {
  650. return( S_OK == CPropVariant::Compare(&cpropvar, &propvar) );
  651. }
  652. inline BOOL operator == ( PROPVARIANT &propvar, CPropVariant &cpropvar )
  653. {
  654. return( S_OK == CPropVariant::Compare(&cpropvar, &propvar) );
  655. }
  656. inline BOOL operator == ( PROPVARIANT propvar1, PROPVARIANT propvar2)
  657. {
  658. return( S_OK == CPropVariant::Compare(&propvar1, &propvar2) );
  659. }
  660. inline BOOL operator != ( CPropVariant &cpropvar1, CPropVariant &cpropvar2 )
  661. {
  662. return( S_FALSE == CPropVariant::Compare(&cpropvar1, &cpropvar2) );
  663. }
  664. inline BOOL operator != ( CPropVariant &cpropvar, PROPVARIANT &propvar )
  665. {
  666. return( S_FALSE == CPropVariant::Compare(&cpropvar, &propvar) );
  667. }
  668. inline BOOL operator != ( PROPVARIANT &propvar, CPropVariant &cpropvar )
  669. {
  670. return( S_FALSE == CPropVariant::Compare(&cpropvar, &propvar) );
  671. }
  672. inline BOOL operator != ( PROPVARIANT &propvar1, PROPVARIANT &propvar2)
  673. {
  674. return( S_FALSE == CPropVariant::Compare(&propvar1, &propvar2) );
  675. }
  676. #endif // !_CPROPVAR_HXX_