Can create object using C++ CoCreateInstance, but not using C# Activator.CreateInstance

  • Thread starter Thread starter Brian Rogers
  • Start date Start date
B

Brian Rogers

Hello everyone,

I apologize for the cross and re-post, but I am still searching for an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous pluggable
protocol adaptor, so I can analyse the traffic between urlmon.dll (IE) and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol registry key) is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Brian,

If you are trying to access the asyncronous pluggable protocol adaptor,
you shouldn't be creating it directly, but rather, you should be using the
IMoniker interface.

However, that doesn't mean that one ^can't^ create it directly, as it
should just be another COM object. It could be that there is something in
the constructor of the class that detects some sort of context (just a
guess).

As a workaround, you can have unmanaged code that creates the object,
and then passes the pointer to managed code.

Hope this helps.
 
Hi Nicholas,

I appreciate the feedback.

The objective is to place a wrapper around the protocol adapter, so I can
reverse engineer the data flow in both directions. I want to analyse the
data flow between IE and the FTP protocol handler.

I actually have no idea how the IMoniker interface comes into play. I
believe the handler was supposed to support the IInternetProtocol and
IInternetProtocolRoot interfaces amongst others. Currently, I can't even
create the filter to bind it to IUnknown.

In the end, I want to create a custom FTP Protocol handler in C#. My C++ is
not good enough to create and expose an unmanaged factory class, so that was
not an option for me.

Thanks,
B.

Nicholas Paldino said:
Brian,

If you are trying to access the asyncronous pluggable protocol adaptor,
you shouldn't be creating it directly, but rather, you should be using the
IMoniker interface.

However, that doesn't mean that one ^can't^ create it directly, as it
should just be another COM object. It could be that there is something in
the constructor of the class that detects some sort of context (just a
guess).

As a workaround, you can have unmanaged code that creates the object,
and then passes the pointer to managed code.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Brian Rogers said:
Hello everyone,

I apologize for the cross and re-post, but I am still searching for an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous pluggable
protocol adaptor, so I can analyse the traffic between urlmon.dll (IE) and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol registry key) is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Brian,
If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I replace IID_IInternetProtocol with IID_IUnknown, I get an access
violation exception. Unless I'm missing something, that looks like a
bug. I suspect that's why you get the exception in managed code.

The only workaround I can suggest is that you call CoCreateInstance
through P/Invoke.



Mattias
 
Brian,

It would be much easier to implement a pluggable protocol handler in
C++. You can create an ATL project that will do all of the COM plumbing for
you. Once you have that, all you should have to worry about is the
implementation of the interface (along with the registration).

However, I don't know if you can register your own FTP handler. I think
that for protocols like HTTP and FTP, the COM Moniker framework hard-codes
the protocol handlers.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brian Rogers said:
Hi Nicholas,

I appreciate the feedback.

The objective is to place a wrapper around the protocol adapter, so I can
reverse engineer the data flow in both directions. I want to analyse the
data flow between IE and the FTP protocol handler.

I actually have no idea how the IMoniker interface comes into play. I
believe the handler was supposed to support the IInternetProtocol and
IInternetProtocolRoot interfaces amongst others. Currently, I can't even
create the filter to bind it to IUnknown.

In the end, I want to create a custom FTP Protocol handler in C#. My C++ is
not good enough to create and expose an unmanaged factory class, so that was
not an option for me.

Thanks,
B.

message news:[email protected]...
Brian,

If you are trying to access the asyncronous pluggable protocol adaptor,
you shouldn't be creating it directly, but rather, you should be using the
IMoniker interface.

However, that doesn't mean that one ^can't^ create it directly, as it
should just be another COM object. It could be that there is something in
the constructor of the class that detects some sort of context (just a
guess).

As a workaround, you can have unmanaged code that creates the object,
and then passes the pointer to managed code.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Brian Rogers said:
Hello everyone,

I apologize for the cross and re-post, but I am still searching for an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous pluggable
protocol adaptor, so I can analyse the traffic between urlmon.dll (IE) and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol registry key) is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Hi Mattias,

Thank you for looking into the issue.

