Я создал Credential Manager
DLL, чтобы воспользоваться событием NPLogonNotify
. Я тестирую это на полностью исправленном экземпляре Windows 7 Ultimate
.Учетная запись диспетчера учетных записей вызывает зависание входа в систему при форсировании смены пароля
Когда пользователь регистрируется в моей реализации NPLogonNotify
, он создает пару процессов, используя CreateProcess
. Эти процессы - это приложения Windows, и все работает отлично.
Когда я заставляю пользователя менять свой пароль при следующем входе в систему, они меняют свой пароль, и система зависает на «Изменение пароля». Что-то о создании нового процесса внутри NPLoponNotify
не играет хорошо, когда пользователь меняет свой пароль.
Я проверял, что это код NPLogonNotify
, комментируя ВСЕ код в этом экспорте и тестируя изменение пароля силы. Если у меня есть весь код, который прокомментирован, смена пароля работает отлично, с кодом, который он висит бесконечно.
Ниже представлены экспортируемые функции для верительных менеджера
NPGetCaps
DWORD APIENTRY NPGetCaps(DWORD nIndex)
{
DWORD ret = 0;
switch (nIndex)
{
case WNNC_NET_TYPE:
ret = WNNC_CRED_MANAGER; // credential manager
break;
case WNNC_SPEC_VERSION:
// We are using version 5.1 of the spec.
ret = WNNC_SPEC_VERSION51;
break;
case WNNC_DRIVER_VERSION:
ret = 1; // This driver is version 1.
break;
case WNNC_START:
ret = 1; // We are already "started"
break;
}
return ret;
}
NPPasswordChangeNotify
DWORD APIENTRY NPPasswordChangeNotify(LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, DWORD dwChangeInfo)
{
return WN_SUCCESS;
}
ПРИМЕЧАНИЕ: данная функция не влияет на систему час я попытался полностью отказаться от экспорта, и я все равно получаю тот же результат.
NPLogonNotify
DWORD APIENTRY NPLogonNotify(PLUID lpLogon, LPCWSTR lpAuthentInfoType, LPVOID lpAuthentInfo, LPCWSTR lpPreviousAuthentInfoType, LPVOID lpPreviousAuthentInfo, LPWSTR lpStationName, LPVOID StationHandle, LPWSTR *lpLogonScript)
{
lpLogonScript = nullptr;
//auth type can help here to know what we're doing
if (lstrcmpi(lpAuthentInfoType, L"MSV1_0:Interactive") != 0 && lstrcmpiW(lpAuthentInfoType, L"Kerberos:Interactive"))
return WN_SUCCESS;
WCHAR filename[MAX_PATH];
GetModuleFileName(g_Module, filename, MAX_PATH);
wcsrchr(filename, L'\\')[0] = L'\0';
WCHAR exe1Filename[MAX_PATH];
wsprintf(exe1Filename, L"%lS\\exe1.exe", filename);
STARTUPINFOW si = { 0 };
PROCESS_INFORMATION pi = { 0 };
si.cb = sizeof(STARTUPINFO);
if (CreateProcess((LPWSTR)exe1Filename, nullptr, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))
{
WaitForInputIdle(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
MSV1_0_INTERACTIVE_LOGON *authInfo = (MSV1_0_INTERACTIVE_LOGON *)lpAuthentInfo;
si = { 0 };
pi = { 0 };
si.cb = sizeof(STARTUPINFO);
((PWSTR)(&((char *)authInfo->UserName.Buffer)[authInfo->UserName.Length]))[0] = L'\0';
WCHAR args[(UNLEN + 14) * 2];
wsprintf(args, L"exe2.exe %lS", authInfo->UserName.Buffer);
WCHAR exe2Path[MAX_PATH];
wsprintf(exe2Path, L"%lS\\exe2.exe", filename);
if (CreateProcess((LPWSTR)exe2Path, (LPWSTR)args, nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))
{
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
return WN_SUCCESS;
}
Я понимаю, что приведенный выше код очень плохо и не имеет никакой проверки ошибок и не является безопасным. Я делаю это как тест и учебное упражнение, чтобы узнать больше о Credential Managers.
Кто-нибудь знает, почему код внутри NPLogonNotify
отлично подходит для входа пользователя в систему, но полностью зависает системой, когда пользователь вынужден менять свой пароль при входе в систему?
висит в 'WaitForInputIdle' или в' WaitForSingleObject (pi.hProcess, INFINITE); 'Я прокомментировал только это и тест. если вешать действительно здесь (не висели, когда вы не ждете) - задача в ваших отдельных процессах. Я запускаю отладчик раньше (на текущем рабочем столе winlogon) и просматриваю под ним – RbMm
@RbMm Хорошая мысль, я возьму их и посмотрю. Я предполагал, что он даже не дошел до этого момента, поскольку на экране ничего не отображалось, но оно могло отображаться, но являлось чем-то другим или не отображалось нормально, что заставило бы его замерзнуть. Я обновлю вопрос с результатами – vane
Вы пробовали ... отладки? – conio