-
-
[旧帖] 关于异步可插入协议中Mime Filter过滤器的报错问题,有代码,请高手帮忙 0.00雪花
-
发表于: 2011-8-2 23:47 3232
-
由于要对IE下载的内容作过滤,查了很多资料,最后发现异步可插入协议的Pluggable Mime Filter是我所需要的,于是继续着相关资料,居然有人已经完整的实现了,真是太高兴了,这下可以省一些时间,不过在接下来的时间我才发现我之前的想法完全错误了,这个网上找到的Demo是对text/html作过滤的,在IInternetProtocolSink接口的ReportDate方法处对收到的内容进行加工,研究了几天,原理基本算搞懂了,也对下载的Demo作了不少的测试,最后发现这个demo在应对某些页面时会卡死或报错,主要有两种表现,1.在打开tieba.baidu.com时程序运行到ReportResult时,就不在执行下面的代码,也不报错,直接卡死,2.点击QQ空间里面的“添加应用”按钮时,程序报错。
程序运行环境是winxp下的IE6浏览器,初步分析发现可能和javascript有关系,因为tieba.baidu.com在下载网页的过程中有调用javascript的URL,QQ空间里面那个按钮也是javascript,虽然是这样思考,但是又没有可以修改的入手方法,特来请教对该技术有一定认识的高手帮忙。下面贴上IInternetProtocolSink接口的ReportDate方法代码和完整代码的下载地址。
//IInternetProtocolSink
STDMETHODIMP CHTMLFilter::ReportData( DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
USES_CONVERSION;
CString Ts("");
char p[1024];
HRESULT hr;
ULONG Readtotal;
do
{
memset(p,0,sizeof(p));
hr = UrlMonProtocol->Read(p, sizeof(p)-1, &Readtotal);
//p[Readtotal]='\0';
CString pTemp(p);
Ts=Ts+pTemp;
}while((hr != S_FALSE));// && (hr != INET_E_DOWNLOAD_FAILURE) && (hr != INET_E_DATA_NOT_AVAILABLE));
if(hr == S_FALSE)
{
CString FName="D:/test/";
CString tempFile=URL_Code(Url);
FName+=tempFile;
CFile hFile;
hFile.Open(FName, CFile::modeCreate|CFile::modeWrite);
hFile.Write(Ts,Ts.GetLength());
//ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE, T2W(FName));
TotalSize= Ts.GetLength() ;
//CreateStreamOnHGlobal(0, true, &DataStream);
const char * pTs = Ts.GetBuffer(Ts.GetLength());
ULONG cbWritten;
DataStream->Write(pTs,Ts.GetLength(),&cbWritten);
Ts.ReleaseBuffer();
pTs = NULL;
ULARGE_INTEGER Dummy;
_LARGE_INTEGER zero;
zero.QuadPart =0;
DataStream->Seek ( zero, STREAM_SEEK_SET, &Dummy);
UrlMonProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
TotalSize, TotalSize);
UrlMonProtocolSink->ReportResult(S_OK, S_OK, NULL);
}
else
{
Abort(hr, 0);
}
return S_OK;
}
程序运行环境是winxp下的IE6浏览器,初步分析发现可能和javascript有关系,因为tieba.baidu.com在下载网页的过程中有调用javascript的URL,QQ空间里面那个按钮也是javascript,虽然是这样思考,但是又没有可以修改的入手方法,特来请教对该技术有一定认识的高手帮忙。下面贴上IInternetProtocolSink接口的ReportDate方法代码和完整代码的下载地址。
//IInternetProtocolSink
STDMETHODIMP CHTMLFilter::ReportData( DWORD grfBSCF, ULONG ulProgress, ULONG ulProgressMax)
{
USES_CONVERSION;
CString Ts("");
char p[1024];
HRESULT hr;
ULONG Readtotal;
do
{
memset(p,0,sizeof(p));
hr = UrlMonProtocol->Read(p, sizeof(p)-1, &Readtotal);
//p[Readtotal]='\0';
CString pTemp(p);
Ts=Ts+pTemp;
}while((hr != S_FALSE));// && (hr != INET_E_DOWNLOAD_FAILURE) && (hr != INET_E_DATA_NOT_AVAILABLE));
if(hr == S_FALSE)
{
CString FName="D:/test/";
CString tempFile=URL_Code(Url);
FName+=tempFile;
CFile hFile;
hFile.Open(FName, CFile::modeCreate|CFile::modeWrite);
hFile.Write(Ts,Ts.GetLength());
//ReportProgress(BINDSTATUS_CACHEFILENAMEAVAILABLE, T2W(FName));
TotalSize= Ts.GetLength() ;
//CreateStreamOnHGlobal(0, true, &DataStream);
const char * pTs = Ts.GetBuffer(Ts.GetLength());
ULONG cbWritten;
DataStream->Write(pTs,Ts.GetLength(),&cbWritten);
Ts.ReleaseBuffer();
pTs = NULL;
ULARGE_INTEGER Dummy;
_LARGE_INTEGER zero;
zero.QuadPart =0;
DataStream->Seek ( zero, STREAM_SEEK_SET, &Dummy);
UrlMonProtocolSink->ReportData(BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION | BSCF_DATAFULLYAVAILABLE,
TotalSize, TotalSize);
UrlMonProtocolSink->ReportResult(S_OK, S_OK, NULL);
}
else
{
Abort(hr, 0);
}
return S_OK;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: