私は現在、別のシステムで実行されている COM オブジェクトからデータを取得する必要がある MFC アプリケーションに取り組んでいます。両方のシステムが Windows XP を実行し、同じユーザー アカウントを手動でセットアップした場合 (つまり、両方のシステムで同じユーザー名とパスワード、ドメインなし)、この同じデータ交換メカニズムが既に機能し、完全にサポートされています。問題は、同じユーザー アカウントが設定されているが、企業ドメイン ユーザー アカウントでログインしている別のコンピューターから、この同じ DCOM システムにアクセスできるように設定しようとしていることです。
現在、Run As を使用してアプリケーションを手動で実行し、代替ユーザーを指定すると機能しますが、より良い解決策を探しています。CoCreateInstanceEx で COSERVERINFO の COAUTHIDENTITY を設定するときに、代替アカウントのユーザー名とパスワードを指定しましたが、うまくいかないようです。ドメイン エントリで、ローカル コンピューターのコンピューター名、リモート コンピューターのコンピューター名、空白のままにするなど、さまざまなことを試しましたが、何も解決しないようです。
サーバー コンピューター上のオブジェクトの DCOM アクセス許可を編集して、Everyone アカウントへのフル アクセスを許可しようとしましたが、効果がないようで、何が問題なのかを示す意味のあるエラー メッセージを見つけることができませんでした。サーバー コンピューターで何らかのログ メッセージを取得して、Run As を使用して実行したときにどのような資格情報が表示されるかを正確に確認できれば、おそらく役立つでしょう。誰にもアイデアはありますか?または、ドメイン以外のアカウントから 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;
}