I add MIME filter to my WebBrowser Control by IInternetSession.RegisterMimeFilter。 The MIME type is "text/html"。
The filter have a bug that the flash cant shown in some site such as "http://cn.yahoo.com/". I
tryed add "" before the tag,noneffective。
I return data directly but falsh still invisible。
I set the IE safe level to lowest(internet,intranet,activex). still noneffective.
If I don't register the MIME filter,the flash can shown allways。
any idea ?
[ComVisible(true)]
[Guid("1c470f4b-0486-4558-80c7-ad08d652a465"), ClassInterface(ClassInterfaceType.AutoDispatch)]
public class MimeHandler : IInternetProtocol, IInternetProtocolRoot, IInternetProtocolSink
{
const int S_OK = 0x00000000;
const int S_FALSE = 0x00000001;
const int E_FAIL = unchecked((int)0x80004005);
const int E_POINTER = unchecked((int)0x80004005);
const int INET_E_ERROR_FIRST = unchecked((int)0x800C0002);
const int INET_E_INVALID_URL = unchecked((int)0x800C0002);
const int INET_E_NO_SESSION = unchecked((int)0x800C0003);
const int INET_E_CANNOT_CONNECT = unchecked((int)0x800C0004);
const int INET_E_RESOURCE_NOT_FOUND = unchecked((int)0x800C0005);
const int INET_E_OBJECT_NOT_FOUND = unchecked((int)0x800C0006);
const int INET_E_DATA_NOT_AVAILABLE = unchecked((int)0x800C0007);
const int INET_E_DOWNLOAD_FAILURE = unchecked((int)0x800C0008);
const int INET_E_AUTHENTICATION_REQUIRED = unchecked((int)0x800C0009);
const int INET_E_NO_VALID_MEDIA = unchecked((int)0x800C000A);
const int INET_E_CONNECTION_TIMEOUT = unchecked((int)0x800C000B);
const int INET_E_INVALID_REQUEST = unchecked((int)0x800C000C);
const int INET_E_UNKNOWN_PROTOCOL = unchecked((int)0x800C000D);
const int INET_E_SECURITY_PROBLEM = unchecked((int)0x800C000E);
const int INET_E_CANNOT_LOAD_DATA = unchecked((int)0x800C000F);
const int INET_E_CANNOT_INSTANTIATE_OBJECT = unchecked((int)0x800C0010);
const int INET_E_USE_DEFAULT_PROTOCOLHANDLER = unchecked((int)0x800C0011);
const int INET_E_QUERYOPTION_UNKNOWN = unchecked((int)0x800C0013);
const int INET_E_REDIRECT_FAILED = unchecked((int)0x800C0014);
const int INET_E_REDIRECT_TO_DIR = unchecked((int)0x800C0015);
const int INET_E_CANNOT_LOCK_REQUEST = unchecked((int)0x800C0016);
private string cacheFileName = "";
private string url;
private MemoryStream dataStream = new MemoryStream();
private IInternetProtocol urlMonProtocol;
private IInternetProtocolSink urlMonProtocolSink;
private byte[] buffer = null;
private uint written = 0;
private long totalSize = 0;
protected MemoryStream Stream = new MemoryStream(0x8000);
protected byte[] StreamBuffer = new byte[0x8000];
private string MimeType = "";
private string char_set = "";
public MimeHandler()
{
}
public void Start(string szURL, IInternetProtocolSink Sink,
IInternetBindInfo pOIBindInfo, uint grfPI, uint dwReserved)
{
MimeType = szURL;
urlMonProtocol = (IInternetProtocol)Sink;
urlMonProtocolSink = Sink;
uint Fetched = 0;
const int BINDSTRING_URL = 14;
pOIBindInfo.GetBindString(BINDSTRING_URL, ref url, 1, ref Fetched);
throw new COMException("", S_OK);
}
public void ReportProgress(uint ulStatusCode, string szStatusText)
{
uint bindStatus = Convert.ToUInt32(BINDSTATUS.BINDSTATUS_CACHEFILENAMEAVAILABLE);
if (ulStatusCode == bindStatus)
{
cacheFileName = szStatusText;
}
urlMonProtocolSink.ReportProgress(ulStatusCode, szStatusText);
throw new COMException("", S_OK);
}
public void ReportData(BSCF grfBSCF, uint ulProgress, uint ulProgressMax)
{
UInt32 resultOfRead;
dataStream = new MemoryStream();
do
{ //while result == S_OK there is still data
byte[] readBuffer = new byte[1024];
uint totalRead;
int size = Marshal.SizeOf(readBuffer[0]) * readBuffer.Length;
IntPtr unmanagedPointer = Marshal.AllocHGlobal(size);
Marshal.Copy(readBuffer, 0, unmanagedPointer, readBuffer.Length);
// Call unmanaged code
resultOfRead = urlMonProtocol.Read(unmanagedPointer, Convert.ToUInt32(readBuffer.Length), out totalRead);
byte[] receiveBuffer = new byte[1024];
Marshal.Copy(unmanagedPointer, receiveBuffer, 0, 1024);
dataStream.Write(receiveBuffer, 0, Convert.ToInt32(totalRead));
//free memory
Marshal.FreeHGlobal(unmanagedPointer);
} //while (resultOfRead == HRESULT.S_OK);
while ((resultOfRead != S_FALSE) &&
(resultOfRead != INET_E_DOWNLOAD_FAILURE) && (resultOfRead != INET_E_DATA_NOT_AVAILABLE));
if (resultOfRead == HRESULT.S_FALSE)
{
//all data recieved
dataStream.Flush();
totalSize = dataStream.Length;
//INSERT MANIPULATION OF DATA!
HandleData();
urlMonProtocolSink.ReportData(
BSCF.BSCF_FIRSTDATANOTIFICATION |
BSCF.BSCF_LASTDATANOTIFICATION |
BSCF.BSCF_DATAFULLYAVAILABLE, Convert.ToUInt32(totalSize), Convert.ToUInt32(totalSize));
urlMonProtocolSink.ReportResult(Convert.ToInt32(HRESULT.S_OK), HRESULT.S_OK, null);
}
throw new COMException("", S_OK);
}
public UInt32 Read(System.IntPtr pv, uint cb, out uint pcbRead)
{
pcbRead = 0;
if (written < totalSize)
{
if (totalSize - written <= cb)
{
Marshal.Copy(buffer, (int)written, pv, (int)(totalSize - written));
pcbRead = (uint)(totalSize - written);
written += (uint)(totalSize - written);
return (UInt32)S_FALSE;
}
else
{
Marshal.Copy(buffer, (int)written, pv, (int)cb);
written += cb;
pcbRead = cb;
return (UInt32)S_OK;
}
}
else
{ return (UInt32)S_FALSE; }
}
public void Resume()
{
urlMonProtocol.Resume();
throw new COMException("", unchecked((int)0x80004001));
}
public void Terminate(uint dwOptions)
{
urlMonProtocol.Terminate(dwOptions);
throw new COMException("", S_OK);
}
public void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out _ULARGE_INTEGER plibNewPosition)
{
urlMonProtocol.Seek(dlibMove, dwOrigin, out plibNewPosition);
throw new COMException("", S_OK);
}
public void LockRequest(uint dwOptions)
{
urlMonProtocol.LockRequest(dwOptions);
throw new COMException("", S_OK);
}
public void UnlockRequest()
{
urlMonProtocol.UnlockRequest();
throw new COMException("", S_OK);
}
public void Abort(int hrReason, uint dwOptions)
{
urlMonProtocol.Abort(hrReason, dwOptions);
throw new COMException("", S_OK);
}
public void Suspend()
{
urlMonProtocol.Suspend();
throw new COMException("", unchecked((int)0x80004001));
}
public void Continue(ref _tagPROTOCOLDATA pProtocolData)
{
urlMonProtocol.Continue(ref pProtocolData);
throw new COMException("", S_OK);
}
public void Switch(ref _tagPROTOCOLDATA pProtocolData)
{
urlMonProtocolSink.Switch(ref pProtocolData);
throw new COMException("", S_OK);
}
public void ReportResult(int hrResult, uint dwError, string szResult)
{
urlMonProtocolSink.ReportResult(hrResult, dwError, szResult);
throw new COMException("", S_OK);
}
public static IHttpNegotiate GetHttpNegotiate(IInternetProtocolSink Sink)
{
if ((Sink is IServiceProvider) == false)
throw new Exception("Error ProtocolSink does not support IServiceProvider.");
IServiceProvider Provider = (IServiceProvider) Sink;
object obj_Negotiate = new object();
Provider.QueryService(ref Guids.IID_IHttpNegotiate, ref Guids.IID_IHttpNegotiate, out obj_Negotiate);
return (IHttpNegotiate) obj_Negotiate;
}
public static BINDINFO GetBindInfo(IInternetBindInfo pOIBindInfo)
{
BINDINFO BindInfo = new BINDINFO();
BindInfo.cbSize = (UInt32) Marshal.SizeOf(typeof (BINDINFO));
UInt32 AsyncFlag;
pOIBindInfo.GetBindInfo(out AsyncFlag, ref BindInfo);
return BindInfo;
}
private void HandleData()
{
buffer = new byte[(int)dataStream.Length];
dataStream.Seek(0, SeekOrigin.Begin);
dataStream.Read(buffer, 0, buffer.Length);
written = 0;
totalSize = buffer.Length;
/*
string content = BytesToString(buffer, out char_set);
if (this.MimeType.IndexOf("javascript",StringComparison.OrdinalIgnoreCase) != -1)
{
}
else if (this.MimeType.IndexOf("html", StringComparison.OrdinalIgnoreCase) != -1)
{
Regex reg_first = new Regex("<!DOCTYPE[^>]+?>",RegexOptions.IgnoreCase);
Match m = reg_first.Match(content);
if(m.Success)
{
int head = content.IndexOf(m.Value,StringComparison.OrdinalIgnoreCase);
if (head != -1)
{
string l = url.Length.ToString();
while (l.Length < 4)
{
l = "0" + l;
}
l = "(" + l + ")" + url;
content = content.Substring(0, head + m.Value.Length) +
"\r\n <!-- saved from url=" + l + " --> " +
content.Substring(head + m.Value.Length);
}
}
}
byte[] data = StringToBytes(content, char_set);
dataStream = new MemoryStream(data);
buffer = new byte[(int)dataStream.Length];
dataStream.Seek(0, SeekOrigin.Begin);
dataStream.Read(buffer, 0, buffer.Length);
written = 0;
totalSize = buffer.Length;*/
}
private string BytesToString(byte[] data,out string charSet)
{
charSet = "";
string sHtml = Encoding.Default.GetString(data);
string CharSet = "";
Regex rg = new Regex("<meta.+?charset=(?<name>.*?)\".*?>", RegexOptions.IgnoreCase);
Match m = rg.Match(sHtml);
if(m.Success)
{
CharSet = m.Groups["name"].Value;
charSet = CharSet;
}
if (CharSet.Length > 0)
{
sHtml = Encoding.GetEncoding(CharSet).GetString(data);
}
return sHtml;
}
private byte[] StringToBytes(string text,string charSet)
{
if (charSet.Length > 0)
{ return Encoding.GetEncoding(charSet).GetBytes(text); }
else
{ return Encoding.Default.GetBytes(text); }
}
}
I have resolve this question.
[ComVisible(true)]
[Guid("1c470f4b-0486-4558-80c7-ad08d652a465"), ClassInterface(ClassInterfaceType.AutoDispatch)]
public class MimeHandler : IInternetProtocol, IInternetProtocolRoot, IInternetProtocolSink
{
.......
//private static ArrayList not = new ArrayList();
private static string newUrl = "";
public static string NewUrl //set it berfor Navigate
{
get
{ return newUrl; }
set
{
newUrl = value;
not.Clear();
}
}
private void HandleData()
{
buffer = new byte[(int)dataStream.Length];
dataStream.Seek(0, SeekOrigin.Begin);
dataStream.Read(buffer, 0, buffer.Length);
written = 0;
totalSize = buffer.Length;
string content = BytesToString(buffer, out char_set);
if(string.Equals(url,newUrl))
{
Regex reg_js = new Regex("(?<head><script[^<>]+src=\"*)(?<url>[^\"\\s>]+)(?<end>\"*[^<>]*>\\s*</script>)", RegexOptions.IgnoreCase);
MatchCollection mc_js = reg_js.Matches(content);
foreach (Match m in mc_js)
{
if (!m.Groups["url"].Value.EndsWith(".js",StringComparison.OrdinalIgnoreCase))
{ not.Add(m.Groups["url"].Value); }
}
}
byte[] data = StringToBytes(content, char_set);
dataStream = new MemoryStream(data);
buffer = new byte[(int)dataStream.Length];
dataStream.Seek(0, SeekOrigin.Begin);
dataStream.Read(buffer, 0, buffer.Length);
written = 0;
totalSize = buffer.Length;
}
public void Start(string szURL, IInternetProtocolSink Sink,
IInternetBindInfo pOIBindInfo, uint grfPI, uint dwReserved)
{
uint Fetched = 0;
const int BINDSTRING_URL = 14;
pOIBindInfo.GetBindString(BINDSTRING_URL, ref url, 1, ref Fetched);
for (int i = 0; i < not.Count;++i )
{
Regex reg_end = new Regex("\\.html?$");
string t = (string)not[i];
if (string.Equals(reg_end.Replace(t, ""), reg_end.Replace(url, "")))
{
throw new COMException("", INET_E_USE_DEFAULT_PROTOCOLHANDLER);
}
}
MimeType = szURL;
urlMonProtocol = (IInternetProtocol)Sink;
urlMonProtocolSink = Sink;
//System.IO.File.AppendAllText("C:\\url.txt", url + "\r\n");
throw new COMException("", S_OK);
}
//.......
}
I don't know why the data still error when I return data directly . Now I have to use "throw new COMException("", INET_E_USE_DEFAULT_PROTOCOLHANDLER)" in Start. In this way flash can shown.
User contributions licensed under CC BY-SA 3.0