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.

373 lines
12 KiB

  1. // --------------------------------------------------------------------------------
  2. // htmlcset.cpp
  3. // --------------------------------------------------------------------------------
  4. #include "pch.hxx"
  5. #include <docobj.h>
  6. #include "mshtmdid.h"
  7. #include "mshtmcid.h"
  8. #include "mshtml.h"
  9. #include <BadStrFunctions.h>
  10. // --------------------------------------------------------------------------------
  11. // HTMLCSETTHREAD
  12. // --------------------------------------------------------------------------------
  13. typedef struct tagHTMLCSETTHREAD {
  14. HRESULT hrResult;
  15. IStream *pStmHtml;
  16. LPSTR pszCharset;
  17. } HTMLCSETTHREAD, *LPHTMLCSETTHREAD;
  18. // --------------------------------------------------------------------------------
  19. // Prototypes
  20. // --------------------------------------------------------------------------------
  21. class CSimpleSite : public IOleClientSite, public IDispatch, public IOleCommandTarget
  22. {
  23. public:
  24. // ----------------------------------------------------------------------------
  25. // Constructor
  26. // ----------------------------------------------------------------------------
  27. CSimpleSite(IHTMLDocument2 *pDocument)
  28. {
  29. TraceCall("CSimpleSite::CSimpleSite");
  30. Assert(pDocument);
  31. m_cRef = 1;
  32. m_pDocument = pDocument;
  33. m_pszCharset = NULL;
  34. }
  35. // ----------------------------------------------------------------------------
  36. // Deconstructor
  37. // ----------------------------------------------------------------------------
  38. ~CSimpleSite(void)
  39. {
  40. TraceCall("CSimpleSite::~CSimpleSite");
  41. SafeMemFree(m_pszCharset);
  42. }
  43. // ----------------------------------------------------------------------------
  44. // IUnknown
  45. // ----------------------------------------------------------------------------
  46. STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
  47. STDMETHODIMP_(ULONG) AddRef(void);
  48. STDMETHODIMP_(ULONG) Release(void);
  49. // ----------------------------------------------------------------------------
  50. // IOleClientSite methods.
  51. // ----------------------------------------------------------------------------
  52. STDMETHODIMP SaveObject(void) { return E_NOTIMPL; }
  53. STDMETHODIMP GetMoniker(DWORD, DWORD, LPMONIKER *) { return E_NOTIMPL; }
  54. STDMETHODIMP GetContainer(LPOLECONTAINER *) { return E_NOTIMPL; }
  55. STDMETHODIMP ShowObject(void) { return E_NOTIMPL; }
  56. STDMETHODIMP OnShowWindow(BOOL) { return E_NOTIMPL; }
  57. STDMETHODIMP RequestNewObjectLayout(void) { return E_NOTIMPL; }
  58. // ----------------------------------------------------------------------------
  59. // IDispatch
  60. // ----------------------------------------------------------------------------
  61. STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) { return E_NOTIMPL; }
  62. STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo) { return E_NOTIMPL; }
  63. STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid) { return E_NOTIMPL; }
  64. STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr);
  65. // ----------------------------------------------------------------------------
  66. // IOleCommandTarget
  67. // ----------------------------------------------------------------------------
  68. STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { return E_NOTIMPL; }
  69. STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut);
  70. private:
  71. // ----------------------------------------------------------------------------
  72. // Privates
  73. // ----------------------------------------------------------------------------
  74. LONG m_cRef;
  75. IHTMLDocument2 *m_pDocument;
  76. public:
  77. // ----------------------------------------------------------------------------
  78. // Publics
  79. // ----------------------------------------------------------------------------
  80. LPSTR m_pszCharset;
  81. };
  82. // --------------------------------------------------------------------------------
  83. // Prototypes
  84. // --------------------------------------------------------------------------------
  85. DWORD GetHtmlCharsetThreadEntry(LPDWORD pdwParam);
  86. // --------------------------------------------------------------------------------
  87. // GetHtmlCharset
  88. // --------------------------------------------------------------------------------
  89. HRESULT GetHtmlCharset(IStream *pStmHtml, LPSTR *ppszCharset)
  90. {
  91. // Locals
  92. HRESULT hr=S_OK;
  93. HTHREAD hThread=NULL;
  94. DWORD dwThreadId;
  95. HTMLCSETTHREAD Thread;
  96. // Trace
  97. TraceCall("GetHtmlCharset");
  98. // Invalid Arg
  99. if (NULL == pStmHtml || NULL == ppszCharset)
  100. return TraceResult(E_INVALIDARG);
  101. // Init
  102. *ppszCharset = NULL;
  103. // Initialize the Structure
  104. ZeroMemory(&Thread, sizeof(HTMLCSETTHREAD));
  105. // Initialize
  106. Thread.hrResult = S_OK;
  107. Thread.pStmHtml = pStmHtml;
  108. // Rewind it
  109. IF_FAILEXIT(hr = HrRewindStream(pStmHtml));
  110. // Create the inetmail thread
  111. hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetHtmlCharsetThreadEntry, &Thread, 0, &dwThreadId);
  112. if (NULL == hThread)
  113. {
  114. hr = TraceResult(E_OUTOFMEMORY);
  115. goto exit;
  116. }
  117. // Wait for SpoolEngineThreadEntry to signal the event
  118. WaitForSingleObject(hThread, INFINITE);
  119. // Failure
  120. if (FAILED(Thread.hrResult))
  121. {
  122. hr = TraceResult(Thread.hrResult);
  123. goto exit;
  124. }
  125. // Null pszCharset ?
  126. if (NULL == Thread.pszCharset)
  127. {
  128. hr = TraceResult(E_OUTOFMEMORY);
  129. goto exit;
  130. }
  131. // Return the object
  132. *ppszCharset = Thread.pszCharset;
  133. exit:
  134. // Cleanup
  135. if (hThread)
  136. CloseHandle(hThread);
  137. // Done
  138. return(hr);
  139. }
  140. // --------------------------------------------------------------------------------
  141. // GetHtmlCharsetThreadEntry
  142. // --------------------------------------------------------------------------------
  143. DWORD GetHtmlCharsetThreadEntry(LPDWORD pdwParam)
  144. {
  145. // Locals
  146. HRESULT hr=S_OK;
  147. MSG msg;
  148. CSimpleSite *pSite=NULL;
  149. IHTMLDocument2 *pDocument=NULL;
  150. IOleObject *pOleObject=NULL;
  151. IOleCommandTarget *pTarget=NULL;
  152. IPersistStreamInit *pPersist=NULL;
  153. LPHTMLCSETTHREAD pThread=(LPHTMLCSETTHREAD)pdwParam;
  154. // Trace
  155. TraceCall("GetHtmlCharsetThreadEntry");
  156. // Initialize COM
  157. hr = CoInitialize(NULL);
  158. if (FAILED(hr))
  159. {
  160. pThread->hrResult = hr;
  161. return(0);
  162. }
  163. // Create me a trident
  164. IF_FAILEXIT(hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IHTMLDocument2, (LPVOID *)&pDocument));
  165. // Create Site
  166. IF_NULLEXIT(pSite = new CSimpleSite(pDocument));
  167. // Get Command Target
  168. IF_FAILEXIT(hr = pDocument->QueryInterface(IID_IOleCommandTarget, (LPVOID *)&pTarget));
  169. // Get the OLE object interface from trident
  170. IF_FAILEXIT(hr = pTarget->QueryInterface(IID_IOleObject, (LPVOID *)&pOleObject));
  171. // Set the client site
  172. IF_FAILEXIT(hr = pOleObject->SetClientSite((IOleClientSite *)pSite));
  173. // Get IPersistStreamInit
  174. IF_FAILEXIT(hr = pTarget->QueryInterface(IID_IPersistStreamInit, (LPVOID *)&pPersist));
  175. // Load
  176. IF_FAILEXIT(hr = pPersist->Load(pThread->pStmHtml));
  177. // Pump Messages
  178. while (GetMessage(&msg, NULL, 0, 0))
  179. {
  180. TranslateMessage(&msg);
  181. DispatchMessage(&msg);
  182. }
  183. // Kill the Site
  184. pOleObject->SetClientSite(NULL);
  185. // Get Charset
  186. pThread->pszCharset = pSite->m_pszCharset;
  187. // Don't Free It
  188. pSite->m_pszCharset = NULL;
  189. exit:
  190. // Cleanup
  191. SafeRelease(pSite);
  192. SafeRelease(pOleObject);
  193. SafeRelease(pPersist);
  194. SafeRelease(pTarget);
  195. SafeRelease(pDocument);
  196. // Return hr
  197. pThread->hrResult = hr;
  198. // Uninit ole
  199. CoUninitialize();
  200. // Done
  201. return(1);
  202. }
  203. // --------------------------------------------------------------------------------
  204. // CSimpleSite::AddRef
  205. // --------------------------------------------------------------------------------
  206. STDMETHODIMP_(ULONG) CSimpleSite::AddRef(void)
  207. {
  208. return ::InterlockedIncrement(&m_cRef);
  209. }
  210. // --------------------------------------------------------------------------------
  211. // CSimpleSite::Release
  212. // --------------------------------------------------------------------------------
  213. STDMETHODIMP_(ULONG) CSimpleSite::Release(void)
  214. {
  215. LONG cRef = 0;
  216. cRef = ::InterlockedDecrement(&m_cRef);
  217. if (0 == cRef)
  218. {
  219. delete this;
  220. return cRef;
  221. }
  222. return cRef;
  223. }
  224. // --------------------------------------------------------------------------------
  225. // CSimpleSite::QueryInterface
  226. // --------------------------------------------------------------------------------
  227. STDMETHODIMP CSimpleSite::QueryInterface(REFIID riid, LPVOID *ppv)
  228. {
  229. // Locals
  230. HRESULT hr=S_OK;
  231. // Stack
  232. TraceCall("CSimpleSite::QueryInterface");
  233. // Invalid Arg
  234. Assert(ppv);
  235. // Find IID
  236. if (IID_IUnknown == riid)
  237. *ppv = (IUnknown *)(IOleClientSite *)this;
  238. else if (IID_IOleClientSite == riid)
  239. *ppv = (IOleClientSite *)this;
  240. else if (IID_IDispatch == riid)
  241. *ppv = (IDispatch *)this;
  242. else if (IID_IOleCommandTarget == riid)
  243. *ppv = (IOleCommandTarget *)this;
  244. else
  245. {
  246. *ppv = NULL;
  247. hr = TraceResult(E_NOINTERFACE);
  248. goto exit;
  249. }
  250. // AddRef It
  251. ((IUnknown *)*ppv)->AddRef();
  252. exit:
  253. // Done
  254. return(hr);
  255. }
  256. // --------------------------------------------------------------------------------
  257. // CSimpleSite::Invoke
  258. // --------------------------------------------------------------------------------
  259. STDMETHODIMP CSimpleSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
  260. WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT *pVarResult,
  261. EXCEPINFO *pExcepInfo, UINT *puArgErr)
  262. {
  263. // Trace
  264. TraceCall("CSimpleSite::Invoke");
  265. // Only support one dispid
  266. if (dispIdMember != DISPID_AMBIENT_DLCONTROL)
  267. return(E_NOTIMPL);
  268. // Invalid arg
  269. if (NULL == pVarResult)
  270. return(E_INVALIDARG);
  271. // Set the return value
  272. pVarResult->vt = VT_I4;
  273. pVarResult->lVal = DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_DLACTIVEXCTLS | DLCTL_NO_FRAMEDOWNLOAD | DLCTL_FORCEOFFLINE;
  274. // Done
  275. return(S_OK);
  276. }
  277. // --------------------------------------------------------------------------------
  278. // CSimpleSite::Exec
  279. // --------------------------------------------------------------------------------
  280. STDMETHODIMP CSimpleSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
  281. DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
  282. {
  283. // Trace
  284. TraceCall("CSimpleSite::Exec");
  285. // Done Parsing ?
  286. if (IDM_PARSECOMPLETE == nCmdID)
  287. {
  288. // Locals
  289. BSTR bstrCharset=NULL;
  290. // Valid
  291. Assert(m_pDocument);
  292. // Get Charset
  293. if (SUCCEEDED(m_pDocument->get_charset(&bstrCharset)) && bstrCharset)
  294. {
  295. // Validate
  296. Assert(NULL == m_pszCharset);
  297. // Convert to ansi
  298. m_pszCharset = PszToANSI(CP_ACP, bstrCharset);
  299. // Free the bstr
  300. SysFreeString(bstrCharset);
  301. }
  302. // Done
  303. PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
  304. }
  305. // Done
  306. return(S_OK);
  307. }