IInternetProtocoll implementation (Pluggable Protocall Handler)

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) {
}
}


}
 
J

Juerg Staub

I found one of the problems already. My TMSProtocollHandler does not
implement IInternetProtocolInfo. So I changed the ClassFactory that to
the following



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_IInternetProtocol = new
Guid("{79eac9e4-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_IInternetProtocol) {
TMSProtocolHandler ctrl = new TMSProtocolHandler();
ppvObject =
Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
}
else {
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
// LockServer still the same...
}
}


Then I realized, no matter what I pass as the guid into the
RegisterNameSpace call, in the ClassFactory::CreateInstance riid is
always 79eac9ec-baf9-11ce-8c82-00aa004ba90b which is
IID_IInternetProtocolInfo. To me it seems, that in my case this
interface must be implemented.
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);


Is this true and how can I implement two COM interface in one C# class
(TMSProtocollHandler)?

Thanks for your help.

Juerg





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) {
}
}


}
 
J

Jeffrey Tan[MSFT]

Hi Juerg,

Thanks for your posting.
I will find someoone to help you on this issue.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: (e-mail address removed) (Juerg Staub)
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Subject: Re: IInternetProtocoll implementation (Pluggable Protocall
Handler)
| Date: 10 Nov 2003 09:53:01 -0800
| Organization: http://groups.google.com
| Lines: 385
| Message-ID: <[email protected]>
| References: <[email protected]>
| NNTP-Posting-Host: 198.240.212.30
| Content-Type: text/plain; charset=ISO-8859-1
| Content-Transfer-Encoding: 8bit
| X-Trace: posting.google.com 1068486782 19428 127.0.0.1 (10 Nov 2003
17:53:02 GMT)
| X-Complaints-To: (e-mail address removed)
| NNTP-Posting-Date: Mon, 10 Nov 2003 17:53:02 +0000 (UTC)
| Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!t-onlin
e.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!postnews1.google.com!no
t-for-mail
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:198119
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| I found one of the problems already. My TMSProtocollHandler does not
| implement IInternetProtocolInfo. So I changed the ClassFactory that to
| the following
|
|
|
| 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_IInternetProtocol = new
| Guid("{79eac9e4-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_IInternetProtocol) {
| TMSProtocolHandler ctrl = new TMSProtocolHandler();
| ppvObject =
| Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
| }
| else {
| Marshal.ThrowExceptionForHR(E_NOINTERFACE);
| }
| // LockServer still the same...
| }
| }
|
|
| Then I realized, no matter what I pass as the guid into the
| RegisterNameSpace call, in the ClassFactory::CreateInstance riid is
| always 79eac9ec-baf9-11ce-8c82-00aa004ba90b which is
| IID_IInternetProtocolInfo. To me it seems, that in my case this
| interface must be implemented.
|
| > 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);
|
|
| Is this true and how can I implement two COM interface in one C# class
| (TMSProtocollHandler)?
|
| Thanks for your help.
|
| Juerg
|
|
|
|
|
| (e-mail address removed) (Juerg Staub) wrote in message
| > 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) {
| > }
| > }
| >
| >
| > }
|
 
J

Juerg Staub

Hello,

Got a bit further. Modified ClassFactory implementation, i.e not
checking for the aggregation anymore. Now Terminate (from
IInternetProtocolRoot) gets called as the one and only method. I think
some of my definitions or ordering are wrong?

Thanks

Juerg


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 PARSEACTION {
PARSE_CANONICALIZE = 1, // compute canonical URL
PARSE_FRIENDLY, // get user friendly name from
URL
PARSE_SECURITY_URL, // get security URL.
PARSE_ROOTDOCUMENT, // returns URL of root
document for site
PARSE_DOCUMENT, // Strips of #anchor
PARSE_ANCHOR, // Strips of everything before
#anchor
PARSE_ENCODE, // encode the url
PARSE_DECODE, // decode the url
PARSE_PATH_FROM_URL, // get the path if apply
PARSE_URL_FROM_PATH, // create a url from the path
PARSE_MIME, // return mime of this url
PARSE_SERVER, // return server
PARSE_SCHEMA,
PARSE_SITE,
PARSE_DOMAIN,
PARSE_LOCATION,
PARSE_SECURITY_DOMAIN, // returns the canonical
security form of the URL.
PARSE_ESCAPE, // encode the url
PARSE_UNESCAPE // decode the url
}


