|
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) ?
|
|
|
|
|
Hi,
I am trying to use list view in a property page which is created in ATL for display in a MMC snapin. I opened the property page in the resource view,
added the list view control from the list . Now my cpp file cannot compile
and it gives me error error C2367 in the tlh file.(REdefinition of interface)
In the cpp file I found that the following line is included.
#import "C:\WINNT\System32\Comctl32.ocx" raw_interfaces_only, raw_native_types, no_namespace, named_guids
I commented out everything after "...\Comctl32.ocx" , the project builds, but the propery page does not show anything. Not even the rest of the controls in the page.
Can somebody help this novice programmer on this issue ? I would be really greatful.
Thanks,
Sameer
|
|
|
|
|
Are you calling InitCommonControls() or InitCommonControlsEx() before the listctrl gets created?
I'm an alien, I'm an alien
it's a beautiful life....
Bush
|
|
|
|
|
I called these functions but it did not work.
Actually I am trying to put list view activex control in the page.
I found the reason from somebody that properysheet
class CSnapInPropertyPageImpl is derived from CDialogImpl instead of
from CAxDialogImpl in which case it would have worked.
|
|
|
|
|
When I inserted a new JPG picture into the OLE Control, it just shown me an icon, but when i inserted a BMP picture it shown me the content of that picture. How can i insert a new JPG picture into the OLE Control and see its content not its icon
|
|
|
|
|
The following is the simplified code:
#include <objbase.h>
interface ix:IUnknown
{
virtual void __stdcall fx()=0;
};
class Try:public ix
{
public:
HRESULT __stdcall QueryInterface(IID& iid,void** ppv){return S_OK;}
virtual ULONG __stdcall AddRef(){return 0;}
virtual ULONG __stdcall Release(){return 0;}
virtual void __stdcall fx(){}
Try(){}
};
void f()
{
Try ptry;
}
--------------------Configuration: try - Win32 Debug-------
d:\files\vc\com\try\try.cpp(23) : error C2259: 'Try' : cannot instantiate abstract class due to following members:
d:\files\vc\com\try\try.cpp(7) : see declaration of 'Try'
d:\files\vc\com\try\try.cpp(23) : warning C4259: 'long __stdcall IUnknown::QueryInterface(const struct _GUID &,void ** )' : pure virtual function was not defined
d:\microsoft visual studio\vc98\include\unknwn.h(109) : see declaration of 'QueryInterface'
d:\files\vc\com\try\try.cpp(23) : error C2259: 'Try' : cannot instantiate abstract class due to following members:
d:\files\vc\com\try\try.cpp(7) : see declaration of 'Try'
d:\files\vc\com\try\try.cpp(23) : warning C4259: 'long __stdcall IUnknown::QueryInterface(const struct _GUID &,void ** )' : pure virtual function was not defined
d:\microsoft visual studio\vc98\include\unknwn.h(109) : see declaration of 'QueryInterface'
**********************************************************
I really don't know what's wrong with the code.
|
|
|
|
|
Hi,
The thing that you didn't get about COM technology is that "you will not deal with classes any more, what you have to care about is interfaces". Here you are trying to create an instance of Try class, which is wrong in COM world. You have to ask the component for a certain interface, and the component itself will create the class instance for you, and it will cast it to the required interface.
To access your component you have to make a call like this one:
{
IX *pX; //See, you are defining the interface instead of the class
HRESULT hr = CoCreateinstance(CLSID_Try, NULL, CLSCTX_SERVER, IID_IX,(void**) &pX);
pX->fx();
pX->Release();
}
Regards,
ShadiK.
Shadi Al-Kahwaji
|
|
|
|
|
Thank you for your reply.
|
|
|
|
|
I'm totally new to COM and I want to know of some good starting reference information (online articles, books, sites).
The problem I want to address is interfacing a VB application with my VC++ app. I will be sharing data between the two apps, probably in the form of a linked-list structure (on VC++ side) and an array (on the VB side.)
Thanks for the help.
Johnny
|
|
|
|
|
I am designing a module and I want to know if this is a good design or not. My conerns are that I will be conflicting with the COM threading architecture.
Could anyone tell me if this is ok? :
I have an object, IQueue which has a method IQueue::Add([in] long nID)
IQueue is an MTA, meaning that its methods could be called multiple times simaltaneusly.
long nID will be added to a vector<long>. Adding to the vector<long> is thread safe. (using my own protection mechanism)
Till there I am fine.
Now, here is where I need help.
When IQueue is initialized, I want to create a thread that will scan this vector<long>, pick up the longs from it and do something with them.
Is it OK if I create a new thread from within IQueue? (this new thread will only be accessible internally from IQueue)
Any thoughts?
Thanks!
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|
Hi,
There are two things (as I saw from what you have said) that you have to care of:
1- Once you have created a new thread (withing an MTA or STA), this new thread does not know anything about COM Runtime Environment, this means that you have to call CoInitialize(0) or CoInitializeEx(0, ..).
2- Also this new thread cannot access your Vector, you have to pass this vector to the new thread.
This is what I can say about your problem
Enjoy,
ShadiK.
Shadi Al-Kahwaji
|
|
|
|
|
1) Ok, no problem. Thanks for pointing it out.
2) No problem there, I have a mechanism to do that.
Thanks!
Jeremy.
"Hey man, Taliban, Tali me Banana."
|
|
|
|
|