异步可插入协议 [英] Asynchronous Pluggable Protocols

查看:144
本文介绍了异步可插入协议的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用作为参考,我试图创建一个异步可插拔协议只是暂时提供给我的应用程序(和未注册系统范围)。我使用 CoInternetGetSession ,然后调用 RegisterNameSpace 来做到这一点。然而,当我拨打电话到 RegisterNameSpace 我得到一个AccessViolation异常:尝试读取或写入受保护的内存 <。 ?/ p>

任何想法是怎么回事



我的代码如下所示:

  [ComImport] 
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
[的Guid(00000001-0000-0000-C000-000000000046)]
[标记有​​ComVisible特性(真)]
公共接口的IClassFactory
{
无效的CreateInstance(IntPtr的pUnkOuter,裁判的Guid RIID,出的IntPtr ppvObject);
无效LockServer(布尔涌向);
}

/ *自定义类作为一个类工厂,创建的协议* /
的一个实例[的Guid(0b9c4422-2b6e-4c2d-91b0-9016053ab1b1 )
[标记有​​ComVisible特性(真),ClassInterface(ClassInterfaceType.AutoDispatch)
公共类PluggableProtocolFactory:IClassFactory的
{
公共类型的AppType;
公共PluggableProtocolFactory(T型)
{
this.AppType = T;
}
公共无效的CreateInstance(IntPtr的pUnkOuter,裁判的Guid RIID,出的IntPtr ppvObject)
{
RIID = ProtocolSupport.GetGuid(this.AppType);
IInternetProtocol P = Activator.CreateInstance(this.AppType)为IInternetProtocol;
ppvObject = Marshal.GetComInterfaceForObject(P的typeof(IInternetProtocol));
}

公共无效LockServer(布尔涌向)
{
变种B =羊群;
}

}

[标记有​​ComVisible特性(真)]
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
〔的Guid(79eac9e7-baf9-11ce-8c82-00aa004ba90b)]
公共接口IInternetSession
{
无效CreateBinding(); //未实现
无效GetCache(); //未实现
无效GetSessionOption(); //未实现
无效RegisterMimeFilter([的MarshalAs(UnmanagedType.Interface)IClassFactory的PCF,裁判的Guid rclsid,[的MarshalAs(UnmanagedType.LPWStr)串pwzType);
无效RegisterNameSpace([的MarshalAs(UnmanagedType.Interface)IClassFactory的PCF,裁判的Guid rclsid,[的MarshalAs(UnmanagedType.LPWStr)字符串pwzProtocol,
UInt32的cPatterns,[的MarshalAs(UnmanagedType.LPArray,ArraySubType = UnmanagedType .LPWStr)的String [] ppwzPatterns,UInt32的dwReserved);
无效SetCache(); //未实现
无效SetSessionOption(); //未实现
无效UnregisterMimeFilter(PCF的IClassFactory [的MarshalAs(UnmanagedType.LPWStr)串pwzType);
无效UnregisterNameSpace(PCF的IClassFactory [的MarshalAs(UnmanagedType.LPWStr)串pwzProtocol);
}

[标记有​​ComVisible特性(假)]公共接口IComRegister
{
无效寄存器(T型);
无效注销(T型);
}

[标记有​​ComVisible特性(假),AttributeUsage(AttributeTargets.Class,的AllowMultiple = TRUE)]
公共类AsyncProtocolAttribute:属性,IComRegister
{
公共字符串名称;
公共字符串描述;

函数[DllImport(urlmon.dll中,PreserveSig = FALSE)]
公共静态外部INT CoInternetGetSession(UInt32的dwSessionMode / * = 0 * / REF IInternetSession ppIInternetSession,UInt32的dwReserved / * = 0 * /);

公共无效寄存器(T型)
{
IInternetSession会话= NULL;
CoInternetGetSession(0,参考会话,0);
的Guid G =新的GUID(79EAC9E4-BAF9-11CE-8C82-00AA004BA90B);
session.RegisterNameSpace(新PluggableProtocolFactory(T),REF克,this.Name,0,NULL,0);

}



的CreateInstance 在PluggableProtocolFactory方法不会被调用。 (一个破发点也从来没有被击中),所以别的东西是 RegisterNameSpace 方法内发生的事情。



我尝试运行同时作为管理员和普通用户。 。同样的错误,在这两个场合


解决方案

行,想通了:在IInternetSession接口的声明是错误的:



下面是一个更好的,我从 monoblog回升

  [标记有​​ComVisible特性(真),与GUID(79eac9e7-baf9-11ce-8c82-00aa004ba90b), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)
公共接口IInternetSession
{
[PreserveSig]
INT RegisterNameSpace(
[IN]的IClassFactory的ClassFactory,
[IN]裁判的Guid rclsid,
[中,的MarshalAs(UnmanagedType.LPWStr)字符串pwzProtocol,
[IN]
INT cPatterns,
[中,的MarshalAs(UnmanagedType.LPWStr)]
串ppwzPatterns,
[IN]诠释dwReserved);

[PreserveSig]
INT UnregisterNameSpace(
[IN]的IClassFactory的ClassFactory,
[中,的MarshalAs(UnmanagedType.LPWStr)串pszProtocol);

INT Bogus1();

INT Bogus2();

INT Bogus3();

INT Bogus4();

INT Bogus5();
}


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.

解决方案

OK, figured it out: The declaration of the IInternetSession interface was wrong:

Here's a better one I picked up from monoblog:

[ComVisible(true), Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b"),InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
public interface IInternetSession
{
    [PreserveSig]
    int RegisterNameSpace(
        [In] IClassFactory classFactory,
        [In] ref Guid rclsid,
        [In, MarshalAs(UnmanagedType.LPWStr)] string pwzProtocol,
        [In]
            int cPatterns,
        [In, MarshalAs(UnmanagedType.LPWStr)]
            string ppwzPatterns,
        [In] int dwReserved);

    [PreserveSig]
    int UnregisterNameSpace(
        [In] IClassFactory classFactory,
        [In, MarshalAs(UnmanagedType.LPWStr)] string pszProtocol);

    int Bogus1();

    int Bogus2();

    int Bogus3();

    int Bogus4();

    int Bogus5();
}

这篇关于异步可插入协议的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