#include "../NSimple.h" #include "../class/stdEx.h" /* Yofoo-HtmlFilter Code By Yofoo Last Edit: 2010-12-10 */ #define MIDL_DEFINE_GUID(type,name,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) / const type name = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} MIDL_DEFINE_GUID(CLSID, CLSID_HtmlFilter, 0x6F666F59, 0x2D6F, 0x7448, 0x6D, 0x6C, 0x46, 0x69, 0x6C, 0x74, 0x65, 0x72); #if 0 #define MEM_TRACE ATLTRACE #else #define MEM_TRACE __noop #endif #if 0 #define FLT_TRACE ATLTRACE #else #define FLT_TRACE __noop #endif #define FunInlineDefine {return S_OK;} class CoInterface : public IClassFactory { public: STDMETHOD(GetTypeInfoCount)(unsigned int*)FunInlineDefine STDMETHOD(GetTypeInfo)(unsigned int, LCID, ITypeInfo**)FunInlineDefine STDMETHOD(GetIDsOfNames)(REFIID, LPOLESTR*, unsigned int, LCID, DISPID*)FunInlineDefine STDMETHOD(Invoke)(DISPID, REFIID, LCID, unsigned short, DISPPARAMS*, VARIANT*, EXCEPINFO*, unsigned int*)FunInlineDefine STDMETHOD(Start)(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved)FunInlineDefine STDMETHOD(Continue)(PROTOCOLDATA *pProtocolData)FunInlineDefine STDMETHOD(Abort)(HRESULT hrReason, DWORD dwOptions)FunInlineDefine STDMETHOD(Terminate)(DWORD dwOptions)FunInlineDefine STDMETHOD(Suspend)()FunInlineDefine STDMETHOD(Resume)()FunInlineDefine STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead)FunInlineDefine STDMETHOD(Seek)(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)FunInlineDefine STDMETHOD(UnlockRequest)()FunInlineDefine STDMETHOD(LockRequest)(DWORD dwOptions)FunInlineDefine STDMETHOD (ReportData)( DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)FunInlineDefine STDMETHOD (ReportProgress)( ULONG ulStatusCode, LPCWSTR szStatusText)FunInlineDefine STDMETHOD (ReportResult)( HRESULT hrResult, DWORD dwError, LPCWSTR szResult)FunInlineDefine STDMETHOD (Switch)( PROTOCOLDATA *pProtocolData)FunInlineDefine STDMETHOD (SetPriority)(LONG nPriority)FunInlineDefine STDMETHOD (GetPriority)(LONG * pnPriority)FunInlineDefine virtual ~CoInterface(){} }; class CHtmlFilter; //#define FunInlineDefine ; #define DefAddRefFun / #define Co_AgnetFun0(_CoVar, _FunRet, _FunName) / _FunRet STDMETHODCALLTYPE _FunName()/ {/ return _CoVar->_FunName();/ } #define Co_AgnetFun1(_CoVar, _FunRet, _FunName, _P1Type, _P1) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1)/ {/ return _CoVar->_FunName(_P1);/ } #define Co_AgnetFun2(_CoVar, _FunRet, _FunName, _P1Type, _P1, _P2Type, _P2) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1, _P2Type _P2)/ {/ return _CoVar->_FunName(_P1, _P2);/ } #define Co_AgnetFun3(_CoVar, _FunRet, _FunName, _P1Type, _P1, _P2Type, _P2, _P3Type, _P3) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1, _P2Type _P2, _P3Type _P3)/ {/ return _CoVar->_FunName(_P1, _P2, _P3);/ } #define Co_AgnetFun4(_CoVar, _FunRet, _FunName, _P1Type, _P1, _P2Type, _P2, _P3Type, _P3, _P4Type, _P4) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1, _P2Type _P2, _P3Type _P3, _P4Type _P4)/ {/ return _CoVar->_FunName(_P1, _P2, _P3, _P4);/ } #define Co_AgnetFun5(_CoVar, _FunRet, _FunName, _P1Type, _P1, _P2Type, _P2, _P3Type, _P3, _P4Type, _P4, _P5Type, _P5) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1, _P2Type _P2, _P3Type _P3, _P4Type _P4, _P5Type _P5)/ {/ return _CoVar->_FunName(_P1, _P2, _P3, _P4, _P5);/ } #define Co_AgnetFun8(_CoVar, _FunRet, _FunName, _P1Type, _P1, _P2Type, _P2, _P3Type, _P3, _P4Type, _P4, _P5Type, _P5, _P6Type, _P6, _P7Type, _P7, _P8Type, _P8) / _FunRet STDMETHODCALLTYPE _FunName(_P1Type _P1, _P2Type _P2, _P3Type _P3, _P4Type _P4, _P5Type _P5, _P6Type _P6, _P7Type _P7, _P8Type _P8)/ {/ return _CoVar->_FunName(_P1, _P2, _P3, _P4, _P5, _P6, _P7, _P8);/ } #define CoAgentJmp0(_CoVar, _FunRet, _FunName) / _FunRet STDMETHODCALLTYPE _FunName()/ {/ __asm jmp _CoVar->_FunName;/ } class CHtmlFilter_IDispatch: public IDispatch { public: CHtmlFilter_IDispatch(CoInterface *pFacClass) { m_pFacClass = pFacClass; } CoInterface *m_pFacClass; Co_AgnetFun2(m_pFacClass, HRESULT, QueryInterface, REFIID, riid, LPVOID*, ppv); Co_AgnetFun0(m_pFacClass, ULONG, AddRef); Co_AgnetFun0(m_pFacClass, ULONG, Release); Co_AgnetFun1(m_pFacClass, HRESULT, GetTypeInfoCount, unsigned int*, pCount); Co_AgnetFun3(m_pFacClass, HRESULT, GetTypeInfo, unsigned int, iTInfo, LCID, lcid, ITypeInfo**, ppTInfo); Co_AgnetFun5(m_pFacClass, HRESULT, GetIDsOfNames, REFIID, riid, LPOLESTR *, rgszNames, UINT, cNames, LCID, lcid, DISPID *, rgDispId); Co_AgnetFun8(m_pFacClass, HRESULT, Invoke, DISPID, dispIdMember, REFIID, riid, LCID, lcid, WORD, wFlags, DISPPARAMS *, pDispParams, VARIANT *, pVarResult, EXCEPINFO *, pExcepInfo, UINT *, puArgErr); }; class CHtmlFilter_IInternetPriority : public IInternetPriority { public: CHtmlFilter_IInternetPriority(CoInterface *pFacClass) { m_pFacClass = pFacClass; } CoInterface *m_pFacClass; Co_AgnetFun2(m_pFacClass, HRESULT, QueryInterface, REFIID, riid, LPVOID*, ppv); Co_AgnetFun0(m_pFacClass, ULONG, AddRef); Co_AgnetFun0(m_pFacClass, ULONG, Release); Co_AgnetFun1(m_pFacClass, HRESULT, SetPriority, LONG, nPriority); Co_AgnetFun1(m_pFacClass, HRESULT, GetPriority, LONG *, pnPriority); }; class CHtmlFilter_IInternetProtocol: public IInternetProtocol { public: CHtmlFilter_IInternetProtocol(CoInterface * pFacClass) { m_pFacClass = pFacClass; } CoInterface *m_pFacClass; Co_AgnetFun2(m_pFacClass, HRESULT, QueryInterface, REFIID, riid, LPVOID*, ppv); Co_AgnetFun0(m_pFacClass, ULONG, AddRef); Co_AgnetFun0(m_pFacClass, ULONG, Release); // IInternetProtocolRoot Co_AgnetFun5(m_pFacClass, HRESULT, Start, LPCWSTR, szUrl,IInternetProtocolSink *, pOIProtSink, IInternetBindInfo *, pOIBindInfo, DWORD, grfPI, HANDLE_PTR, dwReserved); Co_AgnetFun1(m_pFacClass, HRESULT, Continue, PROTOCOLDATA *, pProtocolData); Co_AgnetFun2(m_pFacClass, HRESULT, Abort, HRESULT, hrReason, DWORD, dwOptions); Co_AgnetFun1(m_pFacClass, HRESULT, Terminate, DWORD, dwOptions); Co_AgnetFun0(m_pFacClass, HRESULT, Suspend); Co_AgnetFun0(m_pFacClass, HRESULT, Resume); // IInternetProtocol Co_AgnetFun3(m_pFacClass, HRESULT, Read, void *, pv, ULONG, cb, ULONG *, pcbRead); Co_AgnetFun3(m_pFacClass, HRESULT, Seek, LARGE_INTEGER, dlibMove, DWORD, dwOrigin, ULARGE_INTEGER *, plibNewPosition); Co_AgnetFun0(m_pFacClass, HRESULT, UnlockRequest); Co_AgnetFun1(m_pFacClass, HRESULT, LockRequest, DWORD, dwOptions); }; class CHtmlFilter_IInternetProtocolSink: public IInternetProtocolSink { public: CHtmlFilter_IInternetProtocolSink(CoInterface *pFacClass) { m_pFacClass = pFacClass; } CoInterface *m_pFacClass; Co_AgnetFun2(m_pFacClass, HRESULT, QueryInterface, REFIID, riid, LPVOID*, ppv); Co_AgnetFun0(m_pFacClass, ULONG, AddRef); Co_AgnetFun0(m_pFacClass, ULONG, Release); Co_AgnetFun3(m_pFacClass, HRESULT, ReportData, DWORD, grfBSCF, ULONG, ulProgress, ULONG, ulProgressMax); Co_AgnetFun2(m_pFacClass, HRESULT, ReportProgress, ULONG, ulStatusCode, LPCWSTR, szStatusText); Co_AgnetFun3(m_pFacClass, HRESULT, ReportResult, HRESULT, hrResult, DWORD, dwError, LPCWSTR, szResult); Co_AgnetFun1(m_pFacClass, HRESULT, Switch, PROTOCOLDATA *, pProtocolData); }; typedef enum _FilterType { Filter_namespcae = 0x1000, Filter_Mime = 0x2000 }FilterType; class CHtmlFilter: public CoInterface { public: CHtmlFilter(int nFilterType = Filter_Mime): m_xIDispatch(this), m_xIInternetProtocol(this), m_xIInternetProtocolSink(this), m_xIInternetPriority(this) { m_nRefCount = 0; m_nFilterType = nFilterType; } virtual ~CHtmlFilter() { } CHtmlFilter_IDispatch m_xIDispatch; CHtmlFilter_IInternetProtocol m_xIInternetProtocol; CHtmlFilter_IInternetProtocolSink m_xIInternetProtocolSink; CHtmlFilter_IInternetPriority m_xIInternetPriority; CComPtr<IInternetProtocol> m_UrlMonProtocol; CComPtr<IInternetProtocolSink> m_UrlMonProtocolSink; std::wstring m_sCacheFilePath; std::wstring m_sCurUrl; std::wstring m_sCurMime; LONG m_nRefCount; int m_nFilterType; STDMETHOD(QueryInterface)(REFIID riid, LPVOID* ppv) { if(IsEqualIID(riid, IID_IUnknown)) { *ppv = this; AddRef(); } else if(IsEqualIID(riid, IID_IDispatch)) { *ppv = &m_xIDispatch; } else if(IsEqualIID(riid, IID_IInternetProtocol)) { *ppv = &m_xIInternetProtocol; } else if(IsEqualIID(riid, IID_IInternetProtocolSink)) { *ppv = &m_xIInternetProtocolSink; } else if(IsEqualIID(riid, IID_IInternetPriority)) { *ppv = &m_xIInternetPriority; } else { assert(0); return ResultFromScode(E_NOINTERFACE); } AddRef(); return S_OK; } STDMETHOD_(ULONG, AddRef)() { return InterlockedIncrement(&m_nRefCount); } STDMETHOD_(ULONG, Release)() { int nRef; nRef = InterlockedDecrement(&m_nRefCount); if(nRef <= 0) { MEM_TRACE("delete: %08X/n", this); delete this; } return nRef; } virtual /* [local] */ HRESULT STDMETHODCALLTYPE CreateInstance( /* [unique][in] */ IUnknown *pUnkOuter, /* [in] */ REFIID riid, /* [iid_is][out] */ void **ppvObject) { CHtmlFilter *pFacClass; HRESULT hr; pFacClass = new CHtmlFilter(m_nFilterType); MEM_TRACE("New: %08X/n", pFacClass); hr = pFacClass->QueryInterface(riid, ppvObject); if(FAILED(hr)) delete pFacClass; return hr; } virtual /* [local] */ HRESULT STDMETHODCALLTYPE LockServer( /* [in] */ BOOL fLock) { return S_OK; } public: // IInternetProtocolRoot STDMETHOD(Start)(LPCWSTR szUrl, IInternetProtocolSink *pOIProtSink, IInternetBindInfo *pOIBindInfo, DWORD grfPI, HANDLE_PTR dwReserved) { #define OT_MAX 64 HRESULT hr; BINDINFO BdInfo; ULONG uFetched; LPOLESTR pzUrl[OT_MAX+1]; DWORD dwBdf; PROTOCOLFILTERDATA *pFiltDat; m_UrlMonProtocolSink = pOIProtSink; memset(pzUrl, 0, sizeof(pzUrl)); hr = pOIBindInfo->GetBindString(BINDSTRING_ACCEPT_MIMES, pzUrl, OT_MAX, &uFetched); if(uFetched) { if(wcscmp(pzUrl[0], L"*/*") != 0) FLT_TRACE("BINDSTRING_ACCEPT_MIMES: %S/n", pzUrl[0]); } memset(pzUrl, 0, sizeof(pzUrl)); hr = pOIBindInfo->GetBindString(BINDSTRING_USER_AGENT, pzUrl, OT_MAX, &uFetched); if(uFetched && pzUrl[0]) FLT_TRACE("BINDSTRING_USER_AGENT: %S/n", pzUrl[0]); memset(pzUrl, 0, sizeof(pzUrl)); hr = pOIBindInfo->GetBindString(BINDSTRING_POST_COOKIE, pzUrl, OT_MAX, &uFetched); if(uFetched && pzUrl[0]) FLT_TRACE("BINDSTRING_POST_COOKIE: %S/n", pzUrl[0]); memset(pzUrl, 0, sizeof(pzUrl)); hr = pOIBindInfo->GetBindString(BINDSTRING_POST_DATA_MIME, pzUrl, OT_MAX, &uFetched); if(uFetched && pzUrl[0]) FLT_TRACE("BINDSTRING_POST_DATA_MIME: %S/n", pzUrl[0]); memset(&BdInfo, 0, sizeof(BdInfo)); BdInfo.cbSize = sizeof(BdInfo); hr = pOIBindInfo->GetBindInfo(&dwBdf, &BdInfo); if(m_nFilterType & Filter_namespcae) { CHAR szCurUrl[1024]; FLT_TRACE("IInternetProtocolRoot::Start: %S/n", szUrl); return INET_E_USE_DEFAULT_PROTOCOLHANDLER; NStr::WChar2Char((WCHAR *)szUrl, szCurUrl, sizeof(szCurUrl)); if(NStr::StrTailCmp(szCurUrl, ".js") == 0 || NStr::StrTailCmp(szCurUrl, ".jpg") == 0 || NStr::StrTailCmp(szCurUrl, ".swf") == 0 || 0) { m_UrlMonProtocolSink->ReportResult(S_OK, 0, NULL); m_UrlMonProtocol.Release(); return S_OK; } return INET_E_USE_DEFAULT_PROTOCOLHANDLER; } pFiltDat = (PROTOCOLFILTERDATA *)dwReserved; hr = pOIProtSink->QueryInterface(IID_IInternetProtocol, (void**)&m_UrlMonProtocol); ClearBuffer(); memset(pzUrl, 0, sizeof(pzUrl)); m_sCurMime = szUrl; try { hr = pOIBindInfo->GetBindString(BINDSTRING_URL, pzUrl, OT_MAX, &uFetched); m_sCurUrl = pzUrl[0]; FLT_TRACE("IInternetProtocolRoot::Start: %S, %S/n", szUrl, m_sCurUrl.c_str()); } catch (CMemoryException* e) { } catch (...) { } return S_OK; } STDMETHOD(Continue)(PROTOCOLDATA * pProtocolData) { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->Continue(pProtocolData); return hr; } STDMETHOD(Abort)(HRESULT hrReason, DWORD dwOptions) { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->Abort(hrReason, dwOptions); return hr; } STDMETHOD(Terminate)(DWORD dwOptions) { if(m_nFilterType & Filter_namespcae) return S_OK; HRESULT hr; ClearBuffer(); hr = m_UrlMonProtocol->Terminate(dwOptions); return hr; } STDMETHOD(Suspend)() { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->Suspend(); return hr; } STDMETHOD(Resume)() { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->Resume(); return hr; } // IInternetProtocol ByteMem m_ReadBuffer; ByteMem m_OneBuffer; BOOL m_bReadFull; BOOL ClearBuffer() { m_ReadBuffer.clear(); m_OneBuffer.resize(16*1024); m_bReadFull = FALSE; return TRUE; } // <mce:script .... </script><!-- 替换成空格 static BOOL WINAPI LoopFindPro(CHAR *pFind, VOID *pParam) { CHAR *pEnd; int nSize; CHAR *pTailStr; pTailStr = " // --></mce:script>"; pEnd = StrStrIA(pFind, pTailStr); if(pEnd == NULL) return FALSE; nSize = (int)(pEnd - pFind + strlen(pTailStr)); memset(pFind, ' ', nSize); return TRUE; } BOOL ProcessBuffer() { WCHAR *pUrl; CHAR *pData; DWORD dwSize; dwSize = (DWORD)m_ReadBuffer.size(); m_ReadBuffer.append((BYTE *)"", 1); // 添加字符串结束标记 pData = (CHAR*)m_ReadBuffer.getptr(); pUrl = (WCHAR *)m_sCurUrl.c_str(); if(dwSize <= 0) return TRUE; if(wcsicmp(m_sCurMime.c_str(), L"text/html") != 0 && wcsicmp(m_sCurMime.c_str(), L"application/x-javascript") != 0 && wcsicmp(m_sCurMime.c_str(), L"text/css") != 0 && 1) return TRUE; if(NStr::StrHeadCmp((WCHAR *)m_sCurUrl.c_str(), L"res://") == 0) { NStr::StrReplace(pData, "宋体", "雅黑"); return TRUE; } // return TRUE; // 自己在这里处理 // NStr::LoopFindNoCaseString(LoopFindPro, pData, "<script", pData); //简单去掉脚本元素 CHAR szOld[64]; CHAR szNew[64]; int nCount; nCount = 0; nCount += NStr::StrReplace(pData, "天涯", "太阳"); // 普通编码 NStr::CodePageConvert(936, CP_UTF8, "天涯", szOld, sizeof(szOld)); NStr::CodePageConvert(936, CP_UTF8, "太阳", szNew, sizeof(szNew)); nCount += NStr::StrReplace(pData, szOld, szNew); // UTF8编码 NStr::String2HtmTranMean("天涯", szOld); NStr::String2HtmTranMean("太阳", szNew); nCount += NStr::StrReplace(pData, szOld, szNew); // Htm转义字符10进制 NStr::String2HtmTranMean("天涯", szOld, TRUE); NStr::String2HtmTranMean("太阳", szNew, TRUE); nCount += NStr::StrIReplace(pData, szOld, szNew); // Htm转义字符16进制 nCount += NStr::StrReplace(pData, "宋体", "雅黑"); // 普通编码 CHAR *pFind = strstr(pData, "宋体"); if(pFind) TRACE("Find: 宋体/n"); FLT_TRACE("Replace: %d, %S/n", nCount, m_sCurUrl.c_str()); // 处理完毕 m_ReadBuffer.pop_back(); // 删除添加的字符串结束标记 return TRUE; } BOOL RealFulltoBuffer() { HRESULT hr; DWORD dwRead; if(m_bReadFull) return TRUE; for(;;) { dwRead = 0; hr = m_UrlMonProtocol->Read(m_OneBuffer.getptr(), (ULONG)m_OneBuffer.size(), &dwRead); if(dwRead != 0) m_ReadBuffer.append(m_OneBuffer.getptr(), dwRead); if(hr == S_OK) continue; else if(hr == S_FALSE) break; else return FALSE; } m_bReadFull = TRUE; ProcessBuffer(); return TRUE; } BOOL ReadFromBuffer(void *pv, ULONG cb, ULONG *pcbRead) { if(m_ReadBuffer.size() <= 0) return FALSE; m_ReadBuffer.pop_head(pv, cb, (int *)pcbRead); return TRUE; } STDMETHOD(Read)(void *pv, ULONG cb, ULONG *pcbRead) { if(m_nFilterType & Filter_namespcae) return S_OK; // return m_UrlMonProtocol->Read(pv, cb, pcbRead); BOOL bRetVal; bRetVal = RealFulltoBuffer(); if(bRetVal == FALSE) { *pcbRead = 0; return E_PENDING; } bRetVal = ReadFromBuffer(pv, cb, pcbRead); if(bRetVal == FALSE) return S_FALSE; return S_OK; } STDMETHOD(Seek)(LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->Seek(dlibMove, dwOrigin, plibNewPosition); return hr; } STDMETHOD(UnlockRequest)() { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->UnlockRequest(); return hr; } STDMETHOD(LockRequest)(DWORD dwOptions) { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocol->LockRequest(dwOptions); return hr; } // IInternetProtocolSink STDMETHOD (ReportData)( DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax) { if(m_nFilterType & Filter_namespcae) return INET_E_USE_DEFAULT_PROTOCOLHANDLER; HRESULT hr; hr = m_UrlMonProtocolSink->ReportData(grfBSCF, ulProgress, ulProgressMax); return hr; } STDMETHOD (ReportProgress)( ULONG ulStatusCode, LPCWSTR szStatusText) { HRESULT hr; switch(ulStatusCode) { case BINDSTATUS_DECODING: FLT_TRACE("ReportProgress-BINDSTATUS_DECODING: %S/n", szStatusText); break; case BINDSTATUS_MIMETYPEAVAILABLE: FLT_TRACE("ReportProgress-BINDSTATUS_MIMETYPEAVAILABLE: %S/n", szStatusText); break; case BINDSTATUS_CACHEFILENAMEAVAILABLE: FLT_TRACE("ReportProgress-BINDSTATUS_CACHEFILENAMEAVAILABLE: %S/n", szStatusText); m_sCacheFilePath = szStatusText; break; default: FLT_TRACE("ReportProgress-Unknow: %S/n", szStatusText); } hr = m_UrlMonProtocolSink->ReportProgress(ulStatusCode, szStatusText); return hr; } STDMETHOD (ReportResult)( HRESULT hrResult, DWORD dwError, LPCWSTR szResult) { HRESULT hr; hr = m_UrlMonProtocolSink->ReportResult(hrResult, dwError, szResult); return hr; } STDMETHOD (Switch)( PROTOCOLDATA *pProtocolData) { HRESULT hr; hr = m_UrlMonProtocolSink->Switch(pProtocolData); return hr; } STDMETHOD (SetPriority)(LONG nPriority) { return S_OK; } STDMETHOD (GetPriority)(LONG * pnPriority) { return S_OK; } };