.net - C# Asynchronous Pluggable Protocol wrapping default HTTP Protocol throws InvalidCastException -
in order able filter urls fetched (including js, images, etc.) c# web browser (winforms), containable option seems asynchronous pluggable protocol wrapping http (and later on others well). unfortunately fails invalidcastexception
thrown original original protocol implementation after several calls <- weird part, seems succeed several times before failing.
now code:
firstly factory protocol registered , attached:
var ep = new filteredhttpprotocolfactory(); guid id = guid.parse ("e00957bd-d0e1-4eb9-a025-7743fdc8b27b"); session.registernamespace (ep, ref id, "http", 0, null, 0);
(the factory:)
[guid ("ef474615-8079-4cfa-b114-6d1d28634dd8")] [comvisible (true)] [classinterface (classinterfacetype.none)] public class filteredhttpprotocolfactory : iclassfactory { public void createinstance (object punkouter, guid riid, out object ppvobject) { ppvobject = new filteredhttpprotocol(); } public void lockserver (bool flock) { } }
this original http protocol used ie, when using instead of wrapper works fine:
[comimport] [guid ("79eac9e2-baf9-11ce-8c82-00aa004ba90b")] public class originalhttphandler { }
this wrapper itself:
[guid ("e00957bd-d0e1-4eb9-a025-7743fdc8b27b")] [comvisible (true)] [classinterface (classinterfacetype.none)] [asyncprotocol (name = "http2", description = "blah")] public class filteredhttpprotocol : iinternetprotocol, iinternetprotocolroot { private readonly iinternetprotocol _wrapped; public filteredhttpprotocol () { var originalhttphandler = new originalhttphandler(); _wrapped = (iinternetprotocol) originalhttphandler; } public void start (string szurl, iinternetprotocolsink sink, iinternetbindinfo poibindinfo, uint grfpi, uint dwreserved) { _wrapped.start (szurl, sink, poibindinfo, grfpi, dwreserved); } public void continue (ref _tagprotocoldata pprotocoldata) { _wrapped.continue (ref pprotocoldata); // <- fails here } // .... other methods iinternetprotocol public uint read (intptr pv, uint cb, out uint pcbread) { return _wrapped.read (pv, cb, out pcbread); // <- or here } }
so, weird part is, constructor called, start()
called, read()
, continue()
called several times until whole thing fails (either read()
or continue()
) when parts of page visible (!), seems 1 specific image missing (mostly!) :
unable cast com object of type 'clients.windows.protocol.originalhttphandler' interface type 'clients.windows.protocol.iinternetprotocol'. operation failed because queryinterface call on com component interface iid '{79eac9e4-baf9-11ce-8c82-00aa004ba90b}' failed due following error: no such interface supported (exception hresult: 0x80004002 e_nointerface)).
seeing cast object said interface several times (which should result in queryinterface()
call every time, , has been called (verified through breakpoints , such) several times before fails error puzzling. looking @ ref counts ruled out object being disposed (wouldn't make sense anyway).
i have tried several things:
- google apps rare
- http://msdn.microsoft.com/en-us/library/aa767916(v=vs.85).aspx
- inheriting comimport'ed object - implementation gets ignored
- look @ ref counts
- casts of sorts
- check guids , interfaces mistakes
- asking colleagues
basically trying achieve wrap default http protocol implementation of ie filter out urls, including resources retrieved from. satisfied suitable alternatives, have compliant gplv2, deployable browser application, , no changes rest of system (i.e. no proxies).
thanks ;)
btw, going part of master's thesis here: http://desktopgap.codeplex.com
currently i'm investigating same behavior.
i have 2 ideas. first object called thread created:
method, apartment, threadid, objid -------------------- constructor: , sta, 9, #1 start: , sta, 9, #1 continue: , sta, 9, #1 read: , sta, 9, #1 read: , sta, 9, #1 lock: , sta, 9, #1 read: , sta, 9, #1 read: , sta, 9, #1 constructor: , sta, 10, #2 start: , sta, 10, #2 constructor: , sta, 10, #3 <-- notice threadid 10 terminate: , sta, 9, #1 start: , sta, 10, #3 <-- valid call constructor: , sta, 10, #4 start: , sta, 10, #4 read: , sta, 10, #4 continue: , mta, 11, #2 terminate: , sta, 10, #4 continue: , mta, 12, #3 <-- exception here!!! have new thread id of 12 , mta apartment constructor: , sta, 10, #5 start: , sta, 10, #5 constructor: , sta, 10, #6 unlock: , sta, 9, #1 start: , sta, 10, #6
second thought clr handles com calls differently in native c++. i've faced when tried utilize directshow. in case of c++ takes pointer interface , invokes function via v-table. in case of managed code queries interface first. , additional query interface call fail or return wrong object if not implemented. solution create native iuknown wrapper return pointer iinternetprotocol on queryinterface.
Comments
Post a Comment