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.

311 lines
8.6 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. class CPropertySetStg;
  4. class CPropertyStg : public IPropertyStorage
  5. {
  6. public:
  7. // IUnknown
  8. STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv);
  9. STDMETHOD_(ULONG,AddRef) (THIS);
  10. STDMETHOD_(ULONG,Release) (THIS);
  11. // IPropertyStorage
  12. STDMETHODIMP ReadMultiple(ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[]);
  13. STDMETHODIMP WriteMultiple(ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst);
  14. STDMETHODIMP DeleteMultiple(ULONG cpspec, const PROPSPEC rgpspec[]);
  15. STDMETHODIMP ReadPropertyNames(ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[]);
  16. STDMETHODIMP WritePropertyNames(ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[]);
  17. STDMETHODIMP DeletePropertyNames(ULONG cpropid, const PROPID rgpropid[]);
  18. STDMETHODIMP Commit(DWORD grfCommitFlags);
  19. STDMETHODIMP Revert(void);
  20. STDMETHODIMP Enum(IEnumSTATPROPSTG **ppenum);
  21. STDMETHODIMP SetTimes(const FILETIME *pctime, const FILETIME *patime,const FILETIME *pmtime);
  22. STDMETHODIMP SetClass(REFCLSID clsid);
  23. STDMETHODIMP Stat(STATPROPSETSTG *pstatpsstg);
  24. CPropertyStg(CPropertySetStg *ppss, REFFMTID fmtid, DWORD grfMode);
  25. void FMTIDPIDToSectionProp(REFFMTID fmtid, PROPID pid, LPTSTR pszSection, LPTSTR pszValueName);
  26. private:
  27. ~CPropertyStg();
  28. BOOL _SectionValueName(const PROPSPEC *ppspec,
  29. LPTSTR pszSection, UINT cchSection, LPTSTR pszValueName, UINT cchValueName);
  30. HRESULT _ReadProp(const PROPSPEC *ppspec, PROPVARIANT *ppropvar);
  31. LONG _cRef;
  32. CPropertySetStg *_ppss; // back ptr to parent
  33. REFFMTID _fmtid;
  34. DWORD _grfMode;
  35. };
  36. class CPropertySetStg : public IPropertySetStorage
  37. {
  38. friend CPropertyStg;
  39. public:
  40. // IUnknown
  41. STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv);
  42. STDMETHOD_(ULONG,AddRef) (THIS);
  43. STDMETHOD_(ULONG,Release) (THIS);
  44. // IPropertySetStorage
  45. STDMETHODIMP Create(REFFMTID fmtid, const CLSID * pclsid, DWORD grfFlags, DWORD grfMode, IPropertyStorage** ppPropStg);
  46. STDMETHODIMP Open(REFFMTID fmtid, DWORD grfMode, IPropertyStorage** ppPropStg);
  47. STDMETHODIMP Delete(REFFMTID fmtid);
  48. STDMETHODIMP Enum(IEnumSTATPROPSETSTG** ppenum);
  49. CPropertySetStg(LPCTSTR pszFolder, DWORD grfMode);
  50. LPCTSTR IniFile() { return _szIniFile; }
  51. private:
  52. ~CPropertySetStg();
  53. HRESULT _LoadPropHandler();
  54. LONG _cRef;
  55. DWORD _grfMode; // The mode that we opened the file in.
  56. TCHAR _szIniFile[MAX_PATH]; // desktop.ini path
  57. };
  58. CPropertySetStg::CPropertySetStg(LPCTSTR pszFolder, DWORD grfMode) : _cRef(1), _grfMode(grfMode)
  59. {
  60. PathCombine(_szIniFile, pszFolder, TEXT("desktop.ini"));
  61. }
  62. CPropertySetStg::~CPropertySetStg()
  63. {
  64. }
  65. STDMETHODIMP CPropertySetStg::QueryInterface(REFIID riid, void **ppv)
  66. {
  67. static const QITAB qit[] =
  68. {
  69. QITABENT(CPropertySetStg, IPropertySetStorage),
  70. { 0 },
  71. };
  72. return QISearch(this, qit, riid, ppv);
  73. }
  74. STDMETHODIMP_(ULONG) CPropertySetStg::AddRef()
  75. {
  76. return InterlockedIncrement(&_cRef);
  77. }
  78. STDMETHODIMP_(ULONG) CPropertySetStg::Release()
  79. {
  80. ASSERT( 0 != _cRef );
  81. ULONG cRef = InterlockedDecrement(&_cRef);
  82. if ( 0 == cRef )
  83. {
  84. delete this;
  85. }
  86. return cRef;
  87. }
  88. HRESULT CPropertySetStg::_LoadPropHandler()
  89. {
  90. return E_NOTIMPL;
  91. }
  92. STDMETHODIMP CPropertySetStg::Create(REFFMTID fmtid, const CLSID *pclsid, DWORD grfFlags,
  93. DWORD grfMode, IPropertyStorage **pppropstg)
  94. {
  95. *pppropstg = NULL;
  96. return E_NOTIMPL;
  97. }
  98. STDMETHODIMP CPropertySetStg::Open(REFFMTID fmtid, DWORD grfMode, IPropertyStorage **pppropstg)
  99. {
  100. *pppropstg = new CPropertyStg(this, fmtid, grfMode);
  101. return *pppropstg ? S_OK : E_OUTOFMEMORY;
  102. }
  103. STDMETHODIMP CPropertySetStg::Delete(REFFMTID fmtid)
  104. {
  105. return STG_E_ACCESSDENIED;
  106. }
  107. STDMETHODIMP CPropertySetStg::Enum(IEnumSTATPROPSETSTG **ppenum)
  108. {
  109. *ppenum = NULL;
  110. return E_NOTIMPL;
  111. }
  112. CPropertyStg::CPropertyStg(CPropertySetStg *ppss, REFFMTID fmtid, DWORD grfMode) : _ppss(ppss), _fmtid(fmtid), _grfMode(grfMode)
  113. {
  114. _ppss->AddRef();
  115. }
  116. CPropertyStg::~CPropertyStg()
  117. {
  118. _ppss->Release();
  119. }
  120. STDMETHODIMP CPropertyStg::QueryInterface(REFIID riid, void **ppv)
  121. {
  122. static const QITAB qit[] =
  123. {
  124. QITABENT(CPropertyStg, IPropertyStorage),
  125. { 0 },
  126. };
  127. return QISearch(this, qit, riid, ppv);
  128. }
  129. STDMETHODIMP_(ULONG) CPropertyStg::AddRef()
  130. {
  131. return InterlockedIncrement(&_cRef);
  132. }
  133. STDMETHODIMP_(ULONG) CPropertyStg::Release()
  134. {
  135. ASSERT( 0 != _cRef );
  136. ULONG cRef = InterlockedDecrement(&_cRef);
  137. if ( 0 == cRef )
  138. {
  139. delete this;
  140. }
  141. return cRef;
  142. }
  143. BOOL CPropertyStg::_SectionValueName(const PROPSPEC *ppspec,
  144. LPTSTR pszSection, UINT cchSection,
  145. LPTSTR pszValueName, UINT cchValueName)
  146. {
  147. *pszSection = *pszValueName = 0;
  148. if (_fmtid == FMTID_SummaryInformation)
  149. {
  150. if (PIDSI_COMMENTS == ppspec->propid)
  151. {
  152. lstrcpyn(pszSection, TEXT(".ShellClassInfo"), cchSection);
  153. lstrcpyn(pszValueName, TEXT("InfoTip"), cchValueName);
  154. }
  155. }
  156. if (!*pszSection || !*pszValueName)
  157. {
  158. if (PID_CODEPAGE < ppspec->propid)
  159. {
  160. SHStringFromGUID(_fmtid, pszSection, cchSection);
  161. if (PRSPEC_LPWSTR == ppspec->ulKind)
  162. {
  163. SHUnicodeToTChar(ppspec->lpwstr, pszValueName, cchValueName);
  164. }
  165. else if (PRSPEC_PROPID == ppspec->ulKind)
  166. {
  167. wnsprintf(pszValueName, cchValueName, TEXT("Prop%d"), ppspec->propid);
  168. }
  169. }
  170. }
  171. return (*pszSection && *pszValueName) ? TRUE : FALSE;
  172. }
  173. HRESULT CPropertyStg::_ReadProp(const PROPSPEC *ppspec, PROPVARIANT *ppropvar)
  174. {
  175. PropVariantInit(ppropvar); // init out param to VT_EMPTY
  176. HRESULT hr = S_FALSE;
  177. TCHAR szSection[128], szPropName[128];
  178. if (_SectionValueName(ppspec, szSection, ARRAYSIZE(szSection), szPropName, ARRAYSIZE(szPropName)))
  179. {
  180. TCHAR szValue[128];
  181. UINT cch = GetPrivateProfileString(szSection, szPropName, TEXT(""), szValue, ARRAYSIZE(szValue), _ppss->IniFile());
  182. if (cch)
  183. {
  184. hr = SHStrDup(szValue, &ppropvar->pwszVal);
  185. if (SUCCEEDED(hr))
  186. ppropvar->vt = VT_LPWSTR;
  187. }
  188. }
  189. return hr;
  190. }
  191. STDMETHODIMP CPropertyStg::ReadMultiple(ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[])
  192. {
  193. HRESULT hr = S_FALSE;
  194. UINT cRead = 0;
  195. for (UINT i = 0; i < cpspec; i++)
  196. {
  197. hr = _ReadProp(&rgpspec[i], &rgpropvar[i]);
  198. if (S_OK == hr)
  199. {
  200. cRead++;
  201. }
  202. if (FAILED(hr))
  203. {
  204. FreePropVariantArray(i, rgpropvar);
  205. cRead = 0;
  206. break;
  207. }
  208. }
  209. if (cRead)
  210. hr = S_OK; // at least one non VT_EMPTY property read
  211. return hr;
  212. }
  213. STDMETHODIMP CPropertyStg::WriteMultiple(ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst)
  214. {
  215. return E_NOTIMPL;
  216. }
  217. STDMETHODIMP CPropertyStg::DeleteMultiple(ULONG cpspec, const PROPSPEC rgpspec[])
  218. {
  219. return E_NOTIMPL;
  220. }
  221. STDMETHODIMP CPropertyStg::ReadPropertyNames(ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[])
  222. {
  223. return E_NOTIMPL;
  224. }
  225. STDMETHODIMP CPropertyStg::WritePropertyNames(ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[])
  226. {
  227. return E_NOTIMPL;
  228. }
  229. STDMETHODIMP CPropertyStg::DeletePropertyNames(ULONG cpropid, const PROPID rgpropid[])
  230. {
  231. return E_NOTIMPL;
  232. }
  233. STDMETHODIMP CPropertyStg::Commit(DWORD grfCommitFlags)
  234. {
  235. return E_NOTIMPL;
  236. }
  237. STDMETHODIMP CPropertyStg::Revert(void)
  238. {
  239. return E_NOTIMPL;
  240. }
  241. STDMETHODIMP CPropertyStg::Enum(IEnumSTATPROPSTG **ppenum)
  242. {
  243. return E_NOTIMPL;
  244. }
  245. STDMETHODIMP CPropertyStg::SetTimes(const FILETIME *pctime, const FILETIME *patime,const FILETIME *pmtime)
  246. {
  247. return E_NOTIMPL;
  248. }
  249. STDMETHODIMP CPropertyStg::SetClass(REFCLSID clsid)
  250. {
  251. return E_NOTIMPL;
  252. }
  253. STDMETHODIMP CPropertyStg::Stat(STATPROPSETSTG *pstatpsstg)
  254. {
  255. return E_NOTIMPL;
  256. }
  257. STDAPI SHCreatePropStgOnFolder(LPCTSTR pszFolder, DWORD grfMode, IPropertySetStorage **ppss)
  258. {
  259. *ppss = (IPropertySetStorage *)new CPropertySetStg(pszFolder, grfMode);
  260. return *ppss ? S_OK : E_OUTOFMEMORY;
  261. }