public enum QUERYOPTION {
QUERY_EXPIRATION_DATE = 1, // the expiration date in
form of systemtime
QUERY_TIME_OF_LAST_CHANGE, // time of last change in
form of systemtime
QUERY_CONTENT_ENCODING , // the content concoding
schema
QUERY_CONTENT_TYPE, // the content type header
(mime and charset)
QUERY_REFRESH, // the refresh
QUERY_RECOMBINE, // combine the page URL
with the nearest base if TRUE
QUERY_CAN_NAVIGATE, // does the protocol
navigate (unlike mailto)
QUERY_USES_NETWORK, // will URL hit network
QUERY_IS_CACHED, // is data cached locally?
QUERY_IS_INSTALLEDENTRY, // Is the entry installed
locally (on cdrom)
QUERY_IS_CACHED_OR_MAPPED, // is the entry in cache
or is it on a mapped drive
// It may be mapped but may not actually be present
QUERY_USES_CACHE, // does the protocol use
the internet cache
QUERY_IS_SECURE, // is the protocol
encrypted
QUERY_IS_SAFE // the protocol serves only
trusted (e.g. local resource) content
}


public enum BSCF {
FirstDataNotification = 0x1,
IntermediateDataNotification = 0x2,
LastDataNotification = 0x4,
DataFullyAvailable = 0x8,
AvailableDataSizeUnknown = 0x10
}


/// <summary>
/// IInternetSession definition
/// </summary>
[
ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
GuidAttribute("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),
GuidAttribute("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>
[
ComImport(),
GuidAttribute("79EAC9E4-BAF9-11CE-8C82-00AA004BA90B"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)
]
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

#region "IInternetProtocol Methods"
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();
#endregion
}


[
ComImport(),
GuidAttribute("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);
}


[
ComImport(),
GuidAttribute("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);
}


[ClassInterface(ClassInterfaceType.None)]
public class TMSProtocolHandler : IInternetProtocol {

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() {}

}


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_IInternetProtocol = new
Guid("{79EAC9E4-BAF9-11CE-8C82-00AA004BA90B}");
private readonly Guid IID_IInternetProtocolInfo = new
Guid("{79EAC9EC-BAF9-11CE-8C82-00AA004BA90B}");
private readonly Guid IID_IUnknown = new
Guid("{00000000-0000-0000-C000-000000000046}");

public ClassFactory() {
}

public void CreateInstance(IntPtr pUnkOuter, ref Guid riid,
out IntPtr ppvObject) {
ppvObject = IntPtr.Zero;
if (riid == IID_IInternetProtocol || riid == IID_IUnknown)
{
TMSProtocolHandler ctrl = new TMSProtocolHandler();
ppvObject =
Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
}
else {
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
}
public void LockServer(bool fLock) {
}
}

}




Hi Juerg,

Thanks for your posting.
I will find someoone to help you on this issue.

Best regards,
Jeffrey Tan
Microsoft Online Partner Support
Get Secure! - www.microsoft.com/security
This posting is provided "as is" with no warranties and confers no rights.

--------------------
| From: (e-mail address removed) (Juerg Staub)
| Newsgroups: microsoft.public.dotnet.languages.csharp
| Subject: Re: IInternetProtocoll implementation (Pluggable Protocall
Handler)
| Date: 10 Nov 2003 09:53:01 -0800
| Organization: http://groups.google.com
| Lines: 385
| Message-ID: <[email protected]>
| References: <[email protected]>
| NNTP-Posting-Host: 198.240.212.30
| Content-Type: text/plain; charset=ISO-8859-1
| Content-Transfer-Encoding: 8bit
| X-Trace: posting.google.com 1068486782 19428 127.0.0.1 (10 Nov 2003
17:53:02 GMT)
| X-Complaints-To: (e-mail address removed)
| NNTP-Posting-Date: Mon, 10 Nov 2003 17:53:02 +0000 (UTC)
| Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.sul.t-online.de!t-onlin
e.de!news-spur1.maxwell.syr.edu!news.maxwell.syr.edu!postnews1.google.com!no
t-for-mail
| Xref: cpmsftngxa06.phx.gbl microsoft.public.dotnet.languages.csharp:198119
| X-Tomcat-NG: microsoft.public.dotnet.languages.csharp
|
| I found one of the problems already. My TMSProtocollHandler does not
| implement IInternetProtocolInfo. So I changed the ClassFactory that to
| the following
|
|
|
| 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_IInternetProtocol = new
| Guid("{79eac9e4-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_IInternetProtocol) {
| TMSProtocolHandler ctrl = new TMSProtocolHandler();
| ppvObject =
| Marshal.GetComInterfaceForObject(ctrl,typeof(IInternetProtocol));
| }
| else {
| Marshal.ThrowExceptionForHR(E_NOINTERFACE);
| }
| // LockServer still the same...
| }
| }
|
|
| Then I realized, no matter what I pass as the guid into the
| RegisterNameSpace call, in the ClassFactory::CreateInstance riid is
| always 79eac9ec-baf9-11ce-8c82-00aa004ba90b which is
| IID_IInternetProtocolInfo. To me it seems, that in my case this
| interface must be implemented.
|
| > 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);
|
|
| Is this true and how can I implement two COM interface in one C# class
| (TMSProtocollHandler)?
|
| Thanks for your help.
|
| Juerg
|
|
|
|
|
| (e-mail address removed) (Juerg Staub) wrote in message
| > 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) {
| > }
| > }
| >
| >
| > }
|
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top