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.

237 lines
5.5 KiB

  1. // ClientCaps.cpp : Implementation of CClientCaps
  2. #include "headers.h"
  3. #pragma MARK_DATA(__FILE__)
  4. #pragma MARK_CODE(__FILE__)
  5. #pragma MARK_CONST(__FILE__)
  6. #include "iextag.h"
  7. #include "utils.hxx"
  8. #include "download.h"
  9. /////////////////////////////////////////////////////////////////////////////
  10. //
  11. // CDownload
  12. //
  13. /////////////////////////////////////////////////////////////////////////////
  14. CDownload::~CDownload()
  15. {
  16. ReleaseInterface (_pdispCallback);
  17. }
  18. /////////////////////////////////////////////////////////////////////////////
  19. HRESULT
  20. CDownload::Download(
  21. BSTR bstrURL,
  22. IDispatch * pdispCallback,
  23. IUnknown * pUnkContainer)
  24. {
  25. HRESULT hr;
  26. CComObject<CDownload> * pDownload;
  27. hr = CComObject<CDownload>::CreateInstance(&pDownload);
  28. if (hr)
  29. goto Cleanup;
  30. pDownload->_pdispCallback = pdispCallback;
  31. pdispCallback->AddRef();
  32. pDownload->StartAsyncDownload(NULL, NULL, bstrURL, pUnkContainer, TRUE);
  33. // hr can now be S_OK, S_ASYNC, or failure
  34. // ignore hr
  35. #if 0
  36. if (FAILED(hr))
  37. {
  38. hr = InvokeCallback(NULL, pdispCallback);
  39. }
  40. #endif
  41. Cleanup:
  42. return hr;
  43. }
  44. /////////////////////////////////////////////////////////////////////////////
  45. //
  46. // the implementation is similar to CBindStatusCallback::OnDataAvailable,
  47. // except it waits for the last chunk of data and only then calls OnFinalDataAvailable
  48. HRESULT
  49. CDownload::OnDataAvailable(DWORD grfBSCF, DWORD dwSize, FORMATETC *pformatetc, STGMEDIUM *pstgmed)
  50. {
  51. HRESULT hr = S_OK;
  52. DWORD dwActuallyRead;
  53. BYTE * pBytes = NULL;
  54. CComPtr<IStream> pStream;
  55. ATLTRACE(_T("CBindStatusCallback::OnDataAvailable\n"));
  56. if (!(BSCF_LASTDATANOTIFICATION & grfBSCF))
  57. goto Cleanup;
  58. ATLTRACE(_T("CBindStatusCallback::OnDataAvailable FINAL\n"));
  59. if (pstgmed->tymed != TYMED_ISTREAM)
  60. goto Cleanup;
  61. pStream = pstgmed->pstm;
  62. if (!pStream)
  63. goto Cleanup;
  64. pBytes = new BYTE[dwSize + 1];
  65. if (pBytes == NULL)
  66. {
  67. hr = E_OUTOFMEMORY;
  68. goto Cleanup;
  69. }
  70. hr = pStream->Read(pBytes, dwSize, &dwActuallyRead);
  71. if (hr)
  72. goto Cleanup;
  73. pBytes[dwActuallyRead] = 0;
  74. if (0 < dwActuallyRead)
  75. {
  76. OnFinalDataAvailable(pBytes, dwActuallyRead);
  77. }
  78. Cleanup:
  79. delete[] pBytes;
  80. return hr;
  81. }
  82. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  83. void
  84. CDownload::OnFinalDataAvailable (BYTE * pBytes, DWORD dwSize)
  85. {
  86. LPTSTR pchString = NULL;
  87. ULONG cchString;
  88. //
  89. // get unicode string
  90. //
  91. // get length
  92. cchString = MultiByteToWideChar(CP_ACP, 0, (LPSTR) pBytes, dwSize, NULL, 0);
  93. if (!cchString)
  94. goto Cleanup;
  95. pchString = new TCHAR[cchString + 1];
  96. if (!pchString)
  97. goto Cleanup;
  98. // convert now
  99. MultiByteToWideChar(CP_ACP, 0, (LPSTR) pBytes, dwSize, pchString, cchString);
  100. pchString[cchString] = 0;
  101. //
  102. // invoke the callback function
  103. //
  104. InvokeCallback(pchString, _pdispCallback);
  105. Cleanup:
  106. ClearInterface (&_pdispCallback);
  107. delete pchString;
  108. }
  109. //////////////////////////////////////////////////////////////////////////////////////////////////////////////
  110. HRESULT
  111. CDownload::InvokeCallback(LPTSTR pchString, IDispatch * pdispCallback)
  112. {
  113. HRESULT hr = S_OK;
  114. if (pdispCallback)
  115. {
  116. VARIANT varArg;
  117. DISPPARAMS dispparams = {&varArg, NULL, 1, 0};
  118. EXCEPINFO excepinfo;
  119. UINT nArgErr;
  120. if (pchString)
  121. {
  122. V_VT(&varArg) = VT_BSTR;
  123. V_BSTR(&varArg) = SysAllocString(pchString);
  124. if (!V_BSTR(&varArg))
  125. return E_OUTOFMEMORY;
  126. }
  127. else
  128. {
  129. V_VT(&varArg) = VT_NULL;
  130. }
  131. hr = pdispCallback->Invoke(
  132. DISPID_VALUE, IID_NULL, LOCALE_SYSTEM_DEFAULT,
  133. DISPATCH_METHOD, &dispparams, NULL, &excepinfo, &nArgErr);
  134. SysFreeString(V_BSTR(&varArg));
  135. }
  136. return hr;
  137. }
  138. /////////////////////////////////////////////////////////////////////////////
  139. //
  140. // CDownloadBehavior
  141. //
  142. /////////////////////////////////////////////////////////////////////////////
  143. /////////////////////////////////////////////////////////////////////////////
  144. CDownloadBehavior::CDownloadBehavior()
  145. {
  146. memset (this, 0, sizeof(*this));
  147. }
  148. /////////////////////////////////////////////////////////////////////////////
  149. CDownloadBehavior::~CDownloadBehavior()
  150. {
  151. ReleaseInterface(_pSite);
  152. }
  153. /////////////////////////////////////////////////////////////////////////////
  154. HRESULT
  155. CDownloadBehavior::Init(IElementBehaviorSite *pSite)
  156. {
  157. if (!pSite)
  158. return E_INVALIDARG;
  159. _pSite = pSite;
  160. _pSite->AddRef();
  161. return S_OK;
  162. }
  163. /////////////////////////////////////////////////////////////////////////////
  164. HRESULT
  165. CDownloadBehavior::Notify(LONG lEvent, VARIANT * pVarNotify)
  166. {
  167. return S_OK;
  168. }
  169. /////////////////////////////////////////////////////////////////////////////
  170. HRESULT
  171. CDownloadBehavior::startDownload(BSTR bstrUrl, IDispatch * pdispCallback)
  172. {
  173. HRESULT hr;
  174. if (!bstrUrl || !pdispCallback)
  175. return E_INVALIDARG;
  176. if (!AccessAllowed(bstrUrl, _pSite))
  177. return E_ACCESSDENIED;
  178. hr = CDownload::Download(bstrUrl, pdispCallback, _pSite);
  179. return hr;
  180. }