程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 用戶名不同的計算機之間的調用dcom

用戶名不同的計算機之間的調用dcom

編輯:關於VC++

DCOM是依賴於RPC服務的,是一種分布式遠程過程(進程)調用,調用代碼在遠程主機上執行,使用遠程主機的系統資源,因此要有遠程主機所屬的訪問權限,一般來說訪問用戶應是遠程主機本地用戶或主機所屬的域用戶,所以

第一步是在遠程主機或其域上注冊(獲得)一個有足夠權限的用戶,

第二步是使用此用戶令牌激活遠程COM服務器,方法是使用CoInitializeSecurity & CoCreateInstanceEx函數(見文後例子),成功激活後就得到相關請求接口的代理,此時代理並沒有對遠程服務器訪問的權限,

第三步是為接口代理設置訪問權限,方法是使用CoSetProxyBlanket函數,此後就可以使用代理指針進行方法調用了。見文後例子

以上是客戶端要做的處理,至於服務器端,只要使用CoInitializeSecurity函數設置一下訪問許可權限就可以了(有時客戶端也要進行這一處理,比如使用了連接點),對於即存的服務器程序使用dcomcfg工具在注冊表裡設置也可以。

CoSetProxyBlanket函數調用例子:

*******************************

原例子:

IRecordServerLink* pRSL=(IRecordServerLink*)mq[0].pItf;

hr = CoSetProxyBlanket( pRSL, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
    RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, &caid, EOAC_NONE);
pRSL->Methods();

----------------------------------

修改後的例子:

hr = CoSetProxyBlanket( pAccount, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
    RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, &caid, EOAC_NONE);
pAccount->Deposit(x);

※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※

CoInitializeSecurity & CoCreateInstanceEx函數調用例子:

*********************************************************

例子1:

HRESULT hr;
hr = CoInitialize(NULL);
ASSERT(SUCCEEDED(hr));
MULTI_QI qi;
qi.pIID = &IID_ICRemoteTime;
qi.hr = NULL;
qi.pItf = NULL;
COAUTHIDENTITY authidentity;
authidentity.User = L"administrator";  ////你機子的帳號
authidentity.UserLength = wcslen(authidentity.User);
authidentity.Domain = NULL;
authidentity.DomainLength = 0;
authidentity.Password = L"";     ////密碼
authidentity.PasswordLength = wcslen(authidentity.User);
authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
COAUTHINFO authinfo = {-1, 0, 0, RPC_C_AUTHN_LEVEL_DEFAULT,
    RPC_C_IMP_LEVEL_IMPERSONATE, &authidentity, 0};
COSERVERINFO servInf;
servInf.dwReserved1 = NULL;
servInf.dwReserved2 = NULL;
// servInf.pAuthInfo = NULL;
servInf.pAuthInfo = &authinfo;
USES_CONVERSION;
servInf.pwszName = L"127.0.0.1";
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_ACCESS_CONTROL, NULL);
ASSERT(SUCCEEDED(hr));
hr = CoCreateInstanceEx(CLSID_CRemoteTime, NULL, CLSCTX_REMOTE_SERVER, &servInf, 1, &qi);
if (FAILED(hr))
{
TRACE(_T("CoCreateInstanceEx failed"));
return false;;
}
if (FAILED(qi.hr))
{
TRACE(_T("Failed to connect to server"));
return false;;
}
//通過IUnkonwn指針去查詢接口指針,返回IAccount指針
hr = pUnknown->QueryInterface(IID_ICRemoteTime,(void**)&pIRetime)

例子2:

HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);

COAUTHIDENTITY us;

us.User      = m_strName.AllocSysString();
us.UserLength   = wcslen(us.User);
us.Password    = m_strPassword.AllocSysString();
us.PasswordLength = wcslen(us.Password);
us.Domain     = m_strDomain.AllocSysString();
us.DomainLength  = wcslen(us.Domain);
us.Flags     = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COAUTHINFO auth;

auth.dwAuthnSvc      = RPC_C_AUTHN_WINNT;
auth.dwAuthzSvc      = RPC_C_AUTHZ_NONE;
auth.pwszServerPrincName = NULL;
auth.dwAuthnLevel     = RPC_C_AUTHN_LEVEL_CONNECT;
auth.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
auth.dwCapabilities    = EOAC_NONE;
auth.pAuthIdentityData  = &us;

COSERVERINFO si;
MULTI_QI   qi;

CComBSTR bstr = strComputer;
LPWSTR name  = bstr.m_str;

si.dwReserved1 = 0;
si.pwszName  = name;
si.pAuthInfo  = m_bAccess ? &auth : NULL;
si.dwReserved2 = 0;

IID iid = __uuidof(m_pIRemoteControl);
qi.pIID = &iid;
qi.pItf = NULL;

do
{
  hr = CoCreateInstanceEx(__uuidof(RemoteControl), NULL, CLSCTX_SERVER, &si, 1, &qi);
  if(FAILED(hr) || FAILED(qi.hr))
  break ;

  m_pIRemoteControl = (IRemoteControl *)qi.pItf;
}while(0);

-----------------------------------

例子3:

HRESULT hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
  RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);

COAUTHIDENTITY us;

us.User      = m_strName.AllocSysString();
us.UserLength   = wcslen(us.User);
us.Password    = m_strPassword.AllocSysString();
us.PasswordLength = wcslen(us.Password);
us.Domain     = m_strDomain.AllocSysString();
us.DomainLength  = wcslen(us.Domain);
us.Flags     = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COAUTHINFO auth;

auth.dwAuthnSvc      = RPC_C_AUTHN_WINNT;
auth.dwAuthzSvc      = RPC_C_AUTHZ_NONE;
auth.pwszServerPrincName = NULL;
auth.dwAuthnLevel     = RPC_C_AUTHN_LEVEL_CONNECT;
auth.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
auth.dwCapabilities    = EOAC_NONE;
auth.pAuthIdentityData  = &us;

MULTI_QI MultiQi={&IID_IUnknown,NULL,NOERROR};
COSERVERINFO si;
CComBSTR bstr = strComputer;
LPWSTR name  = bstr.m_str;

si.dwReserved1 = 0;
si.pwszName  = name;
si.pAuthInfo  = m_bAccess ? &auth : NULL;
si.dwReserved2 = 0;

  hr = CoCreateInstanceEx(__uuidof(RemoteControl), NULL, CLSCTX_SERVER, &si, 1, &MultiQi);

if(FAILED(hr))
{
  MessageBox("創建對象實例失敗!");
  return;
}

  //通過IUnkonwn指針去查詢接口指針,返回IAccount指針
pUnknown = (IUnknown *) MultiQi.pItf;
hr = pUnknown->QueryInterface(IID_IAccount,(void**)&pAccount);
if(FAILED(hr))
{
  MessageBox("沒有查找的接口指針!");
  return false;
}
pUnknown->Release();

  1. 上一頁:
  2. 下一頁:
欄目導航
Copyright © 程式師世界 All Rights Reserved