描述:
我们公司现接手一个项目,需开发一个C/S基于DCOM的软件.现在测试DCOM框架时遇到问题!如有广州并对DCOM熟悉的朋友有兴趣可加入到项目中来.如有高手能在线指导调通测试DCOM架构.可以酬谢,也可以用本ID所有积分相送,或成为个人的朋友! 项目时间紧,借此发布求援,希望能得到高手相助!谢谢!本人QQ 3962762
使用的开发平台是VS2003 VC++, OS全部是 XP PRO
目前测试所遇到的问题描述:A机器调用B机器上的ATL COM系统服务(EXE)报错.RPC 服务器不可用,但如果客户端与服务器都在同一台机器调用OK.----------已在网上查了很多贴子.以下方案都已试过无效.
1.COM服务器的代理/存根已在B机器上注册成功 regsvr32 xxxPS.DLL.(但不知道为什么在注册表中查看该存根的CLSID下的子键为InprocServer32???)
2.DCOMCNFG里面的默认启动/访问权限已设,以及服务组件的启动/访问权限都已加上EVERYON.(根据网上的贴子反复试过)
3.LAN里面的个人防火墙全部关掉.(公司没有用域,只用的是工作组)
4.在A机器上用不同XP帐号登录都试过不行.但互相PING都是OK的.
测试Server部分代码/其他大都为系统生成////////////////////////////////////
HRESULT InitializeSecurity() throw()
{
HRESULT hResult = CoInitializeSecurity(NULL, -1,
NULL, NULL, RPC_C_AUTHN_LEVEL_NONE,
RPC_C_IMP_LEVEL_IMPERSONATE, NULL,
EOAC_NONE, NULL);
return hResult;
}
测试Client部分代码.
hr = CoInitialize(NULL);
if(FAILED(hr))
{
MessageBox("组件初始化失败!");
return false;
}
//初始化安全设置
hr = CoInitializeSecurity(
NULL, //Points to security descriptor
-1, //Count of entries in asAuthSvc
NULL, //Array of names to register
NULL, //Reserved for future use
RPC_C_AUTHN_LEVEL_DEFAULT, //The default authentication level for proxies
RPC_C_IMP_LEVEL_IMPERSONATE, //RPC_C_IMP_LEVEL_IDENTIFY, //The default impersonation level for proxies
NULL, //Reserved; must be set to NULL
0, //Additional client or server-side capabilities
NULL //Reserved for future use
);
COAUTHIDENTITY author_id;
COSERVERINFO server_info;
COAUTHINFO author_info;
TCHAR user[] = _T("lanzsoft");//在本地运行,好像这里不起作用的.随便写都可以调用成功
TCHAR pass[] = _T("123456");//;
BSTR sername = L"192.168.1.4";
TCHAR szDomain[] = _T("WORKGROUP");
ZeroMemory(&author_id,sizeof(COAUTHIDENTITY));
author_id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
author_id.User = reinterpret_cast<unsigned short *>(user);
author_id.UserLength = (ULONG)_tcslen(user);
author_id.Password = reinterpret_cast<unsigned short *>(pass);
author_id.PasswordLength = (ULONG)_tcslen(pass);
author_id.Domain = reinterpret_cast<PUSHORT>(szDomain);
author_id.DomainLength = (ULONG)_tcslen(szDomain);
// author_id.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
ZeroMemory(&author_info,sizeof(COAUTHINFO));
author_info.dwAuthnSvc = RPC_C_AUTHN_WINNT;
author_info.dwAuthzSvc = RPC_C_AUTHN_NONE;
author_info.pwszServerPrincName = NULL;
author_info.dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;//RPC_C_AUTHN_LEVEL_CALL; RPC_C_AUTHN_LEVEL_CONNECT
author_info.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
author_info.dwCapabilities = EOAC_NONE;
author_info.pAuthIdentityData = &author_id;
ZeroMemory(&server_info,sizeof(COSERVERINFO));
server_info.dwReserved1 = 0;
server_info.dwReserved2 = 0;
server_info.pwszName = L"192.168.1.4";
server_info.pAuthInfo = &author_info;
//COSERVERINFO ServerInfo={0,L"larry",NULL,0};
MULTI_QI MultiQi={&IID_IUnknown,NULL,NOERROR};
hr=CoCreateInstanceEx(CLSID_SayHello,NULL,CLSCTX_REMOTE_SERVER,&server_info,1,&MultiQi);
if(FAILED(hr))
{///////////////////////远程调用这里总是RPC 服务器不可用
return false;
}
//通过IUnkonwn指针去查询接口指针,返回IAccount指针
pUnknown = (IUnknown *) MultiQi.pItf;
//pAccount = (IAccount *) MultiQi.pItf;
hr = pUnknown->QueryInterface(IID_ISayHello,(void**)&pSayHello);
//if(FAILED(hr))
//{
// MessageBox("没有查找的接口指针!");
// return false;
//}
pUnknown->Release();
解决方案1:
DCOM的权限问题主要是两个方面,一个是激活权限一个是访问权限。
首先看CoCreateInstanceEx调用成不成功,如果成功则激活权限通过
然后是接口查询,一般最容易出现的权限问题在这里,CoCreateInstanceEx返回的是代理指针,要确保代理指针有权限访问远程存根,要给代理指针赋予访问权限,如下
IUnknown *pIRewUnknown = NULL;
//取得代理的IUnkown接口
hr = qi.pItf->QueryInterface(IID_IUnknown, (void**)&pIRewUnknown);
//赋予代理指针访问访问远程存根的权限
hr = ::CoSetProxyBlanket(pIRewUnknown, -1, 0, 0, RPC_C_AUTHN_LEVEL_DEFAULT,
RPC_C_IMP_LEVEL_IMPERSONATE, &authidentity, 0);
//调用远程方法
hr = pUnknown->QueryInterface(IID_ISayHello,(void**)&pSayHello);
pUnknown->Release();
如果激活权限都通过,说明wendows权限认证这一关没过,比如windows域认证,还有服务器端的安全策略配制,等等。问题很可能出在安全策略配制中,比如不允许无密码用户登录等等。
如果以上方法都不行,就只能使用访问控制对象来解决了,访问控制对象是一个实现IAccessControl接口的com对象,通过使用访问控制对象可以最大限度解决广域网的DCOM访问问题。
没有解决不了的问题,不要急,先说清楚到底什么现象。