I was not aware there was a CoCreateInstance that you could invoke from C#.
I assume you are using some form of reflection to access the object and then
call P/Invoke?

My under the covers COM and C++ skills are seriously lacking. While I
understand the fundamentals and can do some of the advanced stuff, this is a
little further down the road.

In another project, I received an instance of an object through the
marshaller and then invoked methods by name. The problem I have here is
actually getting the initial instance.

Thanks,
B.
 
Hi Nicholas,

Yeah - was trying desperately not to have to do that. I love ATL and C++ -
NOT!!! :)

Hardcoding the handler in the PROTOCOLS key works perfectly for me and
initiates my C# handler. I have registered my protocol as test: for now.
It's the re-routing of the calls to the ftp protocol handler that is killing
me.

All I really need to do is create and instance of the handler and bind it to
the IInternetProtocol interfaces (or other pluggable protocol handlers) in
order to reverse engineer it. Then I implement all the interface methods and
pass the calls to the FTP handler instance. I can then examine all data in
transit.

I appreciate the help though.

Thanks,
B.


Nicholas Paldino said:
Brian,

It would be much easier to implement a pluggable protocol handler in
C++. You can create an ATL project that will do all of the COM plumbing for
you. Once you have that, all you should have to worry about is the
implementation of the interface (along with the registration).

However, I don't know if you can register your own FTP handler. I think
that for protocols like HTTP and FTP, the COM Moniker framework hard-codes
the protocol handlers.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brian Rogers said:
Hi Nicholas,

I appreciate the feedback.

The objective is to place a wrapper around the protocol adapter, so I can
reverse engineer the data flow in both directions. I want to analyse the
data flow between IE and the FTP protocol handler.

I actually have no idea how the IMoniker interface comes into play. I
believe the handler was supposed to support the IInternetProtocol and
IInternetProtocolRoot interfaces amongst others. Currently, I can't even
create the filter to bind it to IUnknown.

In the end, I want to create a custom FTP Protocol handler in C#. My C++ is
not good enough to create and expose an unmanaged factory class, so that was
not an option for me.

Thanks,
B.

message news:[email protected]...
something
in
the constructor of the class that detects some sort of context (just a
guess).

As a workaround, you can have unmanaged code that creates the object,
and then passes the pointer to managed code.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hello everyone,

I apologize for the cross and re-post, but I am still searching for an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous
pluggable
protocol adaptor, so I can analyse the traffic between urlmon.dll
(IE)
and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol registry
key)
is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an instance
of
the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Brian,

In that case, I would stick with what I originally proposed, which is
getting the pointer in unmanaged code and then passing that back to managed
code.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brian Rogers said:
Hi Nicholas,

Yeah - was trying desperately not to have to do that. I love ATL and C++ -
NOT!!! :)

Hardcoding the handler in the PROTOCOLS key works perfectly for me and
initiates my C# handler. I have registered my protocol as test: for now.
It's the re-routing of the calls to the ftp protocol handler that is killing
me.

All I really need to do is create and instance of the handler and bind it to
the IInternetProtocol interfaces (or other pluggable protocol handlers) in
order to reverse engineer it. Then I implement all the interface methods and
pass the calls to the FTP handler instance. I can then examine all data in
transit.

I appreciate the help though.

Thanks,
B.


message news:%[email protected]...
Brian,

It would be much easier to implement a pluggable protocol handler in
C++. You can create an ATL project that will do all of the COM plumbing for
you. Once you have that, all you should have to worry about is the
implementation of the interface (along with the registration).

However, I don't know if you can register your own FTP handler. I think
that for protocols like HTTP and FTP, the COM Moniker framework hard-codes
the protocol handlers.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brian Rogers said:
Hi Nicholas,

I appreciate the feedback.

The objective is to place a wrapper around the protocol adapter, so I can
reverse engineer the data flow in both directions. I want to analyse the
data flow between IE and the FTP protocol handler.

I actually have no idea how the IMoniker interface comes into play. I
believe the handler was supposed to support the IInternetProtocol and
IInternetProtocolRoot interfaces amongst others. Currently, I can't even
create the filter to bind it to IUnknown.

