Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Интерфейс, полученный из метода другого интерфейса

24 views
Skip to first unread message

Dmytry Ginzburg

unread,
Mar 16, 2009, 3:32:03 PM3/16/09
to
Здравствуйте, о моногоуважаемый(ая), All!
Вот.. Hабил письмецо.. А вот, что из этого вышло:
Привет всем! Итак ситуация. Обращаюсь к DCOM-серверу, через функцию
CoCreateInstanceEx. Получаю 2 интерфейса. Делаю это так
_!--==> А тута Windows Clipboard начинается... <==--!_
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{GUID ser,browser;
int hr=CLSIDFromProgID(serv,&ser);
if(hr!=S_OK)MessageBox(Application->Handle,"Hе зарегистрирован
сервер","Ошибка",MB_OK);else{
WideString servername="***";
WideString username="Administrator";
WideString password="*****";
COSERVERINFO info;
COAUTHINFO authinfo;
authinfo.dwAuthnSvc=RPC_C_AUTHN_DEFAULT; //RPC_C_AUTHN_WINNT
authinfo.dwAuthzSvc=RPC_C_AUTHZ_DEFAULT; //RPC_C_AUTHZ_NONE
authinfo.pwszServerPrincName=NULL;
authinfo.dwAuthnLevel=RPC_C_AUTHN_LEVEL_DEFAULT; //RPC_C_AUTHN_LEVEL_NONE
authinfo.dwImpersonationLevel=RPC_C_IMP_LEVEL_IMPERSONATE;
//RPC_C_IMP_LEVEL_IDENTIFY
authinfo.dwCapabilities=EOAC_NONE;
identity.User=(unsigned short *)username.c_bstr();
identity.UserLength=username.Length();
identity.Domain=(unsigned short *)servername.c_bstr();
identity.DomainLength=servername.Length();
identity.Password=(unsigned short *)password.c_bstr();
identity.PasswordLength=password.Length();
identity.Flags=SEC_WINNT_AUTH_IDENTITY_UNICODE;
authinfo.pAuthIdentityData=&identity;
info.pwszName=servername.c_bstr();
info.dwReserved1=0;
info.dwReserved2=0;
info.pAuthInfo=&authinfo;
MULTI_QI mq[2];
mq[0].pIID=&IID_IOPCBrowseServerAddressSpace;
mq[0].pItf=0;
mq[0].hr=0;
mq[1].pIID=&IID_IOPCServer;
mq[1].pItf=0;
mq[1].hr=0;
hr=CoCreateInstanceEx(ser,0,CLSCTX_ALL,&info,2,mq);
//char *buffer=new char[255];
AnsiString s="";
if(hr)s=IntToHex(hr,8);else{opc=(IOPCBrowseServerAddressSpace *)mq[0].pItf;
opcserv=(IOPCServer *)mq[1].pItf;}
hr=CoSetProxyBlanket(opc,RPC_C_AUTHN_DEFAULT,RPC_C_AUTHZ_DEFAULT,0,RPC_C_AUTHN_
LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,&identity,EOAC_NONE);
if(hr)s=IntToHex(hr,8);else{hr=CoSetProxyBlanket(opcserv,RPC_C_AUTHN_DEFAULT,RP
C_C_AUTHZ_DEFAULT,0,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,&iden
tity,EOAC_NONE);
if(hr)s=IntToHex(hr,8);else{
unsigned long server,update;
WideString group="КПА БИП";
IUnknown *unk;
hr=opcserv->AddGroup(group.c_bstr(),1,0,1,0,0,0,&server,&update,&IID_IOPCItemMg
hr=opcserv->t,&unk);
unsigned long autnlevel;
mgt=(IOPCItemMgt *)unk;
void *u;
hr=CoSetProxyBlanket(mgt,RPC_C_AUTHN_DEFAULT,RPC_C_AUTHZ_DEFAULT,0,RPC_C_AUTHN_
LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,&identity,EOAC_NONE);
if(hr)s=IntToHex(hr,8);else{
hr=mgt->QueryInterface(IID_IOPCSyncIO,&u);//_Вот тут получаю _E_ACCESSDENIED_,
hr=mgt->если пользователь имеет пароль
io=(IOPCSyncIO *)u;
if(hr)s=IntToHex(hr,8);}}}
//if(hr&&FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS
|FORMAT_MESSAGE_ARGUMENT_ARRAY, 0, hr, 0, buffer,strlen(buffer),0))
if(s!="")MessageBox(Application->Handle,s.c_str(),"Ошибка",MB_OK);
//delete[]buffer;
}}
_!--==> А тута Windows Clipboard заканчивается... <==--!_
Как видно из кода для каждого интерфейса делаю CoSetProxyBlanket. Hо существуют
интерфейсы, которые исходя из организации сервера невозможно получить из
CoCreateInstanceEx, но можно получить используя метод полученного ранее
интерфейса. Для этих интерфейсов делаю CoSetProxyBlanket. Hо при вызове их
методов получаю E_ACCESSDENIED, если пользователь с паролем, а если
пользователь не имеет пароля, то вызов методов таких интерфейсов проходит
нормально также как и интерфейсов, полученных через CoCreateInstanceEx. Как
можно решить эту проблему.

Желаю Вам всего наилучшего, All.

0 new messages