J
Juerg Staub
Hi,
I have implemented IInternetProtocol and IInternetProtocolRoot in my
protocol handler. Whenever I try to register the instance with
IInternetSession::RegisterNameSpace, I receive a
NullReferenceException. I checked to news for it and other people seem
to have similar problems.
The CreateInstance of the ClassFactory is called and returns an
ppvObject.
Any ideas?
Thanks
Juerg
Registration is done like this:
IInternetSession s;
TMSProtocolHandler.CoInternetGetSession(0,out s, 0);
Guid guid = new Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B");
s.RegisterNameSpace(new ClassFactory(),ref guid,"tmsxml",0,null,0);
Implementation of Interfaces:
using System;
using System.Runtime.InteropServices;
namespace TMSExplorer
{
/// <summary>
/// Typedefs and enums
/// </summary>
public struct _tagPROTOCOLDATA {
public uint grfFlags;
public uint dwState;
public IntPtr pData;
public uint cbData;
}
public struct _tagBINDINFO {
public uint cbSize;
public string szExtraInfo;
public uint stgmedData;
public uint grfBindInfoF;
public uint dwBindVerb;
public string szCustomVerb;
public uint cbstgmedData;
public uint dwOptions;
public uint dwOptionsFlags;
public uint dwCodePage;
public _SECURITY_ATTRIBUTES securityAttributes;
public Guid iid;
public object punk;
public uint dwReserved;
}
public struct _LARGE_INTEGER {
public long QuadPart;
}
public struct _ULARGE_INTEGER {
public ulong QuadPart;
}
public struct _SECURITY_ATTRIBUTES {
public uint nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
public enum PI_FLAGS {
PI_PARSE_URL = 0x00000001,
PI_FILTER_MODE = 0x00000002,
PI_FORCE_ASYNC = 0x00000004,
PI_USE_WORKERTHREAD = 0x00000008,
PI_MIMEVERIFICATION = 0x00000010,
PI_CLSIDLOOKUP = 0x00000020,
PI_DATAPROGRESS = 0x00000040,
PI_SYNCHRONOUS = 0x00000080,
PI_APARTMENTTHREADED = 0x00000100,
PI_CLASSINSTALL = 0x00000200,
PI_PASSONBINDCTX = 0x00002000,
PI_NOMIMEHANDLER = 0x00008000,
PI_LOADAPPDIRECT = 0x00004000,
PD_FORCE_SWITCH = 0x00010000
}
public enum BSCF {
FirstDataNotification = 0x1,
IntermediateDataNotification = 0x2,
LastDataNotification = 0x4,
DataFullyAvailable = 0x8,
AvailableDataSizeUnknown = 0x10
}
/// <summary>
/// IInternetSession definition
/// </summary>
[ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b")
]
public interface IInternetSession {
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="rclsid"></param>
/// <param name="pwzProtocol"></param>
/// <param name="cPatterns"></param>
/// <param name="ppwzPatterns"></param>
/// <param name="dwReserved"></param>
void RegisterNameSpace( [MarshalAs(UnmanagedType.Interface)]
IClassFactory pCF,
ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzProtocol,
uint cPatterns,
[MarshalAs(UnmanagedType.LPArray,
ArraySubType=UnmanagedType.LPWStr)] string[] ppwzPatterns,
uint dwReserved );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="pszProtocol"></param>
void UnregisterNameSpace( IntPtr pCF,
[MarshalAs(UnmanagedType.LPWStr)]
string pszProtocol );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="rclsid"></param>
/// <param name="pwzType"></param>
void RegisterMimeFilter( IntPtr pCF,
ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzType );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="pwzType"></param>
void UnregisterMimeFilter( IntPtr pCF,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzType );
/// <summary>
///
/// </summary>
/// <param name="pBC"></param>
/// <param name="szUrl"></param>
/// <param name="pUnkOuter"></param>
/// <param name="ppUnk"></param>
/// <param name="ppOInetProt"></param>
/// <param name="dwOption"></param>
void CreateBinding( IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string
szUrl,
IntPtr pUnkOuter,
IntPtr ppUnk,
IInternetProtocol ppOInetProt,
uint dwOption );
/// <summary>
///
/// </summary>
/// <param name="dwOption"></param>
/// <param name="pBuffer"></param>
/// <param name="dwBufferLength"></param>
/// <param name="dwReserved"></param>
void SetSessionOption( uint dwOption,
IntPtr pBuffer,
uint dwBufferLength,
uint dwReserved );
/// <summary>
///
/// </summary>
/// <param name="dwOption"></param>
/// <param name="pBuffer"></param>
/// <param name="pdwBufferLength"></param>
/// <param name="dwReserved"></param>
void GetSessionOption( uint dwOption,
IntPtr pBuffer,
uint pdwBufferLength,
uint dwReserved );
}
/// <summary>
/// IClassFactory definitions
/// </summary>
[
ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00000001-0000-0000-C000-000000000046"),
]
public interface IClassFactory {
void CreateInstance( IntPtr pUnkOuter,
ref Guid riid,
out IntPtr ppvObject);
void LockServer(bool fLock);
}
/// <summary>
/// IInternetProtocall definitions
/// </summary>
[
Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)
]
public interface IInternetProtocol {
#region "IInternetProtocolRoot Methods"
void Start(string szUrl, IInternetProtocolSink pOIProtSink,
IInternetBindInfo pOIBindInfo, uint grfPI, uint
dwReserved);
void Continue( ref _tagPROTOCOLDATA pProtocolData);
void Abort(int hrReason, uint dwOptions);
void Terminate(uint dwOptions);
void Suspend();
void Resume();
#endregion
void Read(IntPtr pv, uint cb, out uint pcbRead);
void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out
_ULARGE_INTEGER
plibNewPosition);
void LockRequest(uint dwOptions);
void UnlockRequest();
}
[ClassInterface(ClassInterfaceType.None)]
public class TMSProtocolHandler : IInternetProtocol {
[DllImport("urlmon.dll", PreserveSig=false)]
public static extern void CoInternetGetSession(uint
dwSessionMode, out
IInternetSession ppIInternetSession, uint dwReserved);
public void Start( string szUrl, IInternetProtocolSink
pOIProtSink,
IInternetBindInfo pOIBindInfo, uint grfPI,
uint dwReserved ) {
System.Diagnostics.EventLog.WriteEntry("test","start");
}
public void Continue( ref _tagPROTOCOLDATA pProtocolData) {}
public void Abort(int hrReason, uint dwOptions) {}
public void Terminate(uint dwOptions) {
System.Diagnostics.EventLog.WriteEntry("test","terminate");
}
public void Suspend() {}
public void Resume() {}
public void Read(IntPtr pv, uint cb, out uint pcbRead) {
pcbRead=0;
}
public void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out
_ULARGE_INTEGER plibNewPosition) {plibNewPosition=new
_ULARGE_INTEGER();}
public void LockRequest(uint dwOptions) {}
public void UnlockRequest() {}
}
[Guid("79EAC9E5-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IInternetProtocolSink {
void Switch(ref _tagPROTOCOLDATA pProtocolData);
void ReportProgress(uint ulStatusCode, string szStatusText);
void ReportData(uint grfBSCF, uint ulProgress, uint
ulProgressMax);
void ReportResult(int hrResult, uint dwError, string
szResult);
}
[Guid("79EAC9E1-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IInternetBindInfo {
void GetBindInfo(out uint grfBINDF, ref _tagBINDINFO
pbindinfo);
void GetBindString(uint ulStringType, ref string ppwzStr, uint
cEl, ref
uint pcElFetched);
}
public class ClassFactory: IClassFactory {
private const int CLASS_E_NOAGGREGATION = unchecked((int)
0x80040110);
private const int E_NOINTERFACE = unchecked((int) 0x80004002);
private readonly Guid IID_IInternetProtocolInfo = new
Guid("{79eac9ec-baf9-11ce-8c82-00aa004ba90b}");
public ClassFactory() {
}
public void CreateInstance(IntPtr pUnkOuter, ref Guid riid,
out IntPtr ppvObject) {
ppvObject = IntPtr.Zero;
if (pUnkOuter != IntPtr.Zero) {
Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
}
if (riid == IID_IInternetProtocolInfo) {
TMSProtocolHandler ctrl = new TMSProtocolHandler();
ppvObject =
Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
}
else {
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
}
public void LockServer(bool fLock) {
}
}
}
I have implemented IInternetProtocol and IInternetProtocolRoot in my
protocol handler. Whenever I try to register the instance with
IInternetSession::RegisterNameSpace, I receive a
NullReferenceException. I checked to news for it and other people seem
to have similar problems.
The CreateInstance of the ClassFactory is called and returns an
ppvObject.
Any ideas?
Thanks
Juerg
Registration is done like this:
IInternetSession s;
TMSProtocolHandler.CoInternetGetSession(0,out s, 0);
Guid guid = new Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B");
s.RegisterNameSpace(new ClassFactory(),ref guid,"tmsxml",0,null,0);
Implementation of Interfaces:
using System;
using System.Runtime.InteropServices;
namespace TMSExplorer
{
/// <summary>
/// Typedefs and enums
/// </summary>
public struct _tagPROTOCOLDATA {
public uint grfFlags;
public uint dwState;
public IntPtr pData;
public uint cbData;
}
public struct _tagBINDINFO {
public uint cbSize;
public string szExtraInfo;
public uint stgmedData;
public uint grfBindInfoF;
public uint dwBindVerb;
public string szCustomVerb;
public uint cbstgmedData;
public uint dwOptions;
public uint dwOptionsFlags;
public uint dwCodePage;
public _SECURITY_ATTRIBUTES securityAttributes;
public Guid iid;
public object punk;
public uint dwReserved;
}
public struct _LARGE_INTEGER {
public long QuadPart;
}
public struct _ULARGE_INTEGER {
public ulong QuadPart;
}
public struct _SECURITY_ATTRIBUTES {
public uint nLength;
public IntPtr lpSecurityDescriptor;
public int bInheritHandle;
}
public enum PI_FLAGS {
PI_PARSE_URL = 0x00000001,
PI_FILTER_MODE = 0x00000002,
PI_FORCE_ASYNC = 0x00000004,
PI_USE_WORKERTHREAD = 0x00000008,
PI_MIMEVERIFICATION = 0x00000010,
PI_CLSIDLOOKUP = 0x00000020,
PI_DATAPROGRESS = 0x00000040,
PI_SYNCHRONOUS = 0x00000080,
PI_APARTMENTTHREADED = 0x00000100,
PI_CLASSINSTALL = 0x00000200,
PI_PASSONBINDCTX = 0x00002000,
PI_NOMIMEHANDLER = 0x00008000,
PI_LOADAPPDIRECT = 0x00004000,
PD_FORCE_SWITCH = 0x00010000
}
public enum BSCF {
FirstDataNotification = 0x1,
IntermediateDataNotification = 0x2,
LastDataNotification = 0x4,
DataFullyAvailable = 0x8,
AvailableDataSizeUnknown = 0x10
}
/// <summary>
/// IInternetSession definition
/// </summary>
[ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("79eac9e7-baf9-11ce-8c82-00aa004ba90b")
]
public interface IInternetSession {
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="rclsid"></param>
/// <param name="pwzProtocol"></param>
/// <param name="cPatterns"></param>
/// <param name="ppwzPatterns"></param>
/// <param name="dwReserved"></param>
void RegisterNameSpace( [MarshalAs(UnmanagedType.Interface)]
IClassFactory pCF,
ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzProtocol,
uint cPatterns,
[MarshalAs(UnmanagedType.LPArray,
ArraySubType=UnmanagedType.LPWStr)] string[] ppwzPatterns,
uint dwReserved );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="pszProtocol"></param>
void UnregisterNameSpace( IntPtr pCF,
[MarshalAs(UnmanagedType.LPWStr)]
string pszProtocol );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="rclsid"></param>
/// <param name="pwzType"></param>
void RegisterMimeFilter( IntPtr pCF,
ref Guid rclsid,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzType );
/// <summary>
///
/// </summary>
/// <param name="pCF"></param>
/// <param name="pwzType"></param>
void UnregisterMimeFilter( IntPtr pCF,
[MarshalAs(UnmanagedType.LPWStr)]
string pwzType );
/// <summary>
///
/// </summary>
/// <param name="pBC"></param>
/// <param name="szUrl"></param>
/// <param name="pUnkOuter"></param>
/// <param name="ppUnk"></param>
/// <param name="ppOInetProt"></param>
/// <param name="dwOption"></param>
void CreateBinding( IntPtr pBC,
[MarshalAs(UnmanagedType.LPWStr)] string
szUrl,
IntPtr pUnkOuter,
IntPtr ppUnk,
IInternetProtocol ppOInetProt,
uint dwOption );
/// <summary>
///
/// </summary>
/// <param name="dwOption"></param>
/// <param name="pBuffer"></param>
/// <param name="dwBufferLength"></param>
/// <param name="dwReserved"></param>
void SetSessionOption( uint dwOption,
IntPtr pBuffer,
uint dwBufferLength,
uint dwReserved );
/// <summary>
///
/// </summary>
/// <param name="dwOption"></param>
/// <param name="pBuffer"></param>
/// <param name="pdwBufferLength"></param>
/// <param name="dwReserved"></param>
void GetSessionOption( uint dwOption,
IntPtr pBuffer,
uint pdwBufferLength,
uint dwReserved );
}
/// <summary>
/// IClassFactory definitions
/// </summary>
[
ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00000001-0000-0000-C000-000000000046"),
]
public interface IClassFactory {
void CreateInstance( IntPtr pUnkOuter,
ref Guid riid,
out IntPtr ppvObject);
void LockServer(bool fLock);
}
/// <summary>
/// IInternetProtocall definitions
/// </summary>
[
Guid("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)
]
public interface IInternetProtocol {
#region "IInternetProtocolRoot Methods"
void Start(string szUrl, IInternetProtocolSink pOIProtSink,
IInternetBindInfo pOIBindInfo, uint grfPI, uint
dwReserved);
void Continue( ref _tagPROTOCOLDATA pProtocolData);
void Abort(int hrReason, uint dwOptions);
void Terminate(uint dwOptions);
void Suspend();
void Resume();
#endregion
void Read(IntPtr pv, uint cb, out uint pcbRead);
void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out
_ULARGE_INTEGER
plibNewPosition);
void LockRequest(uint dwOptions);
void UnlockRequest();
}
[ClassInterface(ClassInterfaceType.None)]
public class TMSProtocolHandler : IInternetProtocol {
[DllImport("urlmon.dll", PreserveSig=false)]
public static extern void CoInternetGetSession(uint
dwSessionMode, out
IInternetSession ppIInternetSession, uint dwReserved);
public void Start( string szUrl, IInternetProtocolSink
pOIProtSink,
IInternetBindInfo pOIBindInfo, uint grfPI,
uint dwReserved ) {
System.Diagnostics.EventLog.WriteEntry("test","start");
}
public void Continue( ref _tagPROTOCOLDATA pProtocolData) {}
public void Abort(int hrReason, uint dwOptions) {}
public void Terminate(uint dwOptions) {
System.Diagnostics.EventLog.WriteEntry("test","terminate");
}
public void Suspend() {}
public void Resume() {}
public void Read(IntPtr pv, uint cb, out uint pcbRead) {
pcbRead=0;
}
public void Seek(_LARGE_INTEGER dlibMove, uint dwOrigin, out
_ULARGE_INTEGER plibNewPosition) {plibNewPosition=new
_ULARGE_INTEGER();}
public void LockRequest(uint dwOptions) {}
public void UnlockRequest() {}
}
[Guid("79EAC9E5-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IInternetProtocolSink {
void Switch(ref _tagPROTOCOLDATA pProtocolData);
void ReportProgress(uint ulStatusCode, string szStatusText);
void ReportData(uint grfBSCF, uint ulProgress, uint
ulProgressMax);
void ReportResult(int hrResult, uint dwError, string
szResult);
}
[Guid("79EAC9E1-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
public interface IInternetBindInfo {
void GetBindInfo(out uint grfBINDF, ref _tagBINDINFO
pbindinfo);
void GetBindString(uint ulStringType, ref string ppwzStr, uint
cEl, ref
uint pcElFetched);
}
public class ClassFactory: IClassFactory {
private const int CLASS_E_NOAGGREGATION = unchecked((int)
0x80040110);
private const int E_NOINTERFACE = unchecked((int) 0x80004002);
private readonly Guid IID_IInternetProtocolInfo = new
Guid("{79eac9ec-baf9-11ce-8c82-00aa004ba90b}");
public ClassFactory() {
}
public void CreateInstance(IntPtr pUnkOuter, ref Guid riid,
out IntPtr ppvObject) {
ppvObject = IntPtr.Zero;
if (pUnkOuter != IntPtr.Zero) {
Marshal.ThrowExceptionForHR(CLASS_E_NOAGGREGATION);
}
if (riid == IID_IInternetProtocolInfo) {
TMSProtocolHandler ctrl = new TMSProtocolHandler();
ppvObject =
Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
}
else {
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
}
public void LockServer(bool fLock) {
}
}
}