In the end, I want to create a custom FTP Protocol handler in C#. My
C++
is
not good enough to create and expose an unmanaged factory class, so
that
was
not an option for me.

Thanks,
B.

"Nicholas Paldino [.NET/C# MVP]" <[email protected]>
wrote
in
message Brian,

If you are trying to access the asyncronous pluggable protocol
adaptor,
you shouldn't be creating it directly, but rather, you should be
using
the
IMoniker interface.

However, that doesn't mean that one ^can't^ create it directly,
as
it
should just be another COM object. It could be that there is
something
in
the constructor of the class that detects some sort of context (just a
guess).

As a workaround, you can have unmanaged code that creates the object,
and then passes the pointer to managed code.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hello everyone,

I apologize for the cross and re-post, but I am still searching
for
instance
 
Brian,
I was not aware there was a CoCreateInstance that you could invoke from C#.
I assume you are using some form of reflection to access the object and then
call P/Invoke?

No reflection needed, just declare the function like this

[DllImport("ole32.dll", PreserveSig=false)]
[return: MarshalAs(UnmanagedType.IUnknown)]
static extern object CoCreateInstance(
[MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
uint dwClsContext,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid);

and call it something like this

Guid CLSID_FtpProtocol = new
Guid("79eac9e3-baf9-11ce-8c82-00aa004ba90b");
Guid IID_IInternetProtocol = new
Guid("79eac9e4-baf9-11ce-8c82-00aa004ba90b");

o = CoCreateInstance( CLSID_FtpProtocol, null, 1
/*CLSCTX_INPROC_SERVER*/, IID_IInternetProtocol );



Mattias
 
Brian Rogers said:
If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

A bug in URLMon.dll. Activator.CreateInstance calls CoCreateInstance
querying for IUnknown. Rather than looking at the outer unknown, URLMon
erroneously assumes that when an object is created and asked for
IUnknown, the caller wants to aggregate the object. So it goes ahead and
uses outer unknown without checking, but Activator.CreateInstance passes
NULL there. So the whole thing crashes with an AV. .NET marshaling
catches the crash with a structured exception handler, and rethrows it
as OutOfMemoryException.

I'm not familiar with C#, I don't know if there's a way to make it call
CoCreateInstance asking for some interface other than IUnknown.
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
 
I will give it a shot,
Thanks.

Nicholas Paldino said:
Brian,

In that case, I would stick with what I originally proposed, which is
getting the pointer in unmanaged code and then passing that back to managed
code.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Brian Rogers said:
Hi Nicholas,

Yeah - was trying desperately not to have to do that. I love ATL and C++ -
NOT!!! :)

Hardcoding the handler in the PROTOCOLS key works perfectly for me and
initiates my C# handler. I have registered my protocol as test: for now.
It's the re-routing of the calls to the ftp protocol handler that is killing
me.

All I really need to do is create and instance of the handler and bind
it
to
the IInternetProtocol interfaces (or other pluggable protocol handlers) in
order to reverse engineer it. Then I implement all the interface methods and
pass the calls to the FTP handler instance. I can then examine all data in
transit.

I appreciate the help though.

Thanks,
B.


message news:%[email protected]...
Brian,

It would be much easier to implement a pluggable protocol handler in
C++. You can create an ATL project that will do all of the COM
plumbing
for
you. Once you have that, all you should have to worry about is the
implementation of the interface (along with the registration).

However, I don't know if you can register your own FTP handler. I think
that for protocols like HTTP and FTP, the COM Moniker framework hard-codes
the protocol handlers.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

Hi Nicholas,

I appreciate the feedback.

The objective is to place a wrapper around the protocol adapter, so
I
can
reverse engineer the data flow in both directions. I want to analyse the
data flow between IE and the FTP protocol handler.

I actually have no idea how the IMoniker interface comes into play. I
believe the handler was supposed to support the IInternetProtocol and
IInternetProtocolRoot interfaces amongst others. Currently, I can't even
create the filter to bind it to IUnknown.

