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.

289 lines
6.8 KiB

  1. #include "Status.h"
  2. #include "..\\inc\\urlmon.hxx"
  3. #define TIMEOUT 600000 // 10 minutes
  4. /******************************************************************************
  5. Constructor and destructor and helper functions
  6. ******************************************************************************/
  7. CSilentCodeDLSink::CSilentCodeDLSink()
  8. {
  9. m_cRef = 1;
  10. m_pBinding = NULL;
  11. m_hOnStopBindingEvt = CreateEvent(NULL, TRUE, FALSE, NULL);
  12. m_fAbort = FALSE;
  13. }
  14. CSilentCodeDLSink::~CSilentCodeDLSink()
  15. {
  16. if(m_hOnStopBindingEvt)
  17. CloseHandle(m_hOnStopBindingEvt);
  18. }
  19. VOID CSilentCodeDLSink::Abort()
  20. {
  21. m_fAbort = TRUE;
  22. }
  23. HRESULT CSilentCodeDLSink::WaitTillNotified()
  24. {
  25. if (m_hOnStopBindingEvt == NULL)
  26. return E_FAIL;
  27. HRESULT hr = E_FAIL;
  28. DWORD dwResult = 0;
  29. const DWORD MORE_INPUT = WAIT_OBJECT_0 + 1;
  30. MSG msg;
  31. // Test state of event
  32. dwResult = WaitForSingleObject(m_hOnStopBindingEvt, 0);
  33. if (dwResult == WAIT_FAILED)
  34. return HRESULT_FROM_WIN32(GetLastError());
  35. // Note that MsgWaitForMultipleObjects doesn't return
  36. // if there was previously unread input of the specified
  37. // type in the queue. It only wakes up when input arrives.
  38. for (dwResult = MORE_INPUT; dwResult == MORE_INPUT; )
  39. {
  40. if (dwResult == MORE_INPUT)
  41. {
  42. // more input in queue
  43. while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  44. {
  45. TranslateMessage(&msg);
  46. DispatchMessage(&msg);
  47. }
  48. }
  49. else if (dwResult == WAIT_OBJECT_0)
  50. {
  51. // event has been signaled
  52. hr = S_OK;
  53. }
  54. else if (dwResult == 0xFFFFFFFF)
  55. {
  56. // error has occurred
  57. hr = HRESULT_FROM_WIN32(GetLastError());
  58. }
  59. else
  60. {
  61. // timeout or wait abondaned
  62. hr = E_FAIL;
  63. }
  64. dwResult = MsgWaitForMultipleObjects(
  65. 1, &m_hOnStopBindingEvt,
  66. FALSE, TIMEOUT, QS_ALLINPUT);
  67. }
  68. if (FAILED(hr))
  69. Abort();
  70. return hr;
  71. }
  72. /******************************************************************************
  73. IUnknown Methods
  74. ******************************************************************************/
  75. STDMETHODIMP CSilentCodeDLSink::QueryInterface(REFIID riid, void **ppv)
  76. {
  77. *ppv = NULL;
  78. if (riid == IID_IUnknown || riid == IID_IBindStatusCallback)
  79. {
  80. *ppv = (IBindStatusCallback*)this;
  81. }
  82. else if (riid == IID_ICodeInstall)
  83. {
  84. *ppv = (ICodeInstall*)this;
  85. }
  86. else if (riid == IID_IWindowForBindingUI)
  87. {
  88. *ppv = (IWindowForBindingUI*)this;
  89. }
  90. if (*ppv != NULL)
  91. {
  92. ((IUnknown*)*ppv)->AddRef();
  93. return S_OK;
  94. }
  95. return E_NOINTERFACE;
  96. }
  97. STDMETHODIMP_(ULONG) CSilentCodeDLSink::AddRef()
  98. {
  99. return ++m_cRef;
  100. }
  101. STDMETHODIMP_(ULONG) CSilentCodeDLSink::Release()
  102. {
  103. if (--m_cRef)
  104. return m_cRef;
  105. delete this;
  106. return 0;
  107. }
  108. /******************************************************************************
  109. IBindStatusCallback Methods
  110. ******************************************************************************/
  111. STDMETHODIMP CSilentCodeDLSink::OnStartBinding(DWORD grfBSCOption, IBinding *pib)
  112. {
  113. if (m_pBinding != NULL)
  114. m_pBinding->Release();
  115. m_pBinding = pib;
  116. if (m_pBinding != NULL)
  117. m_pBinding->AddRef();
  118. if (m_fAbort)
  119. m_pBinding->Abort();
  120. return S_OK;
  121. }
  122. STDMETHODIMP CSilentCodeDLSink::GetPriority(LONG *pnPriority)
  123. {
  124. if (m_fAbort)
  125. m_pBinding->Abort();
  126. return S_OK;
  127. }
  128. STDMETHODIMP CSilentCodeDLSink::OnLowResource(DWORD reserved)
  129. {
  130. if (m_fAbort)
  131. m_pBinding->Abort();
  132. return S_OK;
  133. }
  134. STDMETHODIMP CSilentCodeDLSink::OnProgress(
  135. ULONG ulProgress,
  136. ULONG ulProgressMax,
  137. ULONG ulStatusCode,
  138. LPCWSTR szStatusText)
  139. {
  140. if (m_fAbort)
  141. m_pBinding->Abort();
  142. return S_OK;
  143. }
  144. STDMETHODIMP CSilentCodeDLSink::OnStopBinding(
  145. HRESULT hresult,
  146. LPCWSTR szError)
  147. {
  148. if (m_pBinding)
  149. {
  150. m_pBinding->Release();
  151. m_pBinding = NULL;
  152. }
  153. if(m_hOnStopBindingEvt)
  154. SetEvent(m_hOnStopBindingEvt);
  155. return S_OK;
  156. }
  157. STDMETHODIMP CSilentCodeDLSink::GetBindInfo(
  158. DWORD* pgrfBINDF,
  159. BINDINFO* pbindInfo)
  160. {
  161. if (!pgrfBINDF || !pbindInfo || !pbindInfo->cbSize)
  162. return E_INVALIDARG;
  163. *pgrfBINDF = BINDF_ASYNCHRONOUS|BINDF_SILENTOPERATION;
  164. // clear BINDINFO but keep its size
  165. DWORD cbSize = pbindInfo->cbSize;
  166. ZeroMemory( pbindInfo, cbSize );
  167. pbindInfo->cbSize = cbSize;
  168. return S_OK;
  169. }
  170. STDMETHODIMP CSilentCodeDLSink::OnDataAvailable(
  171. DWORD grfBSCF,
  172. DWORD dwSize,
  173. FORMATETC *pformatetc,
  174. STGMEDIUM *pstgmed)
  175. {
  176. if (m_fAbort)
  177. m_pBinding->Abort();
  178. return S_OK;
  179. }
  180. STDMETHODIMP CSilentCodeDLSink::OnObjectAvailable(
  181. REFIID riid,
  182. IUnknown *punk)
  183. {
  184. return S_OK;
  185. }
  186. /******************************************************************************
  187. ICodeInstall Methods
  188. ******************************************************************************/
  189. STDMETHODIMP CSilentCodeDLSink::GetWindow(
  190. REFGUID rguidReason,
  191. HWND *phwnd)
  192. {
  193. *phwnd = (HWND)INVALID_HANDLE_VALUE;
  194. if (m_fAbort)
  195. m_pBinding->Abort();
  196. return S_FALSE;
  197. }
  198. STDMETHODIMP CSilentCodeDLSink::OnCodeInstallProblem(
  199. ULONG ulStatusCode,
  200. LPCWSTR szDestination,
  201. LPCWSTR szSource,
  202. DWORD dwReserved)
  203. {
  204. switch (ulStatusCode)
  205. {
  206. case CIP_ACCESS_DENIED:
  207. case CIP_DISK_FULL:
  208. return E_ABORT;
  209. case CIP_OLDER_VERSION_EXISTS:
  210. return S_OK; // always update
  211. case CIP_NEWER_VERSION_EXISTS:
  212. return S_FALSE; // don't update
  213. case CIP_NAME_CONFLICT:
  214. return E_ABORT;
  215. case CIP_EXE_SELF_REGISTERATION_TIMEOUT:
  216. return S_OK;
  217. case CIP_TRUST_VERIFICATION_COMPONENT_MISSING:
  218. return E_ABORT;
  219. case CIP_UNSAFE_TO_ABORT:
  220. return S_OK;
  221. default:
  222. return E_ABORT;
  223. }
  224. return S_OK;
  225. }