|
It doesn't solve my problem. The same crash will happen when the application releases smart pointers members.
|
|
|
|
|
Then call their Release() methods in your ExitInstance().
--Mike--
http://home.inreach.com/mdunn/
"The Earth is doomed." -- Rupert Giles
your with and
|
|
|
|
|
Please help! I am getting desperate.
Hello, here is my situation:
I have a normal C++ program that has an instance of a COM object (my own), IMyObject
I have another out-of-process COM server, which exposes a COM object IMyOtherObject. IMyOtherObject is held by my C++ program.
So, I end up with this in my C++ program:
void main()
{
IMyObject
IMyOtherObject
}
Now, IMyOtherObject needs to use IMyObject.
How do I pass IMyObject to IMyOtherObject?
Is this possible?
where should I look?
HELP
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|
If you are using MFC, you can use LPDISPATCH as the type in your odl file.
Use this to pass your other COM Interface
|
|
|
|
|
Hi,
If you cannot send the Interface becuase you don't find a data type to send it, then there is no problem. If you want to send IMyObject interface to IMyOtherObject interface, you have to define method to do this in IMyOtherObject like this:
STDMETHOD(SetIMyObjectInterface)(IMyObject *pMyObject);
The problem here that you might compile this using the .h and .c of the IMyObject, but you will face a problem inside the .IDL file, which is IMyObject is undeclared.
To solve this problem, move IMyOtherObject section in the IDL to the type library body:
library MYLIBLib
{
....
//Don't forget to import IMyObject type library here to define the IMyObject Interface
interface IMyOtherObject : IDispatch
{
SetIMyObjectInterface(IMyObject *pMyObject);
}
....
}
I guess this would help you to pass an com interface to another com component.
If this does not answer your question, please, re-phrase your question.
Regards,
ShadiK.
Shadi Al-Kahwaji
|
|
|
|
|
pass it as an IUnknown* then queryinterface for IMyObject when you get it.
|
|
|
|
|
I tied this (I am trying everything!)
Its the best results I got so far.
I pass the IUnkown* , and on the other side I queryinterface.
before passing IMyObject, I do this:
myObj.QueryInterface(IID_IUnknown,&pUnk);
Then I pass pUnk to IMyOtherObject.
This is how I do the queryinterface in IMyOtherObject:
pUnk->QueryInterface(__uuidof(IMyObj),reinterpret_cast _void**> &pMyObj))
However, when I queryinterface I get the error "The interface is unknown."
Am I doing it right?
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|
OK. I did some more research: (I bought Inside Distributed COM - Guy Eddon, Henry Eddon, MS Press).
A Very good book.
I came across a section: Marshalling Interface Pointers.
It says that taking an IMyObject interface pointer and return it to a client in another process is not possible. He says: "What constitutes a valid interface pointer in one apartment is complete gibberish in another."
I think will have to re-create the V-table and do some other stuff.
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|
You can generate a proxy stub DLL which will allow the interface to be marshalled. It is indeed very possible to pass interface pointers across, and it is very easy. I do it all the time.
For the answers to this, and pretty much any other question about COM, I would HIGHLY recommend Essential COM by Don Box as THE book on COM.
|
|
|
|
|
While doing some testing to make a bit of code bullet proof, I decided to use IsBadReadPtr to check if a BSTR is invalid. While everything for null and uninitialised BSTRs is fine, after calling SysFreeString, IsBadReadPtr still says that the BSTR is fine. Also multiple calls to SYsFreeString with the same BSTR succeed without error. I thought the memory was supposed to be allocated on the SysFreeString call?
Cheers,
Steve
Even if you're not paranoid, they might still be watching you.
|
|
|
|
|
IsBadReadPtr only checks that the pointer points into a valid memory page. After freeing memory the page in which the memory was may still be valid. Hence the "false" positive.
|
|
|
|
|
Does anybody have any examples of DCOM security configurations for XP in a workgroup? (Yes, they are different from 2000. The same settings I use on 2000 do not work on XP.)
I finally got the bloody thing to at least return an interface. But when I do a QueryInterface on that interface, I get E_ACCESSDENIED.
I ... AM ... GOING ... INSANE ...
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
Hi ,
I have a questtion on microsoft-word appliaction.
I need to add my own icon to the existing ms-word application and when i click on that some message box should pop up. I don't know how to manipulate the existing ms-word application. Please help me how to do this.
and one more thing when i install some application like wordweb in my system that icon automatically adding to ms-word.and i write some text into word and select that after that when i click on that icon it is trying to find the meaning of that text. It is just an .Exe application.
so plz guide me how to do this.....
If u have any examples plz send me.
waiting for your early response....
Regards,
|
|
|
|
|
Hi,
I guess what you meant by icon is an Add-In to the MS Word "Added Toolbar with icons". Ok, if this your question, then you can use the VB to create an Add-In toolbar which can be deployed and installed later on to be part of MS Word Add-Ins. You might need to try this with Visual Basic | New Project | Add-In.
Regards,
ShadiK.
Shadi Al-Kahwaji
|
|
|
|
|
Hi,
I have an ATL component.
My Client is a standard VB application.
The component fires events.
Events are directly handled by VB Client.
This works fine as long as the component
is a local server.
I want to use this component from a remote
machine..
But when I make it a remote server,
I get the error, "PERMISSION DENIED"
I tried all possible combinations in
DcomCnfg Dialog.
I specified the permissions (in Security Tab).
I tried "Interactive & Launching User" Identities
but it gives the same error.
But when I specify the Username & password of
the client machine, it creates an instance of
server on Host machine...
...But it hangs after that..
Can anyone help me out ....
Is it that one cannot use Connection points
in Dcom ...
Please some body reply to this message....
Firoz.
|
|
|
|
|
With Connection Points you have too have the right Security Setting on both machines.
Essentially it is a two way duplex communication system
Machine A must have right to Machine B
and
Machine B must have rights to Machine A
Check you security settings on both Machines
|
|
|
|
|
You can programatically correct this problem. I will try to remember to post the code I use. If you don't hear from me in a day or two, send me an email.
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
The first thing that should be done is that COM security should be turned off in the client. Of course, if your client is also acting as a server or is a DLL being loaded by another application, you might not have this option.
hResult = CoInitializeSecurity (NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY,
NULL, EOAC_NONE, NULL);
This needs to be done after you call CoInitialize or CoInitializeEx.
Next, you need a routine in your server such as the following.
inline HRESULT DtRemoveSecurity (IUnknown *pUnk)
{
HRESULT hResult;
CComPtr <IUnknown> pRealUnk;
hResult = pUnk ->QueryInterface (IID_IUnknown, (void **) &pRealUnk);
if (SUCCEEDED (hResult) && pRealUnk != pUnk)
{
hResult = CoSetProxyBlanket (pRealUnk, RPC_C_AUTHN_NONE,
RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_ANONYMOUS, 0, EOAC_NONE);
}
hResult = CoSetProxyBlanket (pUnk, RPC_C_AUTHN_NONE,
RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_ANONYMOUS, 0, EOAC_NONE);
return hResult;
}
Next thing you will need to do is modify your XXX::Advise method for your connection point. You might have to subclass the ATL routine do to this.
Inside the XXX::Advise routine, there is usally a point where the interface is queried for the actual interface needed. The code should be modified.
CComPtr <IUnknown> p;
HRESULT hResult = pUnkSink ->QueryInterface (*_piid, (void **) &p);
if (FAILED (hResult))
{
DtRemoveSecurity (pUnkSink);
hResult = pUnkSink ->QueryInterface (*_piid, (void **) &p);
if (FAILED (hResult))
return CONNECT_E_CANNOTCONNECT;
}
This code test to see if you can query the interface. If it fails then security is removed and then another attempt is made. At this stage it is important that you don't blindly remove security since that causes problems with connections on the local machine.
Now, if you are using a GIT based connection point, then after the interface is retrieved from the GIT, you will need to invoke DtRemoveSecurity on the retrieved interface. This can be done blindly on local or remote interfaces.
Hope this helps.
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
Excellent solution (about removing the security from the client), very clever, fits in with what Jeff Prosise says about connection points.
extract from Jeff Prosise article
One of the errors that newbies often experience when they first
begin tinkering with DCOM occurs when they fail to give a remote
server process permission to perform callbacks to a client.
Suppose a client on machine A launches a COM server on machine B
and receives an interface pointer in return. Then that client
passes an interface pointer of its own to the server so the
server can perform callbacks.
What's wrong with this picture? Nothing, except for the fact
that callbacks will only be permitted if the server process is
granted access permission to the client process. If the server
process is assigned the identity Mister Server, then Mister
Server must be granted access permission to the client process.
One way to grant that access permission is to have the client
process call CoInitializeSecurity. Another way is to include
Mister Server (or Everyone) in the client machine's
DefaultAccessPermission ACL.
What makes this error especially difficult to diagnose is that
if connection points are involved, the failure typically doesn't
occur when the server attempts its first callback; it occurs
when the client passes its interface pointer to the server using
IConnectionPoint::Advise. Most implementations of Advise,
including ATL's, call QueryInterface on the client. But if the
server process lacks access permissions in the client process,
QueryInterface will fail. When Advise sees QueryInterface fail,
Advise will fail, too.
The moral: If you're using connection points to facilitate
callbacks from remote servers and IConnectionPoint::Advise
returns E_ACCESSDENIED or E_OUTOFMEMORY, check the access
permissions on the client. Chances are the security principal
whose identity the server process has been assigned does not
have permission to call into the client process.
Read the full security article at
http://www.codeguru.com/activex/COMSecurity1.html
and
http://www.codeguru.com/activex/COMSecurity2.html
|
|
|
|
|
Yup, I got my info from Essential COM.
Tim Smith
Descartes Systems Sciences, Inc.
|
|
|
|
|
Thats great Tim,
Thanx a lot...
But how can I do this with a VB client...
May be, I will have to use one more component at the client side which
will talk to the remote component and simply forward the events fired by
the remote component to the VB Client.
(But then, as you said, I cannot turn off the COM security)
What can I do in this situation ??
Anyway, I will try out this...
Any other suggesion about handling the remote events directly by the
VB Client...??
coz...My client is in VB and I cannot change that...
Thanks...
Firoz
|
|
|
|
|
Hi,
DCOM is a Client calling a component on another computer called Server. When we talk about Events, the roles should be changed, the client will be the server and the server will be the client(Security wise). Goto this article, it might help you in this problem.
http://www.codeproject.com/useritems/dcomcnfg.asp
Don't forget that while configuring the client and the server, you have to give the server the required security privileges to call back the client.
Regards,
ShadiK.
Shadi Al-Kahwaji
|
|
|
|
|
Thanks Shadi...
Giving the Server the required Security Rights made it work...
|
|
|
|
|
Hi,
I have an MFC application (exe) containing an ATL COM object (ATL support added to the project). that I want to be able to use from another application. I have created a proxy/stub dll and registered both in the registry but when I try to create an instance of the object it returns E_FAIL. What could I be doing wrong?
Johannes
|
|
|
|
|
Start from the top
Have you called
if (!AfxOleInit())
return TRUE;
from your MFC app (called from InitInstance) ?
|
|
|
|
|