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.

235 lines
6.6 KiB

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. class CResourceMap : public IResourceMap, IPersistFile
  4. {
  5. public:
  6. CResourceMap();
  7. ~CResourceMap();
  8. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObj);
  9. STDMETHODIMP_(ULONG) AddRef(void);
  10. STDMETHODIMP_(ULONG) Release(void);
  11. // IPersist
  12. STDMETHODIMP GetClassID(CLSID* pClassID)
  13. { *pClassID = CLSID_NULL; return S_OK; }
  14. // IPersistFile
  15. STDMETHODIMP IsDirty(void)
  16. { return S_FALSE; };
  17. STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
  18. STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember)
  19. { return S_OK; };
  20. STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName)
  21. { return S_OK; };
  22. STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
  23. // IResourceMap
  24. STDMETHODIMP LoadResourceMap(LPCTSTR pszClass, LPCTSTR pszID);
  25. STDMETHODIMP SelectResourceScope(LPCTSTR pszResourceType, LPCTSTR pszID, IXMLDOMNode **ppdn);
  26. STDMETHODIMP LoadBitmap(IXMLDOMNode *pdn, LPCTSTR pszID, HBITMAP *pbm);
  27. STDMETHODIMP LoadString(IXMLDOMNode *pdn, LPCTSTR pszID, LPTSTR pszBuffer, int cch);
  28. private:
  29. LONG _cRef;
  30. TCHAR _szMapURL[MAX_PATH];
  31. IXMLDOMNode *_pdnRsrcMap; // XML node which describes this wizard
  32. };
  33. CResourceMap::CResourceMap() :
  34. _cRef(1)
  35. {
  36. }
  37. CResourceMap::~CResourceMap()
  38. {
  39. ATOMICRELEASE(_pdnRsrcMap);
  40. }
  41. ULONG CResourceMap::AddRef()
  42. {
  43. return InterlockedIncrement(&_cRef);
  44. }
  45. ULONG CResourceMap::Release()
  46. {
  47. ASSERT( 0 != _cRef );
  48. ULONG cRef = InterlockedDecrement(&_cRef);
  49. if ( 0 == cRef )
  50. {
  51. delete this;
  52. }
  53. return cRef;
  54. }
  55. HRESULT CResourceMap::QueryInterface(REFIID riid, void **ppv)
  56. {
  57. static const QITAB qit[] =
  58. {
  59. QITABENT(CResourceMap, IResourceMap), // IID_IResourceMap
  60. QITABENTMULTI(CResourceMap, IPersist, IPersistFile), // rare IID_IPersist
  61. QITABENT(CResourceMap, IPersistFile), // IID_IPersistFile
  62. {0, 0 },
  63. };
  64. return QISearch(this, qit, riid, ppv);
  65. }
  66. STDAPI CResourceMap_Initialize(LPCWSTR pszURL, IResourceMap **pprm)
  67. {
  68. CResourceMap *prm = new CResourceMap;
  69. if (!prm)
  70. return E_OUTOFMEMORY;
  71. // load from the URL we were given
  72. IPersistFile *ppf;
  73. HRESULT hr = prm->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
  74. if (SUCCEEDED(hr))
  75. {
  76. hr = ppf->Load(pszURL, 0x0);
  77. ppf->Release();
  78. }
  79. // if that succeeded then lets get the IResourceMap for the caller
  80. if (SUCCEEDED(hr))
  81. hr = prm->QueryInterface(IID_PPV_ARG(IResourceMap, pprm));
  82. prm->Release();
  83. return hr;
  84. }
  85. // IPersistFile support
  86. HRESULT CResourceMap::Load(LPCOLESTR pszFileName, DWORD dwMode)
  87. {
  88. StrCpyN(_szMapURL, pszFileName, ARRAYSIZE(_szMapURL));
  89. ATOMICRELEASE(_pdnRsrcMap);
  90. return S_OK;
  91. }
  92. HRESULT CResourceMap::GetCurFile(LPOLESTR *ppszFileName)
  93. {
  94. *ppszFileName = NULL;
  95. HRESULT hr = E_FAIL;
  96. if (_szMapURL[0])
  97. {
  98. *ppszFileName = SysAllocString(_szMapURL);
  99. hr = *ppszFileName ? S_OK:E_OUTOFMEMORY;
  100. }
  101. return hr;
  102. }
  103. // IResourceMap support
  104. HRESULT CResourceMap::LoadResourceMap(LPCTSTR pszResourceClass, LPCTSTR pszID)
  105. {
  106. IXMLDOMDocument *pdocWizardDefn;
  107. HRESULT hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IXMLDOMDocument, &pdocWizardDefn));
  108. if (SUCCEEDED(hr))
  109. {
  110. ATOMICRELEASE(_pdnRsrcMap);
  111. VARIANT varName;
  112. hr = InitVariantFromStr(&varName, _szMapURL);
  113. if (SUCCEEDED(hr))
  114. {
  115. VARIANT_BOOL fSuccess;
  116. hr = pdocWizardDefn->load(varName, &fSuccess);
  117. if (hr == S_OK)
  118. {
  119. if (fSuccess == VARIANT_TRUE)
  120. {
  121. TCHAR szPath[MAX_PATH];
  122. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("resourcemap/%s[@id='%s']"), pszResourceClass, pszID);
  123. hr = pdocWizardDefn->selectSingleNode(szPath, &_pdnRsrcMap);
  124. }
  125. else
  126. {
  127. hr = E_FAIL;
  128. }
  129. }
  130. VariantClear(&varName);
  131. }
  132. pdocWizardDefn->Release();
  133. }
  134. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr;
  135. }
  136. HRESULT CResourceMap::SelectResourceScope(LPCTSTR pszResourceType, LPCTSTR pszID, IXMLDOMNode **ppdn)
  137. {
  138. TCHAR szPath[MAX_PATH];
  139. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("%s[@id='%s']"), pszResourceType, pszID);
  140. HRESULT hr = _pdnRsrcMap->selectSingleNode(szPath, ppdn);
  141. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr; // the call can return S_FALSE
  142. }
  143. HRESULT CResourceMap::LoadBitmap(IXMLDOMNode *pdn, LPCTSTR pszID, HBITMAP *phbm)
  144. {
  145. *phbm = NULL;
  146. TCHAR szPath[MAX_PATH];
  147. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("bitmap[@id='%s']"), pszID);
  148. IXMLDOMNode *pn;
  149. HRESULT hr = (pdn ? pdn:_pdnRsrcMap)->selectSingleNode(szPath, &pn);
  150. if (hr == S_OK)
  151. {
  152. VARIANT var;
  153. hr = pn->get_nodeTypedValue(&var);
  154. if (SUCCEEDED(hr))
  155. {
  156. TCHAR szPath[MAX_PATH];
  157. VariantToStr(&var, szPath, ARRAYSIZE(szPath));
  158. VariantClear(&var);
  159. INT idRes = PathParseIconLocation(szPath) * -1; // fix -ve resource ID
  160. HINSTANCE hinst = LoadLibrary(szPath);
  161. if (hinst)
  162. {
  163. *phbm = (HBITMAP)LoadImage(hinst, MAKEINTRESOURCE(idRes),IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
  164. FreeLibrary(hinst);
  165. }
  166. }
  167. pn->Release();
  168. }
  169. return *phbm ? S_OK:E_FAIL;;
  170. }
  171. HRESULT CResourceMap::LoadString(IXMLDOMNode *pdn, LPCTSTR pszID, LPTSTR pszBuffer, int cch)
  172. {
  173. TCHAR szPath[MAX_PATH];
  174. wnsprintf(szPath, ARRAYSIZE(szPath), TEXT("text[@id='%s']"), pszID);
  175. IXMLDOMNode *pn;
  176. HRESULT hr = (pdn ? pdn:_pdnRsrcMap)->selectSingleNode(szPath, &pn);
  177. if (hr == S_OK)
  178. {
  179. VARIANT var;
  180. hr = pn->get_nodeTypedValue(&var);
  181. if (SUCCEEDED(hr))
  182. {
  183. VariantToStr(&var, pszBuffer, cch);
  184. SHLoadIndirectString(pszBuffer, pszBuffer, cch, NULL);
  185. VariantClear(&var);
  186. }
  187. pn->Release();
  188. }
  189. // try global strings if this load fails
  190. if ((hr != S_OK) && (pdn != NULL))
  191. {
  192. hr = LoadString(NULL, pszID, pszBuffer, cch); // note: this->LoadString, since we want to use global map
  193. }
  194. return (SUCCEEDED(hr) && (hr != S_OK)) ? E_FAIL:hr; // the call can return S_FALSE
  195. }