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.

329 lines
8.8 KiB

  1. #include <urlmon.h>
  2. #include <htmlguid.h>
  3. #include <ocidl.h>
  4. #include "..\\inc\\urlint.h"
  5. #include "..\\inc\\wcheckcb.h"
  6. #include "..\\inc\\debug.h"
  7. #include "..\\download\\cdl.h"
  8. #include "Status.h"
  9. // {5DFE9E81-46E4-11d0-94E8-00AA0059CE02}
  10. const CLSID CLSID_ControlRefreshCallback = {
  11. 0x5dfe9e81, 0x46e4, 0x11d0,
  12. 0x94, 0xe8, 0x0, 0xaa, 0x0,
  13. 0x59, 0xce, 0x2
  14. };
  15. const static TCHAR *g_pszUpdateInfo = TEXT("UpdateInfo");
  16. const static TCHAR *g_pszNewControlInCache = TEXT("NewControlInCache");
  17. #define CLSID_MAX_LENGTH 50
  18. #define CONTENT_MAX_LENGTH 1024
  19. /******************************************************************************
  20. Constructor, Destructor and helper methods
  21. ******************************************************************************/
  22. CControlRefreshCallback::CControlRefreshCallback()
  23. {
  24. DllAddRef();
  25. m_cRef = 1;
  26. m_clsidCtrl = CLSID_NULL;
  27. m_wszURL[0] = '\0';
  28. }
  29. CControlRefreshCallback::~CControlRefreshCallback()
  30. {
  31. Assert(m_cRef == 0);
  32. DllRelease();
  33. }
  34. // Give this object information such as the clsid and url of the control
  35. // it's dealing with
  36. STDMETHODIMP CControlRefreshCallback::SetInfo(
  37. REFCLSID rclsidControl,
  38. LPCWSTR lpwszURL)
  39. {
  40. m_clsidCtrl = rclsidControl;
  41. // copy wide strings
  42. #ifdef UNICODE
  43. lstrcpyW(m_wszURL, lpwszURL); // only works in Win32 mode
  44. // fails on Win95
  45. #else
  46. INT i = 0;
  47. for(; lpwszURL[i]; i++)
  48. m_wszURL[i] = lpwszURL[i];
  49. m_wszURL[i] = '\0';
  50. #endif
  51. Assert(lstrlenW(m_wszURL) == lstrlenW(lpwszURL));
  52. return S_OK;
  53. }
  54. /*
  55. HRESULT CControlRefreshCallback::UpdateControlInCacheFlag(
  56. SCODE scReason) const
  57. {
  58. // update flag in registry so that IE initiates a new
  59. // download when the control is visited.
  60. LONG lResult = ERROR_SUCCESS;
  61. TCHAR szKey[MAX_PATH];
  62. LPOLESTR pwcsClsid = NULL;
  63. BOOL fChanged = (scReason == S_OK);
  64. lstrcpy(szKey, TEXT("CLSID\\"));
  65. if (SUCCEEDED(::StringFromCLSID(m_clsidCtrl, &pwcsClsid)))
  66. {
  67. HKEY hKey = NULL;
  68. int nLen = lstrlen(szKey);
  69. if (WideCharToMultiByte(
  70. CP_ACP, 0, pwcsClsid, -1, szKey + nLen,
  71. MAX_PATH - nLen, NULL, NULL) > 0)
  72. {
  73. lstrcat(szKey, "\\");
  74. lstrcat(szKey, g_pszUpdateInfo);
  75. lResult = RegOpenKeyEx(
  76. HKEY_CLASSES_ROOT, szKey, 0,
  77. KEY_ALL_ACCESS, &hKey);
  78. if (lResult == ERROR_SUCCESS)
  79. {
  80. DWORD dwKeySet = 0;
  81. DWORD dwSize = sizeof(DWORD);
  82. lResult = RegQueryValueEx(
  83. hKey, g_pszNewControlInCache, NULL, NULL,
  84. (LPBYTE)&dwKeySet, &dwSize);
  85. if (lResult != ERROR_SUCCESS || (dwKeySet == 0 && fChanged))
  86. {
  87. dwKeySet = (fChanged ? 1 : 0);
  88. lResult = RegSetValueEx(
  89. hKey, g_pszNewControlInCache, 0,
  90. REG_DWORD, (LPBYTE)&dwKeySet, sizeof(DWORD));
  91. }
  92. RegCloseKey(hKey);
  93. }
  94. }
  95. delete pwcsClsid;
  96. }
  97. return (lResult == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32(lResult));
  98. }
  99. */
  100. HRESULT CControlRefreshCallback::DownloadControl() const
  101. {
  102. HRESULT hr = S_OK;
  103. CSilentCodeDLSink *pscdls = NULL;
  104. LPBC pbc = NULL;
  105. Assert(lstrlenW(m_wszURL) > 0);
  106. Assert(m_clsidCtrl != CLSID_NULL);
  107. pscdls = new CSilentCodeDLSink;
  108. if (pscdls == NULL)
  109. {
  110. hr = E_OUTOFMEMORY;
  111. goto Exit;
  112. }
  113. hr = CreateBindCtx(0, &pbc);
  114. if (SUCCEEDED(hr))
  115. hr = RegisterBindStatusCallback(pbc, pscdls, NULL, 0);
  116. if (FAILED(hr))
  117. goto Exit;
  118. hr = AsyncGetClassBits(
  119. m_clsidCtrl, NULL, NULL,
  120. (DWORD)-1, (DWORD)-1, m_wszURL,
  121. pbc, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
  122. NULL, IID_IClassFactory, 0);
  123. if (hr == MK_S_ASYNCHRONOUS)
  124. hr = pscdls->WaitTillNotified();
  125. RevokeBindStatusCallback(pbc, pscdls);
  126. Exit:
  127. if (pbc)
  128. pbc->Release();
  129. if (pscdls)
  130. pscdls->Release();
  131. return hr;
  132. }
  133. /******************************************************************************
  134. IUnknown Methods
  135. ******************************************************************************/
  136. STDMETHODIMP CControlRefreshCallback::QueryInterface(
  137. REFIID iid,
  138. void** ppvObject)
  139. {
  140. *ppvObject = NULL;
  141. if (iid == IID_IUnknown)
  142. {
  143. *ppvObject = (void*)this;
  144. }
  145. else if (iid == IID_IPersistStream)
  146. {
  147. *ppvObject = (void*)(IPersistStream*)this;
  148. }
  149. else if (iid == IID_IWebCheckAdviseSink)
  150. {
  151. *ppvObject = (void*)(IWebCheckAdviseSink*)this;
  152. }
  153. if (*ppvObject)
  154. {
  155. ((LPUNKNOWN)*ppvObject)->AddRef();
  156. return S_OK;
  157. }
  158. return E_NOINTERFACE;
  159. }
  160. STDMETHODIMP_(ULONG) CControlRefreshCallback::AddRef()
  161. {
  162. return ++m_cRef;
  163. }
  164. STDMETHODIMP_(ULONG) CControlRefreshCallback::Release()
  165. {
  166. if (--m_cRef)
  167. return m_cRef;
  168. delete this;
  169. return 0;
  170. }
  171. /******************************************************************************
  172. IPersistStream Methods
  173. ******************************************************************************/
  174. STDMETHODIMP CControlRefreshCallback::GetClassID(CLSID* pClsssID)
  175. {
  176. *pClsssID = CLSID_ControlRefreshCallback;
  177. return S_OK;
  178. }
  179. STDMETHODIMP CControlRefreshCallback::IsDirty(void)
  180. {
  181. Assert(m_clsidCtrl != CLSID_NULL);
  182. return (m_clsidCtrl != CLSID_NULL ? S_OK : S_FALSE);
  183. }
  184. STDMETHODIMP CControlRefreshCallback::Load(IStream* pStm)
  185. {
  186. DWORD dwLen = 0;
  187. ULONG cb = sizeof(CLSID);
  188. ULONG cbRead = 0;
  189. pStm->Read((void*)&m_clsidCtrl, cb, &cbRead);
  190. Assert(cb == cbRead);
  191. if (cb != cbRead)
  192. goto Exit;
  193. cb = sizeof(DWORD);
  194. cbRead = 0;
  195. pStm->Read((void*)&dwLen, cb, &cbRead);
  196. Assert(cb == cbRead);
  197. if (cb != cbRead)
  198. goto Exit;
  199. cb = dwLen * sizeof(WCHAR);
  200. cbRead = 0;
  201. pStm->Read((void*)&m_wszURL, cb, &cbRead);
  202. Assert(cb == cbRead);
  203. Assert((DWORD)lstrlenW(m_wszURL) == dwLen - 1);
  204. Exit:
  205. return (cbRead == cb ? S_OK : E_FAIL);
  206. }
  207. STDMETHODIMP CControlRefreshCallback::Save(IStream* pStm, BOOL fClearDirty)
  208. {
  209. DWORD dwLen = lstrlenW(m_wszURL) + 1; // add 1 for NULL char
  210. ULONG cb = sizeof(CLSID);
  211. ULONG cbSaved = 0;
  212. pStm->Write((void*)&m_clsidCtrl, cb, &cbSaved);
  213. Assert(cb == cbSaved);
  214. if (cb != cbSaved)
  215. goto Exit;
  216. cb = sizeof(DWORD);
  217. cbSaved = 0;
  218. pStm->Write((void*)&dwLen, cb, &cbSaved);
  219. Assert(cb == cbSaved);
  220. if (cb != cbSaved)
  221. goto Exit;
  222. cb = dwLen * sizeof(WCHAR);
  223. cbSaved = 0;
  224. pStm->Write((void*)m_wszURL, cb, &cbSaved);
  225. Assert(cb == cbSaved);
  226. Exit:
  227. return (cbSaved == cb ? S_OK : E_FAIL);
  228. }
  229. STDMETHODIMP CControlRefreshCallback::GetSizeMax(ULARGE_INTEGER* pcbSize)
  230. {
  231. pcbSize->QuadPart = sizeof(CLSID) + sizeof(DWORD) + sizeof(m_wszURL);
  232. return S_OK;
  233. }
  234. /******************************************************************************
  235. IWebCheckAdviseSink Methods
  236. ******************************************************************************/
  237. STDMETHODIMP CControlRefreshCallback::UpdateBegin(
  238. long lCookie,
  239. SCODE scReason,
  240. BSTR lpURL)
  241. {
  242. return S_OK;
  243. }
  244. // scReason -- S_OK means changed, S_FALSE means no changes
  245. STDMETHODIMP CControlRefreshCallback::UpdateEnd(
  246. long lCookie,
  247. SCODE scReason)
  248. {
  249. Assert(m_clsidCtrl != CLSID_NULL);
  250. LONG lResult = ERROR_SUCCESS;
  251. if (scReason == S_OK)
  252. {
  253. DownloadControl();
  254. // UpdateControlInCacheFlag(scReason);
  255. }
  256. return S_OK;
  257. }
  258. STDMETHODIMP CControlRefreshCallback::UpdateProgress(
  259. long lCookie,
  260. long lCurrent,
  261. long lMax)
  262. {
  263. return S_OK;
  264. }