首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> VC >> VC 教學

跨使用者帳號的 DCOM 遠端呼叫完整設定指南

     編輯:VC 教學

核心原則

DCOM 建立在 RPC 服務之上,遠端物件在伺服器端執行並使用其系統資源,因此用戶端必須具備伺服器機器的存取權限(本地使用者或網域使用者)。

用戶端三步驟設定

  1. 取得有效認證:在遠端機器或網域建立/取得具足夠權限的使用者帳號。
  2. 以使用者權杖啟動遠端 COM 伺服器:使用 CoInitializeSecurity + CoCreateInstanceEx,傳入 COAUTHIDENTITY(含帳號/密碼/網域)與 COSERVERINFO(含伺服器 IP/名稱)。成功取得介面 Proxy。
  3. 為 Proxy 設定存取權限:呼叫 CoSetProxyBlanket 設定驗證/授權等級、模擬層級與認證資訊。此後即可透過 Proxy 呼叫方法。

伺服器端設定

呼叫 CoInitializeSecurity 設定存取權限,或使用 dcomcnfg 工具在登錄中設定既有伺服器程式的啟動/存取權限。若使用連接點,用戶端有時也需呼叫 CoInitializeSecurity。

關鍵代碼範例

CoSetProxyBlanket

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 = CoInitialize(NULL);
COAUTHIDENTITY authidentity = {0};
authidentity.User = L"administrator";
authidentity.UserLength = wcslen(authidentity.User);
authidentity.Password = L"password";
authidentity.PasswordLength = wcslen(authidentity.Password);
authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COAUTHINFO authinfo = {0};
authinfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
authinfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
authinfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_DEFAULT;
authinfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
authinfo.pAuthIdentityData = &authidentity;

COSERVERINFO si = {0};
si.pwszName = L"127.0.0.1";
si.pAuthInfo = &authinfo;

MULTI_QI qi = { &IID_ICRemoteTime, NULL, NULL };

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

hr = CoCreateInstanceEx(CLSID_CRemoteTime, NULL, CLSCTX_REMOTE_SERVER, &si, 1, &qi);
// 檢查 hr 與 qi.hr,再 QueryInterface 取得介面指標

範例 2(使用 CComBSTR 簡化字串處理)

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

COAUTHIDENTITY us = {0};
us.User = m_strName.AllocSysString();
us.Password = m_strPassword.AllocSysString();
us.Domain = m_strDomain.AllocSysString();
us.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

COAUTHINFO auth = {0};
auth.dwAuthnSvc = RPC_C_AUTHN_WINNT;
auth.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
auth.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
auth.pAuthIdentityData = &us;

COSERVERINFO si = {0};
si.pwszName = bstr.m_str; // 目標電腦名/IP
si.pAuthInfo = m_bAccess ? &auth : NULL;

MULTI_QI qi = { &__uuidof(IRemoteControl), NULL, NULL };
hr = CoCreateInstanceEx(__uuidof(RemoteControl), NULL, CLSCTX_SERVER, &si, 1, &qi);
m_pIRemoteControl = (IRemoteControl*)qi.pItf;

常見陷阱

  • 密碼長度計算錯誤:PasswordLength = wcslen(Password) 而非 User。
  • COAUTHIDENTITY 字串必須為 Unicode(SEC_WINNT_AUTH_IDENTITY_UNICODE)。
  • 防火牆封鎖 RPC 連接埠(135 及動態範圍)。
  • 伺服器端 dcomcnfg 中「啟動與啟用權限」未授予用戶帳號「本機啟動」與「遠端啟用」權限。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved