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.

1307 lines
27 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. CPROPSET.CPP
  5. Abstract:
  6. Implements the CProp and CPropSet classes.
  7. History:
  8. a-davj 04-Mar-97 Created.
  9. --*/
  10. #include "precomp.h"
  11. #include "stdafx.h"
  12. #include <wbemidl.h>
  13. #include "cpropset.h"
  14. //***************************************************************************
  15. //
  16. //
  17. // DESCRIPTION:
  18. //
  19. //
  20. // PARAMETERS:
  21. //
  22. //
  23. // RETURN VALUE:
  24. //
  25. //***************************************************************************
  26. CProp::CProp()
  27. {
  28. m_dwPropID = 0;
  29. m_dwSize = 0;
  30. m_dwType = VT_EMPTY;
  31. m_pValue = NULL; // must init to NULL
  32. }
  33. //***************************************************************************
  34. //
  35. //
  36. // DESCRIPTION:
  37. //
  38. //
  39. // PARAMETERS:
  40. //
  41. //
  42. // RETURN VALUE:
  43. //
  44. //***************************************************************************
  45. CProp::~CProp()
  46. {
  47. FreeValue();
  48. }
  49. //***************************************************************************
  50. //
  51. //
  52. // DESCRIPTION:
  53. //
  54. //
  55. // PARAMETERS:
  56. //
  57. //
  58. // RETURN VALUE:
  59. //
  60. //***************************************************************************
  61. BOOL CProp::Set(DWORD dwID, const LPVOID pValue, DWORD dwType, DWORD dwSize)
  62. {
  63. if (m_pValue != NULL)
  64. FreeValue();
  65. m_dwPropID = dwID;
  66. m_dwSize = dwSize;
  67. m_dwType = dwType;
  68. m_pValue = NULL; // set later on if there is data
  69. if(pValue == NULL || m_dwType == 0)
  70. return TRUE;
  71. if (NULL == AllocValue(dwSize))
  72. {
  73. TRACE0("CProp::AllocValue failed");
  74. return FALSE;
  75. }
  76. memcpy(m_pValue, pValue, dwSize);
  77. return TRUE;
  78. }
  79. //***************************************************************************
  80. //
  81. //
  82. // DESCRIPTION:
  83. //
  84. //
  85. // PARAMETERS:
  86. //
  87. //
  88. // RETURN VALUE:
  89. //
  90. //***************************************************************************
  91. LPVOID CProp::Get()
  92. { return m_pValue; }
  93. //***************************************************************************
  94. //
  95. //
  96. // DESCRIPTION:
  97. //
  98. //
  99. // PARAMETERS:
  100. //
  101. //
  102. // RETURN VALUE:
  103. //
  104. //***************************************************************************
  105. DWORD CProp::GetType()
  106. { return m_dwType; }
  107. //***************************************************************************
  108. //
  109. //
  110. // DESCRIPTION:
  111. //
  112. //
  113. // PARAMETERS:
  114. //
  115. //
  116. // RETURN VALUE:
  117. //
  118. //***************************************************************************
  119. DWORD CProp::GetID()
  120. { return m_dwPropID; }
  121. //***************************************************************************
  122. //
  123. //
  124. // DESCRIPTION:
  125. //
  126. //
  127. // PARAMETERS:
  128. //
  129. //
  130. // RETURN VALUE:
  131. //
  132. //***************************************************************************
  133. BOOL CProp::WriteToStream(IStream* pIStream)
  134. {
  135. DWORD cb;
  136. // write the type
  137. pIStream->Write((LPVOID)&m_dwType, sizeof(m_dwType), &cb);
  138. if (cb != sizeof(m_dwType))
  139. return FALSE; //todo
  140. // Write the value
  141. if(m_dwSize > 0)
  142. pIStream->Write(m_pValue, m_dwSize, &cb);
  143. if (cb != m_dwSize)
  144. return FALSE ; //todo
  145. // make sure it ends up on a 32 bit boundry
  146. int iLeftover = m_dwSize % 4;
  147. DWORD dwTemp = 0;
  148. if(iLeftover)
  149. pIStream->Write((LPVOID)&dwTemp, iLeftover, &cb);
  150. return TRUE;
  151. }
  152. //***************************************************************************
  153. //
  154. //
  155. // DESCRIPTION:
  156. //
  157. //
  158. // PARAMETERS:
  159. //
  160. //
  161. // RETURN VALUE:
  162. //
  163. //***************************************************************************
  164. BOOL CProp::ReadFromStream(IStream* pIStream, DWORD dwSize)
  165. {
  166. DWORD cb;
  167. // All properties are made up of a type/value pair.
  168. // The obvious first thing to do is to get the type...
  169. pIStream->Read((LPVOID)&m_dwType, sizeof(m_dwType), &cb);
  170. if (cb != sizeof(m_dwType))
  171. return FALSE;
  172. if (m_pValue != NULL)
  173. FreeValue();
  174. m_dwSize = dwSize;
  175. m_pValue = NULL;
  176. if(dwSize > 0) {
  177. if (NULL == AllocValue(dwSize))
  178. {
  179. TRACE0("CProp::AllocValue failed");
  180. return FALSE;
  181. }
  182. pIStream->Read((LPVOID)m_pValue, dwSize, &cb); //?? does size need to be passed?
  183. if (cb != dwSize)
  184. return FALSE;
  185. }
  186. // Done!
  187. return TRUE;
  188. }
  189. //***************************************************************************
  190. //
  191. //
  192. // DESCRIPTION:
  193. //
  194. //
  195. // PARAMETERS:
  196. //
  197. //
  198. // RETURN VALUE:
  199. //
  200. //***************************************************************************
  201. LPVOID CProp::AllocValue(ULONG cb)
  202. {
  203. return m_pValue = malloc((int)cb);
  204. }
  205. //***************************************************************************
  206. //
  207. //
  208. // DESCRIPTION:
  209. //
  210. //
  211. // PARAMETERS:
  212. //
  213. //
  214. // RETURN VALUE:
  215. //
  216. //***************************************************************************
  217. void CProp::FreeValue()
  218. {
  219. if (m_pValue != NULL)
  220. {
  221. free(m_pValue);
  222. m_pValue = NULL;
  223. }
  224. }
  225. //***************************************************************************
  226. //
  227. //
  228. // DESCRIPTION:
  229. //
  230. //
  231. // PARAMETERS:
  232. //
  233. //
  234. // RETURN VALUE:
  235. //
  236. //***************************************************************************
  237. CPropSection::CPropSection()
  238. {
  239. m_FormatID = GUID_NULL;
  240. m_SH.cbSection = 0;
  241. m_SH.cProperties = 0;
  242. }
  243. //***************************************************************************
  244. //
  245. //
  246. // DESCRIPTION:
  247. //
  248. //
  249. // PARAMETERS:
  250. //
  251. //
  252. // RETURN VALUE:
  253. //
  254. //***************************************************************************
  255. CPropSection::CPropSection( CLSID FormatID)
  256. {
  257. m_FormatID = FormatID;
  258. m_SH.cbSection = 0;
  259. m_SH.cProperties = 0;
  260. }
  261. //***************************************************************************
  262. //
  263. //
  264. // DESCRIPTION:
  265. //
  266. //
  267. // PARAMETERS:
  268. //
  269. //
  270. // RETURN VALUE:
  271. //
  272. //***************************************************************************
  273. CPropSection::~CPropSection()
  274. {
  275. RemoveAll();
  276. return;
  277. }
  278. //***************************************************************************
  279. //
  280. //
  281. // DESCRIPTION:
  282. //
  283. //
  284. // PARAMETERS:
  285. //
  286. //
  287. // RETURN VALUE:
  288. //
  289. //***************************************************************************
  290. void CPropSection::SetFormatID(CLSID FormatID)
  291. { m_FormatID = FormatID; }
  292. //***************************************************************************
  293. //
  294. //
  295. // DESCRIPTION:
  296. //
  297. //
  298. // PARAMETERS:
  299. //
  300. //
  301. // RETURN VALUE:
  302. //
  303. //***************************************************************************
  304. void CPropSection::RemoveAll()
  305. {
  306. POSITION pos = m_PropList.GetHeadPosition();
  307. while (pos != NULL)
  308. delete (CProp*)m_PropList.GetNext(pos);
  309. m_PropList.RemoveAll();
  310. m_SH.cProperties = 0;
  311. }
  312. //***************************************************************************
  313. //
  314. //
  315. // DESCRIPTION:
  316. //
  317. //
  318. // PARAMETERS:
  319. //
  320. //
  321. // RETURN VALUE:
  322. //
  323. //***************************************************************************
  324. CProp* CPropSection::GetProperty(DWORD dwPropID)
  325. {
  326. POSITION pos = m_PropList.GetHeadPosition();
  327. CProp* pProp;
  328. while (pos != NULL)
  329. {
  330. pProp= (CProp*)m_PropList.GetNext(pos);
  331. if (pProp->m_dwPropID == dwPropID)
  332. return pProp;
  333. }
  334. return NULL;
  335. }
  336. //***************************************************************************
  337. //
  338. //
  339. // DESCRIPTION:
  340. //
  341. //
  342. // PARAMETERS:
  343. //
  344. //
  345. // RETURN VALUE:
  346. //
  347. //***************************************************************************
  348. void CPropSection::AddProperty(CProp* pProp)
  349. {
  350. m_PropList.AddTail(pProp);
  351. m_SH.cProperties++;
  352. }
  353. //***************************************************************************
  354. //
  355. //
  356. // DESCRIPTION:
  357. //
  358. //
  359. // PARAMETERS:
  360. //
  361. //
  362. // RETURN VALUE:
  363. //
  364. //***************************************************************************
  365. DWORD CPropSection::GetSize()
  366. { return m_SH.cbSection; }
  367. //***************************************************************************
  368. //
  369. //
  370. // DESCRIPTION:
  371. //
  372. //
  373. // PARAMETERS:
  374. //
  375. //
  376. // RETURN VALUE:
  377. //
  378. //***************************************************************************
  379. DWORD CPropSection::GetCount()
  380. { return m_PropList.GetCount(); }
  381. //***************************************************************************
  382. //
  383. //
  384. // DESCRIPTION:
  385. //
  386. //
  387. // PARAMETERS:
  388. //
  389. //
  390. // RETURN VALUE:
  391. //
  392. //***************************************************************************
  393. CObList* CPropSection::GetList()
  394. { return &m_PropList; }
  395. //***************************************************************************
  396. //
  397. //
  398. // DESCRIPTION:
  399. //
  400. //
  401. // PARAMETERS:
  402. //
  403. //
  404. // RETURN VALUE:
  405. //
  406. //***************************************************************************
  407. BOOL CPropSection::WriteToStream(IStream* pIStream)
  408. {
  409. // Create a dummy property entry for the name dictionary (ID == 0).
  410. ULONG cb;
  411. ULARGE_INTEGER ulSeekOld;
  412. ULARGE_INTEGER ulSeek;
  413. LPSTREAM pIStrPIDO;
  414. PROPERTYIDOFFSET pido;
  415. LARGE_INTEGER li;
  416. // The Section header contains the number of bytes in the
  417. // section. Thus we need to go back to where we should
  418. // write the count of bytes
  419. // after we write all the property sets..
  420. // We accomplish this by saving the seek pointer to where
  421. // the size should be written in ulSeekOld
  422. m_SH.cbSection = 0;
  423. m_SH.cProperties = m_PropList.GetCount();
  424. LISet32(li, 0);
  425. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeekOld);
  426. pIStream->Write((LPVOID)&m_SH, sizeof(m_SH), &cb);
  427. if (sizeof(m_SH) != cb)
  428. {
  429. TRACE0("Write of section header failed (1).\n");
  430. return FALSE;
  431. }
  432. if (m_PropList.IsEmpty())
  433. {
  434. TRACE0("Warning: Wrote empty property section.\n");
  435. return TRUE;
  436. }
  437. // After the section header is the list of property ID/Offset pairs
  438. // Since there is an ID/Offset pair for each property and we
  439. // need to write the ID/Offset pair as we write each property
  440. // we clone the stream and use the clone to access the
  441. // table of ID/offset pairs (PIDO)...
  442. //
  443. pIStream->Clone(&pIStrPIDO);
  444. // Now seek pIStream past the PIDO list
  445. //
  446. LISet32(li, m_SH.cProperties * sizeof(PROPERTYIDOFFSET));
  447. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);
  448. // Now write each section to pIStream.
  449. CProp* pProp = NULL;
  450. POSITION pos = m_PropList.GetHeadPosition();
  451. while (pos != NULL)
  452. {
  453. // Get next element (note cast)
  454. pProp = (CProp*)m_PropList.GetNext(pos);
  455. // Write it
  456. if (!pProp->WriteToStream(pIStream))
  457. {
  458. pIStrPIDO->Release();
  459. return FALSE;
  460. }
  461. // Using our cloned stream write the Format ID / Offset pair
  462. // The offset to this property is the current seek pointer
  463. // minus the pointer to the beginning of the section
  464. pido.dwOffset = ulSeek.LowPart - ulSeekOld.LowPart;
  465. pido.propertyID = pProp->m_dwPropID;
  466. pIStrPIDO->Write((LPVOID)&pido, sizeof(pido), &cb);
  467. if (sizeof(pido) != cb)
  468. {
  469. TRACE0("Write of 'pido' failed\n");
  470. pIStrPIDO->Release();
  471. return FALSE;
  472. }
  473. // Get the seek offset after the write
  474. LISet32(li, 0);
  475. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);
  476. }
  477. pIStrPIDO->Release();
  478. // Now go back to ulSeekOld and write the section header.
  479. // Size of section is current seek point minus old seek point
  480. //
  481. m_SH.cbSection = ulSeek.LowPart - ulSeekOld.LowPart;
  482. // Seek to beginning of this section and write the section header.
  483. LISet32(li, ulSeekOld.LowPart);
  484. pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  485. pIStream->Write((LPVOID)&m_SH, sizeof(m_SH), &cb);
  486. if (sizeof(m_SH) != cb)
  487. {
  488. TRACE0("Write of section header failed (2).\n");
  489. return FALSE;
  490. }
  491. // Set pointer to where it was after last write
  492. LISet32(li, ulSeek.LowPart);
  493. pIStream->Seek(li, STREAM_SEEK_SET, NULL);
  494. return TRUE;
  495. }
  496. //***************************************************************************
  497. //
  498. //
  499. // DESCRIPTION:
  500. //
  501. //
  502. // PARAMETERS:
  503. //
  504. //
  505. // RETURN VALUE:
  506. //
  507. //***************************************************************************
  508. BOOL CPropSection::ReadFromStream(IStream* pIStream,
  509. LARGE_INTEGER liPropSet)
  510. {
  511. ULONG cb;
  512. LPSTREAM pIStrPIDO;
  513. ULARGE_INTEGER ulSectionStart;
  514. LARGE_INTEGER li;
  515. CProp* pProp;
  516. if (m_SH.cProperties || !m_PropList.IsEmpty())
  517. RemoveAll();
  518. // pIStream is pointing to the beginning of the section we
  519. // are to read. First there is a DWORD that is the count
  520. // of bytes in this section, then there is a count
  521. // of properties, followed by a list of propertyID/offset pairs,
  522. // followed by type/value pairs.
  523. //
  524. LISet32(li, 0);
  525. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSectionStart);
  526. pIStream->Read((LPVOID)&m_SH, sizeof(m_SH), &cb);
  527. if (cb != sizeof(m_SH))
  528. return FALSE;
  529. // Now we're pointing at the first of the PropID/Offset pairs
  530. // (PIDOs). To get to each property we use a cloned stream
  531. // to stay back and point at the PIDOs (pIStrPIDO). We seek
  532. // pIStream to each of the Type/Value pairs, creating CProperites
  533. // and so forth as we go...
  534. //
  535. pIStream->Clone(&pIStrPIDO);
  536. // Read the propid /offset structures first
  537. DWORD dwCnt;
  538. PROPERTYIDOFFSET * pArray = new PROPERTYIDOFFSET[m_SH.cProperties];
  539. if(pArray == NULL)
  540. return FALSE; //TODO
  541. for(dwCnt = 0; dwCnt < m_SH.cProperties; dwCnt++) {
  542. pIStrPIDO->Read((LPVOID)&pArray[dwCnt], sizeof(PROPERTYIDOFFSET), &cb);
  543. if (cb != sizeof(PROPERTYIDOFFSET))
  544. {
  545. pIStrPIDO->Release();
  546. delete pArray;
  547. return FALSE;
  548. }
  549. }
  550. pIStrPIDO->Release();
  551. // Now read in the actual properties
  552. for(dwCnt = 0; dwCnt < m_SH.cProperties; dwCnt++)
  553. {
  554. DWORD dwSize;
  555. // Do a seek from the beginning of the property set.
  556. LISet32(li, ulSectionStart.LowPart + pArray[dwCnt].dwOffset);
  557. pIStream->Seek(liPropSet, STREAM_SEEK_SET, NULL);
  558. pIStream->Seek(li, STREAM_SEEK_CUR, NULL);
  559. // Now pIStream is at the type/value pair
  560. pProp = new CProp(); //todo, error checking???
  561. pProp->Set(pArray[dwCnt].propertyID, NULL, 0,0);
  562. if(dwCnt < m_SH.cProperties-1)
  563. dwSize = pArray[dwCnt+1].dwOffset - pArray[dwCnt].dwOffset -
  564. sizeof(DWORD);
  565. else
  566. dwSize = /*ulSectionStart.LowPart +*/ m_SH.cbSection -
  567. pArray[dwCnt].dwOffset - sizeof(DWORD);
  568. ASSERT(dwSize < 1000);
  569. pProp->ReadFromStream(pIStream,dwSize);
  570. m_PropList.AddTail(pProp);
  571. }
  572. delete pArray;
  573. return TRUE;
  574. }
  575. //***************************************************************************
  576. //
  577. //
  578. // DESCRIPTION:
  579. //
  580. //
  581. // PARAMETERS:
  582. //
  583. //
  584. // RETURN VALUE:
  585. //
  586. //***************************************************************************
  587. BOOL CPropSection::SetSectionName(LPCTSTR pszName)
  588. {
  589. m_strSectionName = pszName;
  590. return TRUE;
  591. }
  592. //***************************************************************************
  593. //
  594. //
  595. // DESCRIPTION:
  596. //
  597. //
  598. // PARAMETERS:
  599. //
  600. //
  601. // RETURN VALUE:
  602. //
  603. //***************************************************************************
  604. LPCTSTR CPropSection::GetSectionName()
  605. {
  606. return (LPCTSTR)m_strSectionName;
  607. }
  608. //***************************************************************************
  609. //
  610. //
  611. // DESCRIPTION:
  612. //
  613. //
  614. // PARAMETERS:
  615. //
  616. //
  617. // RETURN VALUE:
  618. //
  619. //***************************************************************************
  620. CPropSet::CPropSet()
  621. {
  622. m_PH.wByteOrder = 0xFFFE;
  623. m_PH.wFormat = 0;
  624. m_PH.dwOSVer = (DWORD)MAKELONG(LOWORD(GetVersion()), 2);
  625. m_PH.clsID = GUID_NULL;
  626. m_PH.cSections = 0;
  627. }
  628. //***************************************************************************
  629. //
  630. //
  631. // DESCRIPTION:
  632. //
  633. //
  634. // PARAMETERS:
  635. //
  636. //
  637. // RETURN VALUE:
  638. //
  639. //***************************************************************************
  640. CPropSet::~CPropSet()
  641. { RemoveAll(); }
  642. //***************************************************************************
  643. //
  644. //
  645. // DESCRIPTION:
  646. //
  647. //
  648. // PARAMETERS:
  649. //
  650. //
  651. // RETURN VALUE:
  652. //
  653. //***************************************************************************
  654. void CPropSet::RemoveAll()
  655. {
  656. POSITION pos = m_SectionList.GetHeadPosition();
  657. while (pos != NULL)
  658. {
  659. delete (CPropSection*)m_SectionList.GetNext(pos);
  660. }
  661. m_SectionList.RemoveAll();
  662. m_PH.cSections = 0;
  663. }
  664. //***************************************************************************
  665. //
  666. //
  667. // DESCRIPTION:
  668. //
  669. //
  670. // PARAMETERS:
  671. //
  672. //
  673. // RETURN VALUE:
  674. //
  675. //***************************************************************************
  676. CPropSection* CPropSet::GetSection(CLSID FormatID)
  677. {
  678. POSITION pos = m_SectionList.GetHeadPosition();
  679. CPropSection* pSect;
  680. while (pos != NULL)
  681. {
  682. pSect = (CPropSection*)m_SectionList.GetNext(pos);
  683. if (IsEqualCLSID(pSect->m_FormatID, FormatID))
  684. return pSect;
  685. }
  686. return NULL;
  687. }
  688. //***************************************************************************
  689. //
  690. //
  691. // DESCRIPTION:
  692. //
  693. //
  694. // PARAMETERS:
  695. //
  696. //
  697. // RETURN VALUE:
  698. //
  699. //***************************************************************************
  700. CPropSection* CPropSet::AddSection(CLSID FormatID)
  701. {
  702. CPropSection* pSect = GetSection(FormatID);
  703. if (pSect)
  704. return pSect;
  705. pSect = new CPropSection(FormatID);
  706. if (pSect)
  707. AddSection(pSect);
  708. return pSect;
  709. }
  710. //***************************************************************************
  711. //
  712. //
  713. // DESCRIPTION:
  714. //
  715. //
  716. // PARAMETERS:
  717. //
  718. //
  719. // RETURN VALUE:
  720. //
  721. //***************************************************************************
  722. void CPropSet::AddSection(CPropSection* pSect)
  723. {
  724. m_SectionList.AddTail(pSect);
  725. m_PH.cSections++;
  726. }
  727. //***************************************************************************
  728. //
  729. //
  730. // DESCRIPTION:
  731. //
  732. //
  733. // PARAMETERS:
  734. //
  735. //
  736. // RETURN VALUE:
  737. //
  738. //***************************************************************************
  739. CProp* CPropSet::GetProperty(CLSID FormatID, DWORD dwPropID)
  740. {
  741. CPropSection* pSect = GetSection(FormatID);
  742. if (pSect)
  743. return pSect->GetProperty(dwPropID);
  744. else
  745. return NULL;
  746. }
  747. //***************************************************************************
  748. //
  749. //
  750. // DESCRIPTION:
  751. //
  752. //
  753. // PARAMETERS:
  754. //
  755. //
  756. // RETURN VALUE:
  757. //
  758. //***************************************************************************
  759. void CPropSet::AddProperty(CLSID FormatID, CProp* pProp)
  760. {
  761. CPropSection* pSect = GetSection(FormatID);
  762. if(pSect == NULL)
  763. pSect = AddSection(FormatID);
  764. if (pSect)
  765. pSect->AddProperty(pProp);
  766. }
  767. //***************************************************************************
  768. //
  769. //
  770. // DESCRIPTION:
  771. //
  772. //
  773. // PARAMETERS:
  774. //
  775. //
  776. // RETURN VALUE:
  777. //
  778. //***************************************************************************
  779. WORD CPropSet::GetByteOrder()
  780. { return m_PH.wByteOrder; }
  781. //***************************************************************************
  782. //
  783. //
  784. // DESCRIPTION:
  785. //
  786. //
  787. // PARAMETERS:
  788. //
  789. //
  790. // RETURN VALUE:
  791. //
  792. //***************************************************************************
  793. WORD CPropSet::GetFormatVersion()
  794. { return m_PH.wFormat; }
  795. //***************************************************************************
  796. //
  797. //
  798. // DESCRIPTION:
  799. //
  800. //
  801. // PARAMETERS:
  802. //
  803. //
  804. // RETURN VALUE:
  805. //
  806. //***************************************************************************
  807. void CPropSet::SetFormatVersion(WORD wFmtVersion)
  808. { m_PH.wFormat = wFmtVersion; }
  809. //***************************************************************************
  810. //
  811. //
  812. // DESCRIPTION:
  813. //
  814. //
  815. // PARAMETERS:
  816. //
  817. //
  818. // RETURN VALUE:
  819. //
  820. //***************************************************************************
  821. DWORD CPropSet::GetOSVersion()
  822. { return m_PH.dwOSVer; }
  823. //***************************************************************************
  824. //
  825. //
  826. // DESCRIPTION:
  827. //
  828. //
  829. // PARAMETERS:
  830. //
  831. //
  832. // RETURN VALUE:
  833. //
  834. //***************************************************************************
  835. void CPropSet::SetOSVersion(DWORD dwOSVer)
  836. { m_PH.dwOSVer = dwOSVer; }
  837. //***************************************************************************
  838. //
  839. //
  840. // DESCRIPTION:
  841. //
  842. //
  843. // PARAMETERS:
  844. //
  845. //
  846. // RETURN VALUE:
  847. //
  848. //***************************************************************************
  849. CLSID CPropSet::GetClassID()
  850. { return m_PH.clsID; }
  851. //***************************************************************************
  852. //
  853. //
  854. // DESCRIPTION:
  855. //
  856. //
  857. // PARAMETERS:
  858. //
  859. //
  860. // RETURN VALUE:
  861. //
  862. //***************************************************************************
  863. void CPropSet::SetClassID(CLSID clsID)
  864. { m_PH.clsID = clsID; }
  865. //***************************************************************************
  866. //
  867. //
  868. // DESCRIPTION:
  869. //
  870. //
  871. // PARAMETERS:
  872. //
  873. //
  874. // RETURN VALUE:
  875. //
  876. //***************************************************************************
  877. DWORD CPropSet::GetCount()
  878. { return m_SectionList.GetCount(); }
  879. //***************************************************************************
  880. //
  881. //
  882. // DESCRIPTION:
  883. //
  884. //
  885. // PARAMETERS:
  886. //
  887. //
  888. // RETURN VALUE:
  889. //
  890. //***************************************************************************
  891. CObList* CPropSet::GetList()
  892. { return &m_SectionList; }
  893. //***************************************************************************
  894. //
  895. //
  896. // DESCRIPTION:
  897. //
  898. //
  899. // PARAMETERS:
  900. //
  901. //
  902. // RETURN VALUE:
  903. //
  904. //***************************************************************************
  905. BOOL CPropSet::WriteToStream(IStream* pIStream)
  906. {
  907. LPSTREAM pIStrFIDO;
  908. FORMATIDOFFSET fido;
  909. ULONG cb;
  910. ULARGE_INTEGER ulSeek;
  911. LARGE_INTEGER li;
  912. LISet32(li, 0);
  913. pIStream->Seek(li,STREAM_SEEK_SET,NULL);
  914. // Write the Property List Header
  915. m_PH.cSections = m_SectionList.GetCount();
  916. pIStream->Write((LPVOID)&m_PH, sizeof(m_PH), &cb);
  917. if (sizeof(m_PH) != cb)
  918. {
  919. TRACE0("Write of Property Set Header failed.\n");
  920. return FALSE;
  921. }
  922. if (m_SectionList.IsEmpty())
  923. {
  924. TRACE0("Warning: Wrote empty property set.\n");
  925. return TRUE;
  926. }
  927. // After the header is the list of Format ID/Offset pairs
  928. // Since there is an ID/Offset pair for each section and we
  929. // need to write the ID/Offset pair as we write each section
  930. // we clone the stream and use the clone to access the
  931. // table of ID/offset pairs (FIDO)...
  932. //
  933. pIStream->Clone(&pIStrFIDO);
  934. // Now seek pIStream past the FIDO list
  935. //
  936. LISet32(li, m_PH.cSections * sizeof(FORMATIDOFFSET));
  937. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);
  938. // Write each section.
  939. CPropSection* pSect = NULL;
  940. POSITION pos = m_SectionList.GetHeadPosition();
  941. while (pos != NULL)
  942. {
  943. // Get next element (note cast)
  944. pSect = (CPropSection*)m_SectionList.GetNext(pos);
  945. // Write it
  946. if (!pSect->WriteToStream(pIStream))
  947. {
  948. pIStrFIDO->Release();
  949. return FALSE;
  950. }
  951. // Using our cloned stream write the Format ID / Offset pair
  952. fido.formatID = pSect->m_FormatID;
  953. fido.dwOffset = ulSeek.LowPart;
  954. pIStrFIDO->Write((LPVOID)&fido, sizeof(fido), &cb);
  955. if (sizeof(fido) != cb)
  956. {
  957. TRACE0("Write of 'fido' failed.\n");
  958. pIStrFIDO->Release();
  959. return FALSE;
  960. }
  961. // Get the seek offset (for pIStream) after the write
  962. LISet32(li, 0);
  963. pIStream->Seek(li, STREAM_SEEK_CUR, &ulSeek);
  964. }
  965. pIStrFIDO->Release();
  966. return TRUE;
  967. }
  968. //***************************************************************************
  969. //
  970. //
  971. // DESCRIPTION:
  972. //
  973. //
  974. // PARAMETERS:
  975. //
  976. //
  977. // RETURN VALUE:
  978. //
  979. //***************************************************************************
  980. BOOL CPropSet::ReadFromStream(IStream* pIStream)
  981. {
  982. ULONG cb;
  983. FORMATIDOFFSET fido;
  984. ULONG cSections;
  985. LPSTREAM pIStrFIDO;
  986. CPropSection* pSect;
  987. LARGE_INTEGER li;
  988. LARGE_INTEGER liPropSet;
  989. LISet32(li, 0);
  990. pIStream->Seek(li,STREAM_SEEK_SET,NULL);
  991. // Save the stream position at which the property set starts.
  992. LARGE_INTEGER liZero = {0,0};
  993. pIStream->Seek(liZero, STREAM_SEEK_CUR, (ULARGE_INTEGER*)&liPropSet);
  994. if (m_PH.cSections || !m_SectionList.IsEmpty())
  995. RemoveAll();
  996. // The stream starts like this:
  997. // wByteOrder wFmtVer dwOSVer clsID cSections
  998. // Which is nice, because our PROPHEADER is the same!
  999. pIStream->Read((LPVOID)&m_PH, sizeof(m_PH), &cb);
  1000. if (cb != sizeof(m_PH))
  1001. return FALSE;
  1002. // Now we're pointing at the first of the FormatID/Offset pairs
  1003. // (FIDOs). To get to each section we use a cloned stream
  1004. // to stay back and point at the FIDOs (pIStrFIDO). We seek
  1005. // pIStream to each of the sections, creating CProperitySection
  1006. // and so forth as we go...
  1007. //
  1008. pIStream->Clone(&pIStrFIDO);
  1009. cSections = m_PH.cSections;
  1010. while (cSections--)
  1011. {
  1012. pIStrFIDO->Read((LPVOID)&fido, sizeof(fido), &cb);
  1013. if (cb != sizeof(fido))
  1014. {
  1015. pIStrFIDO->Release();
  1016. return FALSE;
  1017. }
  1018. // Do a seek from the beginning of the property set.
  1019. LISet32(li, fido.dwOffset);
  1020. pIStream->Seek(liPropSet, STREAM_SEEK_SET, NULL);
  1021. pIStream->Seek(li, STREAM_SEEK_CUR, NULL);
  1022. // Now pIStream is at the type/value pair
  1023. pSect = new CPropSection;
  1024. pSect->SetFormatID(fido.formatID);
  1025. pSect->ReadFromStream(pIStream, liPropSet);
  1026. m_SectionList.AddTail(pSect);
  1027. }
  1028. pIStrFIDO->Release();
  1029. return TRUE;
  1030. }
  1031. //***************************************************************************
  1032. //
  1033. //
  1034. // DESCRIPTION:
  1035. //
  1036. //
  1037. // PARAMETERS:
  1038. //
  1039. //
  1040. // RETURN VALUE:
  1041. //
  1042. //***************************************************************************
  1043. CBuff::CBuff( void )
  1044. {
  1045. bAllocError = FALSE;
  1046. pBuff = NULL;
  1047. dwSize = 0;
  1048. }
  1049. //***************************************************************************
  1050. //
  1051. //
  1052. // DESCRIPTION:
  1053. //
  1054. //
  1055. // PARAMETERS:
  1056. //
  1057. //
  1058. // RETURN VALUE:
  1059. //
  1060. //***************************************************************************
  1061. CBuff::~CBuff()
  1062. {
  1063. if(pBuff)
  1064. CoTaskMemFree(pBuff);
  1065. pBuff = NULL;
  1066. }
  1067. //***************************************************************************
  1068. //
  1069. //
  1070. // DESCRIPTION:
  1071. //
  1072. //
  1073. // PARAMETERS:
  1074. //
  1075. //
  1076. // RETURN VALUE:
  1077. //
  1078. //***************************************************************************
  1079. void CBuff::Add(void * pSrc, DWORD dwAddSize)
  1080. {
  1081. char * pDest;
  1082. if(pBuff == NULL) {
  1083. pBuff = CoTaskMemAlloc(dwAddSize);
  1084. if(pBuff == NULL) {
  1085. bAllocError = TRUE;
  1086. return;
  1087. }
  1088. pDest = (char *)pBuff;
  1089. dwSize = dwAddSize;
  1090. }
  1091. else {
  1092. void * pNew;
  1093. pNew = CoTaskMemRealloc(pBuff,dwSize+dwAddSize);
  1094. if(pNew == NULL) {
  1095. bAllocError = TRUE;
  1096. return;
  1097. }
  1098. pBuff = pNew;
  1099. pDest = (char *)pBuff + dwSize;
  1100. dwSize += dwAddSize;
  1101. }
  1102. memcpy(pDest,pSrc,dwAddSize);
  1103. }
  1104. //***************************************************************************
  1105. //
  1106. //
  1107. // DESCRIPTION:
  1108. //
  1109. //
  1110. // PARAMETERS:
  1111. //
  1112. //
  1113. // RETURN VALUE:
  1114. //
  1115. //***************************************************************************
  1116. void CBuff::RoundOff(void)
  1117. {
  1118. DWORD dwLeftOver = dwSize % 4;
  1119. if(dwLeftOver) {
  1120. DWORD dwAdd = 4 - dwLeftOver;
  1121. DWORD dwZero = 0;
  1122. Add((void *)&dwZero,dwAdd);
  1123. }
  1124. }
  1125. /////////////////////////////////////////////////////////////////////////////
  1126. // Force any extra compiler-generated code into AFX_INIT_SEG
  1127. #ifdef AFX_INIT_SEG
  1128. #pragma code_seg(AFX_INIT_SEG)
  1129. #endif