Windows2003-3790/inetcore/outlookexpress/msoert/htmlcset.cpp
2020-09-30 16:53:55 +02:00

374 lines
12 KiB
C++

// --------------------------------------------------------------------------------
// htmlcset.cpp
// --------------------------------------------------------------------------------
#include "pch.hxx"
#include <docobj.h>
#include "mshtmdid.h"
#include "mshtmcid.h"
#include "mshtml.h"
#include <BadStrFunctions.h>
// --------------------------------------------------------------------------------
// HTMLCSETTHREAD
// --------------------------------------------------------------------------------
typedef struct tagHTMLCSETTHREAD {
HRESULT hrResult;
IStream *pStmHtml;
LPSTR pszCharset;
} HTMLCSETTHREAD, *LPHTMLCSETTHREAD;
// --------------------------------------------------------------------------------
// Prototypes
// --------------------------------------------------------------------------------
class CSimpleSite : public IOleClientSite, public IDispatch, public IOleCommandTarget
{
public:
// ----------------------------------------------------------------------------
// Constructor
// ----------------------------------------------------------------------------
CSimpleSite(IHTMLDocument2 *pDocument)
{
TraceCall("CSimpleSite::CSimpleSite");
Assert(pDocument);
m_cRef = 1;
m_pDocument = pDocument;
m_pszCharset = NULL;
}
// ----------------------------------------------------------------------------
// Deconstructor
// ----------------------------------------------------------------------------
~CSimpleSite(void)
{
TraceCall("CSimpleSite::~CSimpleSite");
SafeMemFree(m_pszCharset);
}
// ----------------------------------------------------------------------------
// IUnknown
// ----------------------------------------------------------------------------
STDMETHODIMP QueryInterface(REFIID, LPVOID FAR *);
STDMETHODIMP_(ULONG) AddRef(void);
STDMETHODIMP_(ULONG) Release(void);
// ----------------------------------------------------------------------------
// IOleClientSite methods.
// ----------------------------------------------------------------------------
STDMETHODIMP SaveObject(void) { return E_NOTIMPL; }
STDMETHODIMP GetMoniker(DWORD, DWORD, LPMONIKER *) { return E_NOTIMPL; }
STDMETHODIMP GetContainer(LPOLECONTAINER *) { return E_NOTIMPL; }
STDMETHODIMP ShowObject(void) { return E_NOTIMPL; }
STDMETHODIMP OnShowWindow(BOOL) { return E_NOTIMPL; }
STDMETHODIMP RequestNewObjectLayout(void) { return E_NOTIMPL; }
// ----------------------------------------------------------------------------
// IDispatch
// ----------------------------------------------------------------------------
STDMETHODIMP GetTypeInfoCount(UINT *pctinfo) { return E_NOTIMPL; }
STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo) { return E_NOTIMPL; }
STDMETHODIMP GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid) { return E_NOTIMPL; }
STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr);
// ----------------------------------------------------------------------------
// IOleCommandTarget
// ----------------------------------------------------------------------------
STDMETHODIMP QueryStatus(const GUID *pguidCmdGroup, ULONG cCmds, OLECMD prgCmds[], OLECMDTEXT *pCmdText) { return E_NOTIMPL; }
STDMETHODIMP Exec(const GUID *pguidCmdGroup, DWORD nCmdID, DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut);
private:
// ----------------------------------------------------------------------------
// Privates
// ----------------------------------------------------------------------------
LONG m_cRef;
IHTMLDocument2 *m_pDocument;
public:
// ----------------------------------------------------------------------------
// Publics
// ----------------------------------------------------------------------------
LPSTR m_pszCharset;
};
// --------------------------------------------------------------------------------
// Prototypes
// --------------------------------------------------------------------------------
DWORD GetHtmlCharsetThreadEntry(LPDWORD pdwParam);
// --------------------------------------------------------------------------------
// GetHtmlCharset
// --------------------------------------------------------------------------------
HRESULT GetHtmlCharset(IStream *pStmHtml, LPSTR *ppszCharset)
{
// Locals
HRESULT hr=S_OK;
HTHREAD hThread=NULL;
DWORD dwThreadId;
HTMLCSETTHREAD Thread;
// Trace
TraceCall("GetHtmlCharset");
// Invalid Arg
if (NULL == pStmHtml || NULL == ppszCharset)
return TraceResult(E_INVALIDARG);
// Init
*ppszCharset = NULL;
// Initialize the Structure
ZeroMemory(&Thread, sizeof(HTMLCSETTHREAD));
// Initialize
Thread.hrResult = S_OK;
Thread.pStmHtml = pStmHtml;
// Rewind it
IF_FAILEXIT(hr = HrRewindStream(pStmHtml));
// Create the inetmail thread
hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)GetHtmlCharsetThreadEntry, &Thread, 0, &dwThreadId);
if (NULL == hThread)
{
hr = TraceResult(E_OUTOFMEMORY);
goto exit;
}
// Wait for SpoolEngineThreadEntry to signal the event
WaitForSingleObject(hThread, INFINITE);
// Failure
if (FAILED(Thread.hrResult))
{
hr = TraceResult(Thread.hrResult);
goto exit;
}
// Null pszCharset ?
if (NULL == Thread.pszCharset)
{
hr = TraceResult(E_OUTOFMEMORY);
goto exit;
}
// Return the object
*ppszCharset = Thread.pszCharset;
exit:
// Cleanup
if (hThread)
CloseHandle(hThread);
// Done
return(hr);
}
// --------------------------------------------------------------------------------
// GetHtmlCharsetThreadEntry
// --------------------------------------------------------------------------------
DWORD GetHtmlCharsetThreadEntry(LPDWORD pdwParam)
{
// Locals
HRESULT hr=S_OK;
MSG msg;
CSimpleSite *pSite=NULL;
IHTMLDocument2 *pDocument=NULL;
IOleObject *pOleObject=NULL;
IOleCommandTarget *pTarget=NULL;
IPersistStreamInit *pPersist=NULL;
LPHTMLCSETTHREAD pThread=(LPHTMLCSETTHREAD)pdwParam;
// Trace
TraceCall("GetHtmlCharsetThreadEntry");
// Initialize COM
hr = CoInitialize(NULL);
if (FAILED(hr))
{
pThread->hrResult = hr;
return(0);
}
// Create me a trident
IF_FAILEXIT(hr = CoCreateInstance(CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, IID_IHTMLDocument2, (LPVOID *)&pDocument));
// Create Site
IF_NULLEXIT(pSite = new CSimpleSite(pDocument));
// Get Command Target
IF_FAILEXIT(hr = pDocument->QueryInterface(IID_IOleCommandTarget, (LPVOID *)&pTarget));
// Get the OLE object interface from trident
IF_FAILEXIT(hr = pTarget->QueryInterface(IID_IOleObject, (LPVOID *)&pOleObject));
// Set the client site
IF_FAILEXIT(hr = pOleObject->SetClientSite((IOleClientSite *)pSite));
// Get IPersistStreamInit
IF_FAILEXIT(hr = pTarget->QueryInterface(IID_IPersistStreamInit, (LPVOID *)&pPersist));
// Load
IF_FAILEXIT(hr = pPersist->Load(pThread->pStmHtml));
// Pump Messages
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Kill the Site
pOleObject->SetClientSite(NULL);
// Get Charset
pThread->pszCharset = pSite->m_pszCharset;
// Don't Free It
pSite->m_pszCharset = NULL;
exit:
// Cleanup
SafeRelease(pSite);
SafeRelease(pOleObject);
SafeRelease(pPersist);
SafeRelease(pTarget);
SafeRelease(pDocument);
// Return hr
pThread->hrResult = hr;
// Uninit ole
CoUninitialize();
// Done
return(1);
}
// --------------------------------------------------------------------------------
// CSimpleSite::AddRef
// --------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CSimpleSite::AddRef(void)
{
return ::InterlockedIncrement(&m_cRef);
}
// --------------------------------------------------------------------------------
// CSimpleSite::Release
// --------------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CSimpleSite::Release(void)
{
LONG cRef = 0;
cRef = ::InterlockedDecrement(&m_cRef);
if (0 == cRef)
{
delete this;
return cRef;
}
return cRef;
}
// --------------------------------------------------------------------------------
// CSimpleSite::QueryInterface
// --------------------------------------------------------------------------------
STDMETHODIMP CSimpleSite::QueryInterface(REFIID riid, LPVOID *ppv)
{
// Locals
HRESULT hr=S_OK;
// Stack
TraceCall("CSimpleSite::QueryInterface");
// Invalid Arg
Assert(ppv);
// Find IID
if (IID_IUnknown == riid)
*ppv = (IUnknown *)(IOleClientSite *)this;
else if (IID_IOleClientSite == riid)
*ppv = (IOleClientSite *)this;
else if (IID_IDispatch == riid)
*ppv = (IDispatch *)this;
else if (IID_IOleCommandTarget == riid)
*ppv = (IOleCommandTarget *)this;
else
{
*ppv = NULL;
hr = TraceResult(E_NOINTERFACE);
goto exit;
}
// AddRef It
((IUnknown *)*ppv)->AddRef();
exit:
// Done
return(hr);
}
// --------------------------------------------------------------------------------
// CSimpleSite::Invoke
// --------------------------------------------------------------------------------
STDMETHODIMP CSimpleSite::Invoke(DISPID dispIdMember, REFIID riid, LCID lcid,
WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT *pVarResult,
EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
// Trace
TraceCall("CSimpleSite::Invoke");
// Only support one dispid
if (dispIdMember != DISPID_AMBIENT_DLCONTROL)
return(E_NOTIMPL);
// Invalid arg
if (NULL == pVarResult)
return(E_INVALIDARG);
// Set the return value
pVarResult->vt = VT_I4;
pVarResult->lVal = DLCTL_NO_SCRIPTS | DLCTL_NO_JAVA | DLCTL_NO_RUNACTIVEXCTLS | DLCTL_NO_DLACTIVEXCTLS | DLCTL_NO_FRAMEDOWNLOAD | DLCTL_FORCEOFFLINE;
// Done
return(S_OK);
}
// --------------------------------------------------------------------------------
// CSimpleSite::Exec
// --------------------------------------------------------------------------------
STDMETHODIMP CSimpleSite::Exec(const GUID *pguidCmdGroup, DWORD nCmdID,
DWORD nCmdExecOpt, VARIANTARG *pvaIn, VARIANTARG *pvaOut)
{
// Trace
TraceCall("CSimpleSite::Exec");
// Done Parsing ?
if (IDM_PARSECOMPLETE == nCmdID)
{
// Locals
BSTR bstrCharset=NULL;
// Valid
Assert(m_pDocument);
// Get Charset
if (SUCCEEDED(m_pDocument->get_charset(&bstrCharset)) && bstrCharset)
{
// Validate
Assert(NULL == m_pszCharset);
// Convert to ansi
m_pszCharset = PszToANSI(CP_ACP, bstrCharset);
// Free the bstr
SysFreeString(bstrCharset);
}
// Done
PostThreadMessage(GetCurrentThreadId(), WM_QUIT, 0, 0);
}
// Done
return(S_OK);
}