|
|
#include "shellprv.h"
#pragma hdrstop
class CPropertySetStg;
class CPropertyStg : public IPropertyStorage { public: // IUnknown
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv); STDMETHOD_(ULONG,AddRef) (THIS); STDMETHOD_(ULONG,Release) (THIS);
// IPropertyStorage
STDMETHODIMP ReadMultiple(ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[]); STDMETHODIMP WriteMultiple(ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst); STDMETHODIMP DeleteMultiple(ULONG cpspec, const PROPSPEC rgpspec[]); STDMETHODIMP ReadPropertyNames(ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[]); STDMETHODIMP WritePropertyNames(ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[]); STDMETHODIMP DeletePropertyNames(ULONG cpropid, const PROPID rgpropid[]); STDMETHODIMP Commit(DWORD grfCommitFlags); STDMETHODIMP Revert(void); STDMETHODIMP Enum(IEnumSTATPROPSTG **ppenum); STDMETHODIMP SetTimes(const FILETIME *pctime, const FILETIME *patime,const FILETIME *pmtime); STDMETHODIMP SetClass(REFCLSID clsid); STDMETHODIMP Stat(STATPROPSETSTG *pstatpsstg);
CPropertyStg(CPropertySetStg *ppss, REFFMTID fmtid, DWORD grfMode); void FMTIDPIDToSectionProp(REFFMTID fmtid, PROPID pid, LPTSTR pszSection, LPTSTR pszValueName);
private: ~CPropertyStg(); BOOL _SectionValueName(const PROPSPEC *ppspec, LPTSTR pszSection, UINT cchSection, LPTSTR pszValueName, UINT cchValueName); HRESULT _ReadProp(const PROPSPEC *ppspec, PROPVARIANT *ppropvar);
LONG _cRef; CPropertySetStg *_ppss; // back ptr to parent
REFFMTID _fmtid; DWORD _grfMode; };
class CPropertySetStg : public IPropertySetStorage { friend CPropertyStg; public: // IUnknown
STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **ppv); STDMETHOD_(ULONG,AddRef) (THIS); STDMETHOD_(ULONG,Release) (THIS);
// IPropertySetStorage
STDMETHODIMP Create(REFFMTID fmtid, const CLSID * pclsid, DWORD grfFlags, DWORD grfMode, IPropertyStorage** ppPropStg); STDMETHODIMP Open(REFFMTID fmtid, DWORD grfMode, IPropertyStorage** ppPropStg); STDMETHODIMP Delete(REFFMTID fmtid); STDMETHODIMP Enum(IEnumSTATPROPSETSTG** ppenum);
CPropertySetStg(LPCTSTR pszFolder, DWORD grfMode);
LPCTSTR IniFile() { return _szIniFile; }
private: ~CPropertySetStg(); HRESULT _LoadPropHandler();
LONG _cRef; DWORD _grfMode; // The mode that we opened the file in.
TCHAR _szIniFile[MAX_PATH]; // desktop.ini path
};
CPropertySetStg::CPropertySetStg(LPCTSTR pszFolder, DWORD grfMode) : _cRef(1), _grfMode(grfMode) { PathCombine(_szIniFile, pszFolder, TEXT("desktop.ini")); }
CPropertySetStg::~CPropertySetStg() { }
STDMETHODIMP CPropertySetStg::QueryInterface(REFIID riid, void **ppv) { static const QITAB qit[] = { QITABENT(CPropertySetStg, IPropertySetStorage), { 0 }, }; return QISearch(this, qit, riid, ppv); }
STDMETHODIMP_(ULONG) CPropertySetStg::AddRef() { return InterlockedIncrement(&_cRef); }
STDMETHODIMP_(ULONG) CPropertySetStg::Release() { ASSERT( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
HRESULT CPropertySetStg::_LoadPropHandler() { return E_NOTIMPL; }
STDMETHODIMP CPropertySetStg::Create(REFFMTID fmtid, const CLSID *pclsid, DWORD grfFlags, DWORD grfMode, IPropertyStorage **pppropstg) { *pppropstg = NULL; return E_NOTIMPL; }
STDMETHODIMP CPropertySetStg::Open(REFFMTID fmtid, DWORD grfMode, IPropertyStorage **pppropstg) { *pppropstg = new CPropertyStg(this, fmtid, grfMode); return *pppropstg ? S_OK : E_OUTOFMEMORY; }
STDMETHODIMP CPropertySetStg::Delete(REFFMTID fmtid) { return STG_E_ACCESSDENIED; }
STDMETHODIMP CPropertySetStg::Enum(IEnumSTATPROPSETSTG **ppenum) { *ppenum = NULL; return E_NOTIMPL; }
CPropertyStg::CPropertyStg(CPropertySetStg *ppss, REFFMTID fmtid, DWORD grfMode) : _ppss(ppss), _fmtid(fmtid), _grfMode(grfMode) { _ppss->AddRef(); }
CPropertyStg::~CPropertyStg() { _ppss->Release(); }
STDMETHODIMP CPropertyStg::QueryInterface(REFIID riid, void **ppv) { static const QITAB qit[] = { QITABENT(CPropertyStg, IPropertyStorage), { 0 }, }; return QISearch(this, qit, riid, ppv); }
STDMETHODIMP_(ULONG) CPropertyStg::AddRef() { return InterlockedIncrement(&_cRef); }
STDMETHODIMP_(ULONG) CPropertyStg::Release() { ASSERT( 0 != _cRef ); ULONG cRef = InterlockedDecrement(&_cRef); if ( 0 == cRef ) { delete this; } return cRef; }
BOOL CPropertyStg::_SectionValueName(const PROPSPEC *ppspec, LPTSTR pszSection, UINT cchSection, LPTSTR pszValueName, UINT cchValueName) { *pszSection = *pszValueName = 0;
if (_fmtid == FMTID_SummaryInformation) { if (PIDSI_COMMENTS == ppspec->propid) { lstrcpyn(pszSection, TEXT(".ShellClassInfo"), cchSection); lstrcpyn(pszValueName, TEXT("InfoTip"), cchValueName); } }
if (!*pszSection || !*pszValueName) { if (PID_CODEPAGE < ppspec->propid) { SHStringFromGUID(_fmtid, pszSection, cchSection); if (PRSPEC_LPWSTR == ppspec->ulKind) { SHUnicodeToTChar(ppspec->lpwstr, pszValueName, cchValueName); } else if (PRSPEC_PROPID == ppspec->ulKind) { wnsprintf(pszValueName, cchValueName, TEXT("Prop%d"), ppspec->propid); } } } return (*pszSection && *pszValueName) ? TRUE : FALSE; }
HRESULT CPropertyStg::_ReadProp(const PROPSPEC *ppspec, PROPVARIANT *ppropvar) { PropVariantInit(ppropvar); // init out param to VT_EMPTY
HRESULT hr = S_FALSE;
TCHAR szSection[128], szPropName[128]; if (_SectionValueName(ppspec, szSection, ARRAYSIZE(szSection), szPropName, ARRAYSIZE(szPropName))) { TCHAR szValue[128]; UINT cch = GetPrivateProfileString(szSection, szPropName, TEXT(""), szValue, ARRAYSIZE(szValue), _ppss->IniFile()); if (cch) { hr = SHStrDup(szValue, &ppropvar->pwszVal); if (SUCCEEDED(hr)) ppropvar->vt = VT_LPWSTR; } } return hr; }
STDMETHODIMP CPropertyStg::ReadMultiple(ULONG cpspec, const PROPSPEC rgpspec[], PROPVARIANT rgpropvar[]) { HRESULT hr = S_FALSE; UINT cRead = 0; for (UINT i = 0; i < cpspec; i++) { hr = _ReadProp(&rgpspec[i], &rgpropvar[i]); if (S_OK == hr) { cRead++; }
if (FAILED(hr)) { FreePropVariantArray(i, rgpropvar); cRead = 0; break; } }
if (cRead) hr = S_OK; // at least one non VT_EMPTY property read
return hr; }
STDMETHODIMP CPropertyStg::WriteMultiple(ULONG cpspec, const PROPSPEC rgpspec[], const PROPVARIANT rgpropvar[], PROPID propidNameFirst) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::DeleteMultiple(ULONG cpspec, const PROPSPEC rgpspec[]) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::ReadPropertyNames(ULONG cpropid, const PROPID rgpropid[], LPOLESTR rglpwstrName[]) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::WritePropertyNames(ULONG cpropid, const PROPID rgpropid[], const LPOLESTR rglpwstrName[]) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::DeletePropertyNames(ULONG cpropid, const PROPID rgpropid[]) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::Commit(DWORD grfCommitFlags) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::Revert(void) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::Enum(IEnumSTATPROPSTG **ppenum) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::SetTimes(const FILETIME *pctime, const FILETIME *patime,const FILETIME *pmtime) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::SetClass(REFCLSID clsid) { return E_NOTIMPL; }
STDMETHODIMP CPropertyStg::Stat(STATPROPSETSTG *pstatpsstg) { return E_NOTIMPL; }
STDAPI SHCreatePropStgOnFolder(LPCTSTR pszFolder, DWORD grfMode, IPropertySetStorage **ppss) { *ppss = (IPropertySetStorage *)new CPropertySetStg(pszFolder, grfMode); return *ppss ? S_OK : E_OUTOFMEMORY; }
|