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.

429 lines
11 KiB

  1. //=--------------------------------------------------------------------------=
  2. // Internet.Cpp
  3. //=--------------------------------------------------------------------------=
  4. // Copyright 1995-1996 Microsoft Corporation. All Rights Reserved.
  5. //
  6. // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  7. // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  8. // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  9. // PARTICULAR PURPOSE.
  10. //=--------------------------------------------------------------------------=
  11. //
  12. // contains internet helper classes CDownloadSink and CInternetControl
  13. //
  14. #include "IPServer.H"
  15. #include "Internet.H"
  16. #include "Util.H"
  17. // ZZ BUGBUG: BUILD-ISSUE: added following #define.
  18. #include "idispids.h"
  19. static VARTYPE rgI4[] = { VT_I4 };
  20. typedef enum {
  21. InternetEvent_Progress = 0,
  22. InternetEvent_ReadyStateChange = 1
  23. } INTERNETEVENTS;
  24. static EVENTINFO rgEvents [] = {
  25. { DISPID_PROGRESS, 1, rgI4 }, // (long percentDone)
  26. { DISPID_READYSTATECHANGE, 1, rgI4 }, // (OLE_READYSTATE newState)
  27. };
  28. // local class for doing async monitoring. It's not really all that
  29. // general purpose, but it does the job...
  30. class CDownloadSink : public IBindStatusCallback
  31. {
  32. public:
  33. CDownloadSink(IUnknown *punkOuter,CInternetControl *,DISPID );
  34. ~CDownloadSink();
  35. STDMETHOD(QueryInterface)(REFIID riid, void **ppvObjOut);
  36. STDMETHOD_(ULONG, AddRef)();
  37. STDMETHOD_(ULONG, Release)();
  38. STDMETHOD(OnStartBinding)(
  39. /* [in] */ DWORD grfBSCOption,
  40. /* [in] */ IBinding *pib);
  41. STDMETHOD(GetPriority)(
  42. /* [out] */ LONG *pnPriority);
  43. STDMETHOD(OnLowResource)(
  44. /* [in] */ DWORD reserved);
  45. STDMETHOD(OnProgress)(
  46. /* [in] */ ULONG ulProgress,
  47. /* [in] */ ULONG ulProgressMax,
  48. /* [in] */ ULONG ulStatusCode,
  49. /* [in] */ LPCWSTR szStatusText);
  50. STDMETHOD(OnStopBinding)(
  51. /* [in] */ HRESULT hresult,
  52. /* [in] */ LPCWSTR szError);
  53. STDMETHOD(GetBindInfo)(
  54. /* [out] */ DWORD *grfBINDINFOF,
  55. /* [unique][out][in] */ BINDINFO *pbindinfo);
  56. STDMETHOD(OnDataAvailable)(
  57. /* [in] */ DWORD grfBSCF,
  58. /* [in] */ DWORD dwSize,
  59. /* [in] */ FORMATETC *pformatetc,
  60. /* [in] */ STGMEDIUM *pstgmed);
  61. STDMETHOD(OnObjectAvailable)(
  62. /* [in] */ REFIID riid,
  63. /* [iid_is][in] */ IUnknown *punk);
  64. CDownloadSink * Next() { return(m_next); }
  65. void Next(CDownloadSink *n) { m_next = n; }
  66. DISPID DispId() { return(m_propId); }
  67. IBinding * Binding() { return(m_binding); }
  68. private:
  69. CDownloadSink * m_next;
  70. CInternetControl * m_control;
  71. DISPID m_propId;
  72. IBinding * m_binding;
  73. DWORD m_ref;
  74. IStream * m_stream;
  75. };
  76. CDownloadSink::CDownloadSink
  77. (
  78. IUnknown * punkOuter,
  79. CInternetControl * control,
  80. DISPID propId
  81. )
  82. {
  83. // CHECK_POINTER(control);
  84. m_control = control;
  85. m_control->AddRef();
  86. m_propId = propId;
  87. m_next = 0;
  88. m_binding = 0;
  89. m_ref = 0;
  90. m_stream = 0;
  91. }
  92. CDownloadSink::~CDownloadSink()
  93. {
  94. if( m_control )
  95. m_control->Release();
  96. if( m_binding )
  97. m_binding->Release();
  98. if( m_stream )
  99. m_stream->Release();
  100. }
  101. STDMETHODIMP
  102. CDownloadSink::QueryInterface(const GUID &iid,void **ppv )
  103. {
  104. if( IsEqualGUID(iid,IID_IUnknown) || IsEqualGUID(iid,IID_IBindStatusCallback) )
  105. {
  106. *ppv = this;
  107. AddRef();
  108. return(NOERROR);
  109. }
  110. return( E_NOINTERFACE );
  111. }
  112. STDMETHODIMP_(ULONG)
  113. CDownloadSink::AddRef()
  114. {
  115. return(++m_ref);
  116. }
  117. STDMETHODIMP_(ULONG)
  118. CDownloadSink::Release()
  119. {
  120. if(!--m_ref)
  121. {
  122. delete this;
  123. return(0);
  124. }
  125. return( m_ref );
  126. }
  127. STDMETHODIMP
  128. CDownloadSink::GetBindInfo( DWORD *grfBINDF, BINDINFO *pbindInfo)
  129. {
  130. *grfBINDF = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_GETNEWESTVERSION;
  131. return(NOERROR);
  132. }
  133. STDMETHODIMP
  134. CDownloadSink::OnStartBinding(DWORD /*grfBSCOption*/,IBinding *pib)
  135. {
  136. // BUGBUG: should check to see options are what we think they are
  137. m_binding = pib;
  138. pib->AddRef();
  139. return(NOERROR);
  140. }
  141. STDMETHODIMP
  142. CDownloadSink::GetPriority( LONG *pnPriority)
  143. {
  144. return(E_NOTIMPL);
  145. }
  146. STDMETHODIMP
  147. CDownloadSink::OnProgress
  148. (
  149. ULONG ulProgress,
  150. ULONG ulProgressMax,
  151. ULONG ulStatusCode,
  152. LPCWSTR pwzStatusText
  153. )
  154. {
  155. return(m_control->OnProgress(m_propId,ulProgress,
  156. ulProgressMax,ulStatusCode,pwzStatusText) );
  157. }
  158. STDMETHODIMP
  159. CDownloadSink::OnDataAvailable
  160. (
  161. DWORD grfBSCF,
  162. DWORD dwSize,
  163. FORMATETC * pFmtetc,
  164. STGMEDIUM * pstgmed
  165. )
  166. {
  167. #ifdef DEBUG
  168. char msg[200];
  169. wsprintf(msg,"::OnDataAvailable(%0xd,%d,%s,%s)\n",grfBSCF,dwSize,
  170. pFmtetc ? "pFmtetc" : "NULL", pstgmed ? "pstgmed" : "NULL" );
  171. OutputDebugString(msg);
  172. #endif
  173. if( !m_stream )
  174. m_stream = pstgmed->pstm;
  175. return(m_control->OnData( m_propId,
  176. grfBSCF,
  177. m_stream,
  178. dwSize ));
  179. }
  180. STDMETHODIMP
  181. CDownloadSink::OnObjectAvailable
  182. (
  183. REFIID riid,
  184. IUnknown *punk
  185. )
  186. {
  187. return(E_NOTIMPL);
  188. }
  189. STDMETHODIMP
  190. CDownloadSink::OnLowResource( DWORD reserved)
  191. {
  192. // BUGBUG: really should have this kind of harsh policy on this ...
  193. m_binding->Abort();
  194. return(S_OK);
  195. }
  196. STDMETHODIMP
  197. CDownloadSink::OnStopBinding(HRESULT hrError, LPCWSTR szError)
  198. {
  199. m_binding->Release();
  200. m_binding = 0;
  201. m_control->Release();
  202. m_control = 0;
  203. return(NOERROR);
  204. }
  205. //------------------------------------------------------
  206. //
  207. // class CInternetControl
  208. //
  209. //
  210. CInternetControl::CInternetControl
  211. (
  212. IUnknown * pUnkOuter,
  213. int iPrimaryDispatch,
  214. void * pMainInterface
  215. )
  216. : COleControl(pUnkOuter,iPrimaryDispatch,pMainInterface)
  217. {
  218. m_host = 0;
  219. m_readyState = READYSTATE_LOADING;
  220. }
  221. CInternetControl::~CInternetControl()
  222. {
  223. if( m_host )
  224. m_host->Release();
  225. }
  226. HRESULT CInternetControl::InternalQueryInterface
  227. (
  228. REFIID riid,
  229. void **ppvObjOut
  230. )
  231. {
  232. *ppvObjOut = NULL;
  233. return COleControl::InternalQueryInterface(riid, ppvObjOut);
  234. }
  235. HRESULT
  236. CInternetControl::GetBindHost()
  237. {
  238. if( m_host )
  239. return(NOERROR);
  240. // Try service provider first...
  241. IServiceProvider * serviceProvider = 0;
  242. HRESULT hr = m_pClientSite->QueryInterface
  243. (
  244. IID_IServiceProvider,
  245. (void**)&serviceProvider
  246. );
  247. if( SUCCEEDED(hr) )
  248. {
  249. hr = serviceProvider->QueryService
  250. (
  251. SID_IBindHost,
  252. IID_IBindHost,
  253. (void**)&m_host
  254. );
  255. serviceProvider->Release();
  256. }
  257. if( FAILED(hr) )
  258. {
  259. // Some containers put IBindHost directly on the client site
  260. hr = m_pClientSite->QueryInterface
  261. (
  262. IID_IBindHost,
  263. (void**)&m_host
  264. );
  265. }
  266. return(hr);
  267. }
  268. HRESULT CInternetControl::GetAMoniker( LPOLESTR url, IMoniker ** ppmkr )
  269. {
  270. HRESULT hr = GetBindHost();
  271. if( SUCCEEDED(hr) )
  272. hr = m_host->CreateMoniker(url,NULL, ppmkr,0);
  273. if( FAILED(hr) )
  274. {
  275. // FUTURE: This really should be a call to MkParseDisplayNameEx!!!
  276. hr = ::CreateURLMoniker(0,url,ppmkr);
  277. // hr = ::MkParseDisplayNameEx(0, url, 0, ppmkr);
  278. }
  279. return( hr );
  280. }
  281. HRESULT CInternetControl::SetupDownload( LPOLESTR url, DISPID propId )
  282. {
  283. CHECK_POINTER(url);
  284. IMoniker * pmkr;
  285. HRESULT hr = GetAMoniker( url, &pmkr );
  286. IBindCtx * pBindCtx = 0;
  287. if( SUCCEEDED(hr) )
  288. {
  289. hr = ::CreateBindCtx(0,&pBindCtx);
  290. }
  291. CDownloadSink * sink = 0;
  292. if( SUCCEEDED(hr) )
  293. {
  294. sink = new CDownloadSink(0,this,propId);
  295. if( sink )
  296. sink->AddRef();
  297. }
  298. if( SUCCEEDED(hr) && !sink )
  299. hr = E_OUTOFMEMORY;
  300. if( SUCCEEDED(hr) )
  301. {
  302. // BUGBUG: There should be a define for 0x77
  303. hr = ::RegisterBindStatusCallback(pBindCtx, sink,0, 0) ;
  304. }
  305. IStream * strm = 0;
  306. if( SUCCEEDED(hr) )
  307. hr = pmkr->BindToStorage( pBindCtx, 0, IID_IStream, (void**)&strm );
  308. if( strm )
  309. strm->Release();
  310. if( pBindCtx )
  311. pBindCtx->Release();
  312. if( FAILED(hr) && sink )
  313. sink->Release();
  314. return(hr);
  315. }
  316. HRESULT CInternetControl::OnData( DISPID, DWORD,IStream *, DWORD)
  317. {
  318. return(NOERROR);
  319. }
  320. HRESULT CInternetControl::OnProgress( DISPID, ULONG progress, ULONG themax, ULONG, LPCWSTR)
  321. {
  322. return(NOERROR);
  323. }
  324. HRESULT CInternetControl::FireReadyStateChange( long newState )
  325. {
  326. FireEvent( &::rgEvents[InternetEvent_ReadyStateChange], m_readyState = newState );
  327. return(S_OK);
  328. }
  329. HRESULT CInternetControl::FireProgress( ULONG dwAmount )
  330. {
  331. FireEvent( &::rgEvents[InternetEvent_Progress], dwAmount );
  332. return(S_OK);
  333. }
  334.