Я испытываю трудности при переносе приложения на основе C ++ CryptoAPI, которое в настоящее время работает на Windows Server 2008, на Windows 8.1. Сценарий таков:
Это приложение в конечном итоге запускается WatchDog.exe, который, в свою очередь, запускается, когда компьютер запускается планировщиком задач Windows.
Планировщик задач использует следующие правила для запуска WatchDog.exe:
Сервер сидит там, никто не вошел в систему, пока в данном сценарии WatchDog.exe не запустит приложение. Журнал приложения подтверждает, что владелец процесса (GetUserName) — это тот же пользовательский планировщик задач, который используется для запуска WatchDog.exe.
Оказывается, это приложение прекрасно работает в Windows Server 2008, но в Windows 8.1 вызов CryptAcquireContext не удается с кодом возврата ERROR_FILE_NOT_FOUND (2 л). Странно то, что приложение НЕ завершится с ошибкой, если при запуске пользователь физически вошел в систему на компьютере, хотя это был не тот пользователь, который запустил приложение вручную.
Я посмотрел на документация и нашел:
«Профиль пользователя не загружен и не может быть найден. Это
происходит, когда приложение олицетворяет пользователя, например,
IUSR_ComputerName account. «
Я никогда не слышал о олицетворении, поэтому я провел исследование и нашел API LogonUser, ImpersonateLoggedOnUser а также RevertToSelf. Затем я обновил приложение следующим образом:
...
HANDLE hToken;
if (! LogonUser(L"admin", L".", L"XXXXXXXX", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hToken))
{
logger->log (_T("Error logging on."));
}
else
{
logger->log (PMLOG_LEVEL_TRACE, _T("Logged on."));
if (! ImpersonateLoggedOnUser(hToken))
{
logger->log (_T("Error impersonating."));
}
else
{
logger->log (_T("Impersonated."));
err = XXXXXXXXX(); // calls function which will execute CryptAcquireContext
if (! RevertToSelf())
{
logger->log (_T("Error reverting."));
}
else
{
logger->log (_T("Reverted."));
}
}
}
...
Выдержка с призывом к CryptAcquireContext:
...
//---------------------------------------------------------------
// Get the handle to the default provider.
if(! CryptAcquireContext(&hCryptProv, cryptContainerName, MS_ENHANCED_PROV, PROV_RSA_FULL, 0))
{
DWORD e = GetLastError();
_stprintf_s (logMsg, 1000, _T("Error %ld acquiring cryptographic provider."), e);
cRSALogger->log (logMsg);
return ERR_CCRYPT_NO_KEY_CONTAINER;
}
cRSALogger->log (_T("Cryptographic provider acquired."));
...
В результате я получил журнал:
...
[2015/01/08 20:53:25-TRACE] Logged on.
[2015/01/08 20:53:25-TRACE] Impersonated.
...
[2015/01/08 20:53:26-ERROR] Error 2 acquiring cryptographic provider.
...
[2015/01/08 20:53:26-TRACE] Reverted.
...
Это, кажется, показывает, что олицетворение работает должным образом, но я все еще получаю ошибку 2 (ERROR_FILE_NOT_FOUND) на CryptAcquireContext.
Резюме:
Любые мысли, куда я могу бежать, чтобы заставить это работать на Windows 8.1?
Заранее спасибо,
Дэн
Задача ещё не решена.