title: Asynchronous Pluggable Protocols
body: <p>Using  <a href="http://www.codeproject.com/KB/aspnet/AspxProtocol.aspx" rel="nofollow noreferrer">this</a> 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 <code>CoInternetGetSession</code> and then calling <code>RegisterNameSpace</code> to do it. However, when I make the call to <code>RegisterNameSpace</code> I get an AccessViolation exception: <code>Attempting to read or write protected memory</code>.</p>
  
  <p>Any idea what's going on?</p>
  
  <p>My code looks like this:</p>
  
  <pre><code>[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);
  
      }
  </code></pre>
  
  <p>The <code>CreateInstance</code> method in PluggableProtocolFactory never gets called. (A break point there never gets hit) so something else is happening inside the <code>RegisterNameSpace</code> method.</p>
  
  <p>I tried running both as an administrator and a normal user. Same error in both occasions.</p>