COM-серверы под разными учетными записями
От: Андрей Д  
Дата: 11.04.07 17:07
Оценка:
Всем привет!
Суть проблемы. Есть приложение, которое запускается под специально созданной локальной учетной записью Windows Z1 в виде службы Windows. Оно при своей работе использует несколько COM-объектов, внутрипроцессных и внепроцессных. В норме внепроцессные запускаются посредством системного DllHost.exe и все прекрасно. Однако, требуется некоторые из них запустить под другой учетной записью, скажем, Z2. Делаю с помощью Wizard-а ATL шаблон сервиса (службы), в нем модифицирую код функции Run():

void CServiceModule::Run()
{
USES_CONVERSION;

DWORD dwRegister=0;
IClassFactory *pClassFact=NULL;
CLSID clsCLSID;
HRESULT hr=S_OK;
WCHAR wsz[64];
_Module.dwThreadID = GetCurrentThreadId();

hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
// If you are running on NT 4.0 or higher you can use the following call
// instead to make the EXE free threaded.
// This means that calls come in on a random RPC thread
// HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);

_ASSERTE(SUCCEEDED(hr));

// This provides a NULL DACL which will allow access to everyone.
CSecurityDescriptor sd;
sd.InitializeFromThreadToken();

// Код, сделанный системой

// hr = CoInitializeSecurity(sd, -1, NULL, NULL,
// RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);

// Мой код, который, если верить статье Владислава Чистякова "Защита в DCOM/COM+", полностью отключает защиту
hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);


if(!SUCCEEDED(hr))
{
DWORD dwErr=GetLastError();
_ASSERTE(0);
}

hr = _Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE);
_ASSERTE(SUCCEEDED(hr));

// Регистрация COM-сервера. Т.е. получение его интерфейса и публикация

hr=CLSIDFromProgID(A2W("OutProcComObjecProgId.Server"), &clsCLSID);

LogEvent("CLSIDFromProgID returned %d", hr);

hr=CoGetClassObject(clsCLSID, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void**)&pClassFact);
LogEvent("CoGetClassObject returned %d", hr);


hr=CoRegisterClassObject(clsCLSID,(IUnknown*) pClassFact, CLSCTX_LOCAL_SERVER,
REGCLS_MULTIPLEUSE, &dwRegister);
LogEvent("CoRegisterClassObject returned %d", hr);



MSG msg;
while (GetMessage(&msg, 0, 0, 0))
DispatchMessage(&msg);

if(pClassFact)
pClassFact->Release();
hr=CoRevokeClassObject(dwRegister);
_Module.RevokeClassObjects();

CoUninitialize();
}
В настройках "Службы компонентов\...\Настройка DCOM" даю права на работу с этим сервисом на всех закладках Z1, указываю, что запускаться он будет под Z2. Запускаю сервис с COM-объектом, а потом основной сервис. При попытке получить интерфейс CoCreateInstance возвращает -2147024891 (0x80070005), что оначает "Отказано в доступе".
Что происходит и что делать???
С уважением, Андрей.
Всем всего наилучшего!
Андрей.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.