我目前正在研究一個需要從另一個系統上運行的COM對象檢索數據的MFC應用程序。當兩個系統都運行Windows XP並使用相同的手動設置用戶帳戶時(即在兩個系統上都有相同的用戶名和密碼,沒有域),我們已經擁有了相同的數據交換機制,並且完全支持這種機制。問題是我試圖設置它,這樣我就可以從另一臺具有相同用戶帳戶設置的計算機訪問同一個DCOM系統,但是使用公司域用戶帳戶登錄。如何正確使用COAUTHIDENTITY模擬CoCreateInstanceEx中的其他用戶?
現在,如果我使用運行方式手動運行我的應用程序並指定替代用戶,它會生效,但我正在尋找更好的解決方案。當我在CoCreateInstanceEx中爲COSERVERINFO設置COAUTHIDENTITY時,我指定了備用帳戶的用戶名和密碼,但似乎不起作用。我嘗試了域項中的各種東西 - 遠程計算機的本地計算機的計算機名稱,並將其留空 - 但似乎沒有任何幫助。
我試圖編輯服務器計算機上的對象的DCOM權限,以允許完全訪問Everyone帳戶,但這似乎沒有幫助,並且我一直無法找到任何有關什麼是有意義的錯誤消息真的錯了。如果我可以在服務器計算機上獲得某種日誌消息,以便準確地查看使用運行方式運行它時遇到的憑據,可能會有所幫助。有人有任何想法嗎?或者,也許知道當你從非域帳戶建立DCOM連接時,系統使用域名(有幾件事暗示計算機名稱已被使用,但在我嘗試時不起作用)。
代碼如下:
COAUTHINFO AuthInfo;
COAUTHIDENTITY AuthIdentity;
COSERVERINFO ServerInfo;
MULTI_QI Results;
AuthIdentity.Domain = (unsigned short *) w_domain;
AuthIdentity.DomainLength = wcslen(w_domain);
AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
AuthIdentity.Password = (unsigned short *) w_password;
AuthIdentity.PasswordLength = wcslen(w_password);
AuthIdentity.User = (unsigned short *) w_username;
AuthIdentity.UserLength = wcslen(w_username);
AuthInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CALL;
AuthInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
AuthInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
AuthInfo.dwCapabilities = EOAC_NONE;
AuthInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
AuthInfo.pAuthIdentityData = &AuthIdentity;
AuthInfo.pwszServerPrincName = NULL;
ServerInfo.dwReserved1 = 0;
ServerInfo.dwReserved2 = 0;
ServerInfo.pAuthInfo = &AuthInfo;
ServerInfo.pwszName = w_nodename;
Results.pIID = &_uuidof(_DS_SessionContext);
Results.pItf = NULL;
Results.hr = 0;
hr = CoCreateInstanceEx(clsid, NULL, CLSCTX_ALL, &ServerInfo, (ULONG) 1, &Results);
if(FAILED(hr))
{
m_Error.Format("(0x%x) CoCreateInstanceEx for _DS_DataFrame failed.",hr);
m_Error2.Format("Make sure computer IP address is correct and connected.");
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}
pSession = (_DS_SessionContext *)Results.pItf;
hr = pSession->raw_DS_GetVersion(&DSStatus, &version);
if(FAILED(hr))
{
m_Error.Format("(0x%x)GetVersion",hr);
CoUninitialize();
UpdateData(false);
UpdateWindow();
return false;
}