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.

375 lines
9.0 KiB

  1. // ===========================================================================
  2. // File: DUMAN.CXX
  3. // Distribution Unit Manager
  4. //
  5. #include <cdlpch.h>
  6. #include <dispex.h>
  7. #include <delaydll.h>
  8. #define ERROR_EXIT(cond) if (!(cond)) { \
  9. goto Exit;}
  10. HRESULT DupAttributeA(IXMLElement *pElem, LPWSTR szAttribName, LPSTR *ppszRet)
  11. {
  12. DEBUG_ENTER((DBG_DOWNLOAD,
  13. Hresult,
  14. "DupAttributeA",
  15. "%#x, %.80wq, %#x",
  16. pElem, szAttribName, ppszRet
  17. ));
  18. VARIANT vProp;
  19. LPSTR pVal = NULL;
  20. HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
  21. if (SUCCEEDED(hr)) {
  22. DWORD len;
  23. // compute length
  24. if (!(len = WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pVal,
  25. 0, NULL, NULL))) {
  26. hr = HRESULT_FROM_WIN32(GetLastError());
  27. goto Exit;
  28. }
  29. pVal = new char[len+1];
  30. if (!pVal) {
  31. hr = E_OUTOFMEMORY;
  32. goto Exit;
  33. }
  34. if (!WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pVal,
  35. len, NULL, NULL)) {
  36. SAFEDELETE(pVal);
  37. hr = HRESULT_FROM_WIN32(GetLastError());
  38. }
  39. }
  40. Exit:
  41. VariantClear(&vProp);
  42. if (pVal) {
  43. SAFEDELETE((*ppszRet));
  44. *ppszRet = pVal;
  45. }
  46. DEBUG_LEAVE(hr);
  47. return hr;
  48. }
  49. HRESULT DupAttribute(IXMLElement *pElem, LPWSTR szAttribName, LPWSTR *ppszRet)
  50. {
  51. DEBUG_ENTER((DBG_DOWNLOAD,
  52. Hresult,
  53. "DupAttribute",
  54. "%#x, %.80wq, %#x",
  55. pElem, szAttribName, ppszRet
  56. ));
  57. VARIANT vProp;
  58. LPWSTR pVal = NULL;
  59. HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
  60. if (SUCCEEDED(hr)) {
  61. Assert(vProp.vt == VT_BSTR);
  62. Assert(vProp.bstrVal);
  63. if (vProp.bstrVal) {
  64. hr = CDLDupWStr( &pVal, vProp.bstrVal);
  65. } else {
  66. hr = E_FAIL;
  67. }
  68. }
  69. VariantClear(&vProp);
  70. if (pVal) {
  71. SAFEDELETE((*ppszRet));
  72. *ppszRet = pVal;
  73. }
  74. DEBUG_LEAVE(hr);
  75. return hr;
  76. }
  77. HRESULT GetAttributeA(IXMLElement *pElem, LPWSTR szAttribName, LPSTR pAttribValue, DWORD dwBufferLen)
  78. {
  79. DEBUG_ENTER((DBG_DOWNLOAD,
  80. Hresult,
  81. "GetAttributeA",
  82. "%#x, %.80wq, %.80q, %#x",
  83. pElem, szAttribName, pAttribValue, dwBufferLen
  84. ));
  85. VARIANT vProp;
  86. HRESULT hr = GetAttribute(pElem, szAttribName, &vProp);
  87. if (SUCCEEDED(hr)) {
  88. if (!WideCharToMultiByte(CP_ACP, 0, vProp.bstrVal , -1, pAttribValue,
  89. dwBufferLen, NULL, NULL)) {
  90. hr = HRESULT_FROM_WIN32(GetLastError());
  91. }
  92. VariantClear(&vProp);
  93. }
  94. DEBUG_LEAVE(hr);
  95. return hr;
  96. }
  97. HRESULT GetAttribute(IXMLElement *pElem, LPWSTR szAttribName, VARIANT *pvProp)
  98. {
  99. DEBUG_ENTER((DBG_DOWNLOAD,
  100. Hresult,
  101. "GetAttribute",
  102. "%#x, %.80wq, %#x",
  103. pElem, szAttribName, pvProp
  104. ));
  105. HRESULT hr = S_OK;
  106. VariantInit(pvProp);
  107. if ((hr = pElem->getAttribute(szAttribName, pvProp)) == S_OK )
  108. {
  109. Assert(pvProp->vt == VT_BSTR);
  110. // caller needs to VariantClear(pvProp);
  111. }
  112. if (hr == S_FALSE) {
  113. hr = REGDB_E_KEYMISSING;
  114. }
  115. DEBUG_LEAVE(hr);
  116. return hr;
  117. }
  118. HRESULT GetNextChildTag(IXMLElement *pRoot, LPCWSTR szTag, IXMLElement **ppChildReq, int &nLastChild)
  119. {
  120. DEBUG_ENTER((DBG_DOWNLOAD,
  121. Hresult,
  122. "GetNextChildTag",
  123. "%#x, %.80wq, %#x, %#x",
  124. pRoot, szTag, ppChildReq, &nLastChild
  125. ));
  126. BSTR bstrTag = NULL;
  127. IXMLElementCollection * pChildren = NULL;
  128. HRESULT hr = S_FALSE; // assume not found.
  129. IXMLElement * pChild = NULL;
  130. //
  131. // Find the children if they exist
  132. //
  133. if (SUCCEEDED(pRoot->get_children(&pChildren)) && pChildren)
  134. {
  135. long length = 0;
  136. if (SUCCEEDED(pChildren->get_length(&length)) && length > 0)
  137. {
  138. VARIANT vIndex, vEmpty;
  139. vIndex.vt = VT_I4;
  140. vEmpty.vt = VT_EMPTY;
  141. nLastChild++;
  142. for (long i=nLastChild; i<length; i++)
  143. {
  144. vIndex.lVal = i;
  145. IDispatch *pDispItem = NULL;
  146. if (SUCCEEDED(pChildren->item(vIndex, vEmpty, &pDispItem)))
  147. {
  148. if (SUCCEEDED(pDispItem->QueryInterface(IID_IXMLElement, (void **)&pChild)))
  149. {
  150. // look for first SoftDist tag
  151. pChild->get_tagName(&bstrTag);
  152. // we may get a NULL bstrTag, possibly from a comment TAG, hence check returned bstrTag
  153. if (bstrTag && (StrCmpIW(bstrTag, szTag) == 0))
  154. {
  155. nLastChild = i;
  156. SAFERELEASE(pDispItem);
  157. hr = S_OK;
  158. goto Exit;
  159. }
  160. SAFESYSFREESTRING(bstrTag);
  161. SAFERELEASE(pChild);
  162. }
  163. SAFERELEASE(pDispItem);
  164. }
  165. }
  166. }
  167. }
  168. else
  169. {
  170. hr = E_FAIL;
  171. }
  172. Exit:
  173. *ppChildReq = pChild;
  174. if (pChildren)
  175. SAFERELEASE(pChildren);
  176. SAFESYSFREESTRING(bstrTag);
  177. DEBUG_LEAVE(hr);
  178. return hr;
  179. }
  180. HRESULT GetFirstChildTag(IXMLElement *pRoot, LPCWSTR szTag, IXMLElement **ppChildReq)
  181. {
  182. DEBUG_ENTER((DBG_DOWNLOAD,
  183. Hresult,
  184. "GetFirstChildTag",
  185. "%#x, %.80wq, %#x",
  186. pRoot, szTag, ppChildReq
  187. ));
  188. int nLastChild = -1; // first child, never seen any before this one
  189. HRESULT hr = GetNextChildTag(pRoot, szTag, ppChildReq, nLastChild);
  190. DEBUG_LEAVE(hr);
  191. return hr;
  192. }
  193. HRESULT
  194. GetTextContent(IXMLElement *pRoot, LPCWSTR szTag, LPWSTR *ppszContent)
  195. {
  196. DEBUG_ENTER((DBG_DOWNLOAD,
  197. Hresult,
  198. "GetTextContent",
  199. "%#x, %.80wq, %#x",
  200. pRoot, szTag, ppszContent
  201. ));
  202. IXMLElement *pChild = NULL;
  203. HRESULT hr = S_OK;
  204. if (GetFirstChildTag(pRoot, szTag, &pChild) == S_OK) {
  205. BSTR bstrText = NULL;
  206. hr = pChild->get_text(&bstrText);
  207. if (FAILED(hr)) {
  208. goto Exit;
  209. }
  210. if (bstrText) {
  211. hr = CDLDupWStr( ppszContent, bstrText);
  212. } else {
  213. hr = E_FAIL;
  214. }
  215. SAFESYSFREESTRING(bstrText);
  216. }
  217. Exit:
  218. SAFERELEASE(pChild);
  219. DEBUG_LEAVE(hr);
  220. return hr;
  221. }
  222. HRESULT GetSoftDistFromOSD(LPCSTR szFile, IXMLElement **ppSoftDist)
  223. {
  224. DEBUG_ENTER((DBG_DOWNLOAD,
  225. Hresult,
  226. "GetSoftDistFromOSD",
  227. "%.80q, %#x",
  228. szFile, ppSoftDist
  229. ));
  230. HRESULT hr = S_OK;
  231. IXMLDocument *pDoc = NULL;
  232. IStream *pStm = NULL;
  233. IPersistStreamInit *pPSI = NULL;
  234. IXMLElement *pRoot = NULL;
  235. BSTR bStrName;
  236. // BUGBUG: optimize here to keep the xml parser up beyond the current code
  237. // download?
  238. //
  239. // Create an empty XML document
  240. //
  241. hr = CoCreateInstance(CLSID_XMLDocument, NULL, CLSCTX_INPROC_SERVER,
  242. IID_IXMLDocument, (void**)&pDoc);
  243. ERROR_EXIT (pDoc);
  244. //
  245. // Synchronously create a stream on an URL
  246. //
  247. hr = URLOpenBlockingStream(0, szFile, &pStm, 0,0);
  248. ERROR_EXIT(SUCCEEDED(hr) && pStm);
  249. //
  250. // Get the IPersistStreamInit interface to the XML doc
  251. //
  252. hr = pDoc->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);
  253. ERROR_EXIT(SUCCEEDED(hr));
  254. //
  255. // Init the XML doc from the stream
  256. //
  257. hr = pPSI->Load(pStm);
  258. ERROR_EXIT(SUCCEEDED(hr));
  259. //
  260. // Now walk the OM and look at interesting things:
  261. //
  262. hr = pDoc->get_root(&pRoot);
  263. ERROR_EXIT(SUCCEEDED(hr));
  264. hr = pRoot->get_tagName(&bStrName);
  265. if (StrCmpIW(bStrName, DU_TAG_SOFTDIST) == 0)
  266. {
  267. *ppSoftDist = pRoot;
  268. (*ppSoftDist)->AddRef();
  269. hr = S_OK;
  270. }
  271. else
  272. {
  273. *ppSoftDist = NULL;
  274. hr = E_FAIL;
  275. }
  276. SAFESYSFREESTRING(bStrName);
  277. Exit:
  278. SAFERELEASE(pDoc);
  279. SAFERELEASE(pPSI);
  280. SAFERELEASE(pStm);
  281. SAFERELEASE(pRoot);
  282. DEBUG_LEAVE(hr);
  283. return hr;
  284. }