Source code of Windows XP (NT5)
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.

469 lines
12 KiB

  1. #include "webgate.h"
  2. #include "msobcomm.h"
  3. #include "commerr.h"
  4. extern CObCommunicationManager* gpCommMgr;
  5. HRESULT hrCallbackSet;
  6. /////////////////////////////////////////////////////////////////////////////
  7. // CWebGate
  8. CWebGate::CWebGate()
  9. {
  10. m_pmk = NULL;
  11. m_pstm = NULL;
  12. m_pbc = NULL;
  13. m_cRef = 0;
  14. m_bstrCacheFileName = NULL;
  15. m_hEventComplete = NULL;
  16. m_hEventError = NULL;
  17. m_bstrPath = NULL;
  18. AddRef();
  19. }
  20. CWebGate::~CWebGate()
  21. {
  22. if(m_pbc)
  23. {
  24. m_pbc->Release();
  25. m_pbc = NULL;
  26. }
  27. FlushCache();
  28. }
  29. // ---------------------------------------------------------------------------
  30. // CWebGate::QueryInterface
  31. // ---------------------------------------------------------------------------
  32. STDMETHODIMP CWebGate::QueryInterface(REFIID riid, void** ppv)
  33. {
  34. HRESULT hr = E_NOINTERFACE;
  35. *ppv = NULL;
  36. if (riid == IID_IUnknown)
  37. {
  38. AddRef();
  39. *ppv = this;
  40. hr = S_OK;
  41. }
  42. else if (riid == IID_IBindStatusCallback)
  43. {
  44. AddRef();
  45. *ppv = (IBindStatusCallback*)this;
  46. hr = S_OK;
  47. }
  48. else if (riid == IID_IHttpNegotiate)
  49. {
  50. AddRef();
  51. *ppv = (IHttpNegotiate*)this;
  52. hr = S_OK;
  53. }
  54. return hr;
  55. }
  56. // ---------------------------------------------------------------------------
  57. // CWebGate::AddRef
  58. // ---------------------------------------------------------------------------
  59. STDMETHODIMP_(ULONG) CWebGate::AddRef()
  60. {
  61. return m_cRef++;
  62. }
  63. // ---------------------------------------------------------------------------
  64. // CWebGate::Release
  65. // ---------------------------------------------------------------------------
  66. STDMETHODIMP_(ULONG) CWebGate::Release()
  67. {
  68. --m_cRef;
  69. if(m_cRef == 0)
  70. {
  71. delete this;
  72. return 0;
  73. }
  74. return m_cRef;
  75. }
  76. // ---------------------------------------------------------------------------
  77. // CWebGate::put_Path
  78. // ---------------------------------------------------------------------------
  79. STDMETHODIMP CWebGate::put_Path(BSTR newVal)
  80. {
  81. BSTR bstrTemp = SysAllocString(newVal);
  82. if (NULL == bstrTemp)
  83. {
  84. return E_OUTOFMEMORY;
  85. }
  86. if (NULL != m_bstrPath)
  87. {
  88. SysFreeString(m_bstrPath);
  89. }
  90. m_bstrPath = bstrTemp;
  91. bstrTemp = NULL;
  92. return S_OK;
  93. }
  94. void CWebGate::FlushCache()
  95. {
  96. if(m_bstrCacheFileName)
  97. {
  98. DeleteFile(m_bstrCacheFileName);
  99. SysFreeString(m_bstrCacheFileName);
  100. m_bstrCacheFileName = NULL;
  101. }
  102. }
  103. // ---------------------------------------------------------------------------
  104. // CWebGate::FetchPage
  105. // ---------------------------------------------------------------------------
  106. STDMETHODIMP CWebGate::FetchPage(DWORD dwDoWait, BOOL* pbRetVal)
  107. {
  108. HRESULT hr = E_FAIL;
  109. IStream* pstm = NULL;
  110. FlushCache();
  111. if(SUCCEEDED(CreateBindCtx(0, &m_pbc)) && m_pbc)
  112. {
  113. RegisterBindStatusCallback(m_pbc,
  114. this,
  115. 0,
  116. 0L);
  117. }
  118. if(SUCCEEDED(CreateURLMoniker(NULL, m_bstrPath, &m_pmk)) && m_pmk && m_pbc)
  119. {
  120. hr = m_pmk->BindToStorage(m_pbc, 0, IID_IStream, (void**)&pstm);
  121. m_pmk->Release();
  122. m_pmk = NULL;
  123. }
  124. if (dwDoWait)
  125. {
  126. MSG msg;
  127. DWORD dwRetCode;
  128. HANDLE hEventList[2];
  129. m_hEventComplete = CreateEvent(NULL, TRUE, FALSE, NULL);
  130. m_hEventError = CreateEvent(NULL, TRUE, FALSE, NULL);
  131. hEventList[0] = m_hEventComplete;
  132. hEventList[1] = m_hEventError;
  133. while(TRUE)
  134. {
  135. // We will wait on window messages and also the named event.
  136. dwRetCode = MsgWaitForMultipleObjects(2,
  137. &hEventList[0],
  138. FALSE,
  139. 300000, // 5 minutes
  140. QS_ALLINPUT);
  141. if(dwRetCode == WAIT_TIMEOUT)
  142. {
  143. *pbRetVal = FALSE;
  144. break;
  145. }
  146. else if(dwRetCode == WAIT_OBJECT_0)
  147. {
  148. *pbRetVal = TRUE;
  149. break;
  150. }
  151. else if(dwRetCode == WAIT_OBJECT_0 + 1)
  152. {
  153. *pbRetVal = FALSE;
  154. break;
  155. }
  156. else
  157. {
  158. if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  159. {
  160. if (WM_QUIT == msg.message)
  161. {
  162. *pbRetVal = FALSE;
  163. break;
  164. }
  165. else
  166. {
  167. TranslateMessage(&msg);
  168. DispatchMessage(&msg);
  169. }
  170. }
  171. }
  172. }
  173. CloseHandle(m_hEventComplete);
  174. CloseHandle(m_hEventError);
  175. m_hEventComplete = NULL;
  176. m_hEventError = NULL;
  177. }
  178. else
  179. *pbRetVal = TRUE;
  180. if(m_pbc)
  181. {
  182. m_pbc->Release();
  183. m_pbc = NULL;
  184. }
  185. return hr;
  186. }
  187. // ---------------------------------------------------------------------------
  188. // CWebGate::get_DownloadFname
  189. // ---------------------------------------------------------------------------
  190. STDMETHODIMP CWebGate::get_DownloadFname(BSTR *pVal)
  191. {
  192. if (pVal == NULL)
  193. return(E_POINTER);
  194. *pVal = SysAllocString(m_bstrCacheFileName);
  195. return(S_OK);
  196. }
  197. /////////////////////////////////////////////////////////////
  198. /////////////////////////////////////////////////////////////
  199. /////////////////////////////////////////////////////////////
  200. ////// IBindStatusCallback
  201. //////
  202. //////
  203. //////
  204. // ---------------------------------------------------------------------------
  205. // CWebGate::GetBindInfo
  206. // ---------------------------------------------------------------------------
  207. STDMETHODIMP CWebGate::GetBindInfo(DWORD* pgrfBINDF, BINDINFO* pbindInfo)
  208. {
  209. *pgrfBINDF = BINDF_PULLDATA |
  210. BINDF_ASYNCHRONOUS |
  211. BINDF_ASYNCSTORAGE |
  212. BINDF_GETNEWESTVERSION |
  213. BINDF_SILENTOPERATION |
  214. BINDF_NOWRITECACHE;
  215. pbindInfo->cbSize = sizeof(BINDINFO);
  216. pbindInfo->szExtraInfo = NULL;
  217. pbindInfo->grfBindInfoF = 0;
  218. pbindInfo->dwBindVerb = BINDVERB_GET;
  219. pbindInfo->szCustomVerb = NULL;
  220. memset(&pbindInfo->stgmedData, 0, sizeof(STGMEDIUM));
  221. return S_OK;
  222. }
  223. HANDLE g_hFile = NULL;
  224. int g_nOBEFileCount = 0;
  225. #define HTML_TAG_BASE_REF L"<BASE HREF=\"%s\">"
  226. // ---------------------------------------------------------------------------
  227. // CWebGate::OnStartBinding
  228. // ---------------------------------------------------------------------------
  229. STDMETHODIMP CWebGate::OnStartBinding(DWORD dwReserved, IBinding* pbinding)
  230. {
  231. WCHAR szTempFileFullName[MAX_PATH];
  232. WCHAR szTempFileName[MAX_PATH];
  233. if(g_hFile)
  234. CloseHandle(g_hFile);
  235. GetTempPath(MAX_PATH, szTempFileFullName);
  236. wsprintf( szTempFileName, L"OOBE%x.htm", g_nOBEFileCount++);
  237. lstrcat(szTempFileFullName, szTempFileName);
  238. if((g_hFile = CreateFile(szTempFileFullName,
  239. GENERIC_WRITE,
  240. 0,
  241. NULL,
  242. CREATE_ALWAYS,
  243. FILE_ATTRIBUTE_NORMAL,
  244. NULL)) == INVALID_HANDLE_VALUE)
  245. {
  246. return E_FAIL;
  247. }
  248. m_bstrCacheFileName = SysAllocString(szTempFileFullName);
  249. return S_OK;
  250. }
  251. // ---------------------------------------------------------------------------
  252. // CWebGate::OnStopBinding
  253. // ---------------------------------------------------------------------------
  254. STDMETHODIMP CWebGate::OnStopBinding(HRESULT hrStatus, LPCWSTR pszError)
  255. {
  256. if(g_hFile)
  257. {
  258. CloseHandle(g_hFile);
  259. g_hFile = NULL;
  260. }
  261. if(S_OK == hrStatus)
  262. {
  263. if(m_hEventError)
  264. SetEvent(m_hEventComplete);
  265. else
  266. gpCommMgr->Fire_DownloadComplete(m_bstrCacheFileName);
  267. }
  268. else
  269. {
  270. if(m_hEventError)
  271. SetEvent(m_hEventError);
  272. //else
  273. // PostMessage(gpCommMgr->m_hwndCallBack, WM_OBCOMM_ONSERVERERROR, (WPARAM)0, (LPARAM)ERR_COMM_SERVER_BINDFAILED);
  274. }
  275. return S_OK;
  276. }
  277. // ---------------------------------------------------------------------------
  278. // CWebGate::OnDataAvailable
  279. // ---------------------------------------------------------------------------
  280. STDMETHODIMP CWebGate::OnDataAvailable
  281. (
  282. DWORD grfBSCF,
  283. DWORD dwSize,
  284. FORMATETC* pfmtetc,
  285. STGMEDIUM* pstgmed
  286. )
  287. {
  288. HRESULT hr;
  289. DWORD dwActuallyRead = 0;
  290. DWORD dwWritten = 0;
  291. // Get the Stream passed
  292. if (BSCF_FIRSTDATANOTIFICATION & grfBSCF)
  293. {
  294. if (!m_pstm && pstgmed->tymed == TYMED_ISTREAM)
  295. {
  296. m_pstm = pstgmed->pstm;
  297. if (m_pstm)
  298. m_pstm->AddRef();
  299. }
  300. }
  301. if (m_pstm && dwSize)
  302. {
  303. BYTE* pszBuff = (BYTE*)malloc(dwSize);
  304. do
  305. {
  306. dwActuallyRead = 0;
  307. // Read what we can
  308. hr = m_pstm->Read(pszBuff, dwSize, &dwActuallyRead);
  309. if (g_hFile)
  310. {
  311. WriteFile(g_hFile, pszBuff, dwActuallyRead, &dwWritten, NULL);
  312. }
  313. } while (hr == E_PENDING || hr != S_FALSE);
  314. free(pszBuff);
  315. }
  316. if (BSCF_LASTDATANOTIFICATION & grfBSCF)
  317. {
  318. if (m_pstm)
  319. {
  320. m_pstm->Release();
  321. m_pstm = NULL;
  322. }
  323. }
  324. return S_OK;
  325. }
  326. // ---------------------------------------------------------------------------
  327. // CWebGate::OnProgress
  328. // ---------------------------------------------------------------------------
  329. STDMETHODIMP CWebGate::OnProgress(ULONG ulProgress, ULONG ulProgressMax, ULONG ulStatusCode, LPCWSTR szStatusText)
  330. {
  331. return S_OK;
  332. }
  333. // ---------------------------------------------------------------------------
  334. // CWebGate::OnObjectAvailable
  335. // ---------------------------------------------------------------------------
  336. STDMETHODIMP CWebGate::OnObjectAvailable(REFIID riid, IUnknown* punk)
  337. {
  338. return E_NOTIMPL;
  339. }
  340. // ---------------------------------------------------------------------------
  341. // CWebGate::GetPriority
  342. // ---------------------------------------------------------------------------
  343. STDMETHODIMP CWebGate::GetPriority(LONG* pnPriority)
  344. {
  345. return E_NOTIMPL;
  346. }
  347. // ---------------------------------------------------------------------------
  348. // CWebGate::OnLowResource
  349. // ---------------------------------------------------------------------------
  350. STDMETHODIMP CWebGate::OnLowResource(DWORD dwReserved)
  351. {
  352. return E_NOTIMPL;
  353. }
  354. /////////////////////////////////////////////////////////////
  355. /////////////////////////////////////////////////////////////
  356. /////////////////////////////////////////////////////////////
  357. ////// IHttpNegotiate
  358. //////
  359. //////
  360. //////
  361. // ---------------------------------------------------------------------------
  362. // CWebGate::BeginningTransaction
  363. // ---------------------------------------------------------------------------
  364. STDMETHODIMP CWebGate::BeginningTransaction
  365. (
  366. LPCWSTR szURL,
  367. LPCWSTR szHeaders,
  368. DWORD dwReserved,
  369. LPWSTR* pszAdditionalHeaders
  370. )
  371. {
  372. // Here's our opportunity to add headers
  373. if (!pszAdditionalHeaders)
  374. {
  375. return E_POINTER;
  376. }
  377. *pszAdditionalHeaders = NULL;
  378. return NOERROR;
  379. }
  380. // ---------------------------------------------------------------------------
  381. // CWebGate::BeginningTransaction
  382. // ---------------------------------------------------------------------------
  383. STDMETHODIMP CWebGate::OnResponse
  384. (
  385. DWORD dwResponseCode,
  386. LPCWSTR szResponseHeaders,
  387. LPCWSTR szRequestHeaders,
  388. LPWSTR* pszAdditionalRequestHeaders)
  389. {
  390. if (!pszAdditionalRequestHeaders)
  391. {
  392. return E_POINTER;
  393. }
  394. *pszAdditionalRequestHeaders = NULL;
  395. return NOERROR;
  396. }