How to call COM+ remotely with anonymous user
The purpose of this tutorial is to give you an idea on how to call the COM+ server remotely. I’m not going to go into the depths of COM+ details or how to develop COM+, this tutorial is designed to show 3 ways on how to call COM+ server with VC++.
Environment: Windows 2000 for server side, Windows XP for client side
Step 1: Setting COM+ security on server side
If the client and server are in same domain, we only need to grant “Access” and “Launch” permissions to Domain Users. Now we hope to call the COM+ component out of domain, this could be anonymous access.
1. Configure the COM+ security
1) Uncheck "Enforce access checks for this application"
2) Check "Perform access checks only at the process level......"
3) "Authentication level for calls: None"
4) "Impersonation level: Anonymous"
2. Enable “guest” account for windows.
Step 2: Call the COM+ remotely
Method 1: Export proxy from server side and then install it on client side
1. On the server side, in “Component Services”, right click your COM+ application and select “Export…”
2. In the “COM Application Export Wizard”, select type as “Application proxy”, it will produce a *.msi file.
3. Install the *.msi file on the client side
Then, you can call this COM+ just as installed on localhost. Here’s the sample code.
void main(void)
{
// Declare and HRESULT and a pointer to the Simple_ATL interface
HRESULT hr;
ISimpleClass *IS = NULL;
// Now we will intilize COM
hr = CoInitialize(0);
// Use the SUCCEDED macro and see if we can get a pointer to
// the interface
if(SUCCEEDED(hr))
{
hr = CoCreateInstance( CLSID_SimpleClass, NULL, CLSCTX_REMOTE_SERVER, IID_ISimpleClass, (void**) &IS);
if(SUCCEEDED(hr))
{
BSTR ReturnValue;
hr = IS->HelloWorld(&ReturnValue);
char* pValue=_com_util::ConvertBSTRToString(ReturnValue);
cout << pValue << endl;
hr = IS->Release();
}
else
{
printf("CreateInstance Error!Error Code:%x\n",hr);
}
}
// Uninitialize COM
CoUninitialize();
}
Method 2: Register the COM+ dll on client side with “RemoteServername”
1. Register the dll as DCOM: regsvr32 <yourcom.dl>
2. Search the DCOM component in registry, find the CLSID of your COM dll
3. Under the CLSID , Create a Key named "AppID", and set the value as same as the value of CLSID
4. Delete the value of CLSID\InprocServer32
5. Add the AppID of step 3 under HKEY_CLASSES_ROOT\AppID
6. Add "RemoteServerName" to the to HKEY_CLASSES_ROOT\AppID\{YourAppID}, the value is the remote server's name
Here’s the example of the registry key settings.
---------------------------------------------------------------------------
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\AppID\{23F55D14-50A5-45E1-B8EA-FBE3E789BA97}]
@="TestCom.SimpleClass"
"RemoteServerName"="zx-win2k02"
[HKEY_CLASSES_ROOT\CLSID\{23F55D14-50A5-45E1-B8EA-FBE3E789BA97}]
@="SimpleClass Class"
"AppID"="{23F55D14-50A5-45E1-B8EA-FBE3E789BA97}"
[HKEY_CLASSES_ROOT\CLSID\{23F55D14-50A5-45E1-B8EA-FBE3E789BA97}\InprocServer32]
@=""
"ThreadingModel"="Apartment"
-------------------------------------------------------------
The source code is as same as Method 1.
Method 3: Call the COM+ remotely with CoCreateInstanceEx
1. Register the dll as DCOM: regsvr32 <yourcom.dl>
2. Write the source code with CoCreateInstanceEx, and specify the remote server name in source code. Here’s the example.
void main(void)
{
HRESULT hr;
ISimpleClass *pI=NULL;
COSERVERINFO sin,*sinptr;
MULTI_QI mqi;
mqi.pIID=&IID_ISimpleClass;
mqi.hr=0;
mqi.pItf=0;
COAUTHINFO authInfo;
authInfo.dwAuthnSvc = RPC_C_AUTHN_NONE;
authInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
……
sin.dwReserved1=0;
sin.dwReserved2=0;
sin .pwszName=L"zx-win2k02";//define the remote server name here
sin.pAuthInfo=&authInfo;
sinptr=&sin;
hr=CoInitialize(0);
if(SUCCEEDED(hr))
{
hr=CoCreateInstanceEx(CLSID_SimpleClass,
NULL,
CLSCTX_REMOTE_SERVER,
sinptr,
1,
&mqi
);
if(SUCCEEDED(hr))
{
pI=(ISimpleClass*)mqi.pItf;
BSTR bsReturnValue;
pI->HelloWorld(&bsReturnValue);
char* pValue=_com_util::ConvertBSTRToString(bsReturnValue);
printf("%s\n",pValue);
delete pValue;
}
else
{
printf("CreateInstance Error!Error Code:%x\n",hr);
}
}
References
Client/Server connection using DCOM, with anonymous access: https://www.codeproject.com/KB/COM/clientserverwithdcom.aspx
DCOM Architecture: https://msdn.microsoft.com/en-us/library/ms809311.aspx
COM+ (Component Services) : https://msdn.microsoft.com/en-us/library/ms685978(VS.85).aspx
CoCreateInstanceEx Function: https://msdn.microsoft.com/en-us/library/ms680701(VS.85).aspx
CoCreateInstance Function: https://msdn.microsoft.com/en-us/library/ms686615(VS.85).aspx
Regards,
Zhixing Lv
Comments
- Anonymous
May 03, 2009
PingBack from http://asp-net-hosting.simplynetdev.com/how-to-call-com-remotely-with-anonymous-user/