Using this as reference, I'm trying to create an asynchronous pluggable protocol that is only temporarily available to my app (and not registered systemwide). I'm using CoInternetGetSession
and then calling RegisterNameSpace
to do it. However, when I make the call to RegisterNameSpace
I get an AccessViolation exception: Attempting to read or write protected memory
.
Any idea what's going on?
My code looks like this:
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("00000001-0000-0000-C000-000000000046")]
[ComVisible(true)]
public interface IClassFactory
{
void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject);
void LockServer(bool fLock);
}
/* Custom class to act as a class factory that create's an instance of the protocol */
[Guid("0b9c4422-2b6e-4c2d-91b0-9016053ab1b1")]
[ComVisible(true),ClassInterface(ClassInterfaceType.AutoDispatch)]
public class PluggableProtocolFactory : IClassFactory
{
public Type AppType;
public PluggableProtocolFactory(Type t)
{
this.AppType = t;
}
public void CreateInstance(IntPtr pUnkOuter, ref Guid riid, out IntPtr ppvObject)
{
riid = ProtocolSupport.GetGuid(this.AppType);
IInternetProtocol p = Activator.CreateInstance(this.AppType) as IInternetProtocol;
ppvObject = Marshal.GetComInterfaceForObject(p, typeof(IInternetProtocol));
}
public void LockServer(bool fLock)
{
var b = fLock;
}
}
[ComVisible(true)]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b")]
public interface IInternetSession
{
void CreateBinding(); // Not Implemented
void GetCache(); // Not Implemented
void GetSessionOption(); // Not Implemented
void RegisterMimeFilter([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzType);
void RegisterNameSpace([MarshalAs(UnmanagedType.Interface)] IClassFactory pCF, ref Guid rclsid, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol,
UInt32 cPatterns, [MarshalAs(UnmanagedType.LPArray,ArraySubType=UnmanagedType.LPWStr)] string[] ppwzPatterns, UInt32 dwReserved);
void SetCache(); // Not Implemented
void SetSessionOption(); // Not Implemented
void UnregisterMimeFilter(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzType);
void UnregisterNameSpace(IClassFactory pCF, [MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol);
}
[ComVisible(false)] public interface IComRegister
{
void Register(Type t);
void Unregister(Type t);
}
[ComVisible(false), AttributeUsage(AttributeTargets.Class, AllowMultiple=true) ]
public class AsyncProtocolAttribute : Attribute, IComRegister
{
public string Name;
public string Description;
[DllImport("urlmon.dll",PreserveSig=false)]
public static extern int CoInternetGetSession(UInt32 dwSessionMode /* = 0 */, ref IInternetSession ppIInternetSession, UInt32 dwReserved /* = 0 */);
public void Register(Type t)
{
IInternetSession session = null;
CoInternetGetSession(0, ref session, 0);
Guid g = new Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B");
session.RegisterNameSpace(new PluggableProtocolFactory(t), ref g, this.Name, 0, null, 0);
}
The CreateInstance
method in PluggableProtocolFactory never gets called. (A break point there never gets hit) so something else is happening inside the RegisterNameSpace
method.
I tried running both as an administrator and a normal user. Same error in both occasions.