In the end, I want to create a custom FTP Protocol handler in C#. My C++
is
not good enough to create and expose an unmanaged factory class, so that
was
not an option for me.

Thanks,
B.

in
message Brian,

If you are trying to access the asyncronous pluggable protocol
adaptor,
you shouldn't be creating it directly, but rather, you should be using
the
IMoniker interface.

However, that doesn't mean that one ^can't^ create it
directly,
(just
a
guess).

As a workaround, you can have unmanaged code that creates the
object,
and then passes the pointer to managed code.

Hope this helps.


--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)


Hello everyone,

I apologize for the cross and re-post, but I am still searching
for
an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous
pluggable
protocol adaptor, so I can analyse the traffic between
urlmon.dll
(IE)
and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol
registry
key)
is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as
CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an
instance
of
the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error.
(OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Hi Mattias,

I get it now. Now I understand.Will give it a shot.

Thanks,
B.

Mattias Sjögren said:
Brian,
I was not aware there was a CoCreateInstance that you could invoke from C#.
I assume you are using some form of reflection to access the object and then
call P/Invoke?

No reflection needed, just declare the function like this

[DllImport("ole32.dll", PreserveSig=false)]
[return: MarshalAs(UnmanagedType.IUnknown)]
static extern object CoCreateInstance(
[MarshalAs(UnmanagedType.LPStruct)] Guid rclsid,
[MarshalAs(UnmanagedType.IUnknown)] object pUnkOuter,
uint dwClsContext,
[MarshalAs(UnmanagedType.LPStruct)] Guid riid);

and call it something like this

Guid CLSID_FtpProtocol = new
Guid("79eac9e3-baf9-11ce-8c82-00aa004ba90b");
Guid IID_IInternetProtocol = new
Guid("79eac9e4-baf9-11ce-8c82-00aa004ba90b");

o = CoCreateInstance( CLSID_FtpProtocol, null, 1
/*CLSCTX_INPROC_SERVER*/, IID_IInternetProtocol );



Mattias
 
Hi Igor,

Pretty impressive. That definitely sounds plausible. I wonder if MS is aware
of the issue? Is this a problem you have encountered before when using
interop?

Your post, combined with the advice from Mattias and Nicholas will
definitely help me solve this problem.

Thanks,
B.
 
Brian Rogers said:
Pretty impressive. That definitely sounds plausible. I wonder if MS is aware
of the issue? Is this a problem you have encountered before when using
interop?

No, I encountered this problem while working with APPs from C++. It's
easy to reproduce - just call CoCreateInstance with NULL outer and
asking for IUnknown. A resulting AV says it cannot dereference NULL
pointer, which I assume to be the outer.
--
With best wishes,
Igor Tandetnik

"For every complex problem, there is a solution that is simple, neat,
and wrong." H.L. Mencken
 
Brian Rogers said:
Hello everyone,

I apologize for the cross and re-post, but I am still searching for an
answer.

Why can C++ can create this object, but C# can't?

I am trying to create an instance of the default FTP asynchronous pluggable
protocol adaptor, so I can analyse the traffic between urlmon.dll (IE) and
the FTP server. The language I am attempting to use is C#.

The CLSID for the adaptor (as referenced in the protocol registry key) is
{79eac9e3-baf9-11ce-8c82-00aa004ba90b} and is stored as CLSID_FtpProtocol.

If I use the following unmanaged C++ code, I can create an instance of the
filter.

HRESULT result;
LPUNKNOWN _pUnk = NULL;
CoInitialize( NULL);
result = CoCreateInstance( CLSID_FtpProtocol,
NULL,
CLSCTX_INPROC_SERVER,
IID_IInternetProtocol,
(LPVOID*)&_pUnk);

If I use the following C# code, I receive an error. (OutOfMemoryException)

Guid IID_IInternetProtocolInfo = new
Guid("{79eac9e3-baf9-11ce-8c82-00aa004ba90b}");
objType = Type.GetTypeFromCLSID(IID_IInternetProtocolInfo);
Activator.CreateInstance(objType);

Any thoughts would be greatly appreciated.

Thanks,
Brian.
 
Back
Top