Skip to content

Commit

Permalink
CP Login screen fixes, last username and Win 10 workaround
Browse files Browse the repository at this point in the history
- if a login has been denied the CP should display
- the last username correctly (if enabled)
- and Win 10 needed a workaround to refresh the login screen
  • Loading branch information
MutonUfoAI committed Oct 17, 2017
1 parent 1f36ec9 commit e6a8145
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 20 deletions.
72 changes: 58 additions & 14 deletions pGina/src/CredentialProvider/Credential.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,19 +519,7 @@ namespace pGina
{
m_loginResult.Message(L"Plugins did not provide a specific error message");
}
if (pGina::Registry::GetBool(L"LastUsernameEnable", false))
{
m_fields->fields[m_fields->usernameFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_NONE;
m_fields->fields[m_fields->passwordFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_FOCUSED;
}
else
{
ClearZeroAndFreeFields(CPFT_EDIT_TEXT, false);
m_fields->fields[m_fields->usernameFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_FOCUSED;
m_fields->fields[m_fields->passwordFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_NONE;
}
ClearZeroAndFreeFields(CPFT_PASSWORD_TEXT, false);


if (hThread_dialog != NULL)
{
Credential::Thread_dialog_close(hThread_dialog);
Expand Down Expand Up @@ -606,10 +594,39 @@ namespace pGina
{
BlockInput(false);
}
ClearZeroAndFreeAnyTextFields(true);

if (pGina::Registry::GetBool(L"LastUsernameEnable", false))
{
std::wstring sessionUname = pGina::Registry::GetString( L"LastUsername", L"");
if (!sessionUname.empty())
{
m_fields->fields[m_fields->usernameFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_NONE;
m_fields->fields[m_fields->passwordFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_FOCUSED;
}
else
{
ClearZeroAndFreeFields(CPFT_EDIT_TEXT, false);
m_fields->fields[m_fields->usernameFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_FOCUSED;
m_fields->fields[m_fields->passwordFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_NONE;
}
}
else
{
ClearZeroAndFreeFields(CPFT_EDIT_TEXT, false);
m_fields->fields[m_fields->usernameFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_FOCUSED;
m_fields->fields[m_fields->passwordFieldIdx].fieldStatePair.fieldInteractiveState = CPFIS_NONE;
}
ClearZeroAndFreeFields(CPFT_PASSWORD_TEXT, false);

*pcpgsr = CPGSR_NO_CREDENTIAL_FINISHED;
*pcpsiOptionalStatusIcon = CPSI_ERROR;

// Win 10 Workarround to redraw the CP after an error
if (Credential::ISwin10())
{
Provider::m_redraw = true;
}

return S_FALSE;
}

Expand Down Expand Up @@ -1090,5 +1107,32 @@ namespace pGina
WaitForSingleObject(thread, 1000);
CloseHandle(thread);
}

// https://stackoverflow.com/questions/36543301/detecting-windows-10-version/36543774#36543774
BOOL Credential::ISwin10()
{
RTL_OSVERSIONINFOW rovi = { 0 };
HMODULE hMod = ::GetModuleHandle(L"ntdll.dll");
if (hMod)
{
Credential::RtlGetVersionPtr fxPtr = (Credential::RtlGetVersionPtr)::GetProcAddress(hMod, "RtlGetVersion");
if (fxPtr != nullptr)
{
rovi.dwOSVersionInfoSize = sizeof(rovi);
if (fxPtr(&rovi) != 0)
{
rovi.dwMajorVersion = 10;
}
}
FreeLibrary(hMod);
}

if (rovi.dwMajorVersion == 10)
{
return true;
}

return false;
}
}
}
4 changes: 3 additions & 1 deletion pGina/src/CredentialProvider/Credential.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ namespace pGina
DWORD usageFlags, const wchar_t *username, const wchar_t *password);

virtual void ServiceStateChanged(bool newState);


typedef NTSTATUS(WINAPI* RtlGetVersionPtr)(PRTL_OSVERSIONINFOW);
BOOL ISwin10();
private:
void ClearZeroAndFreeAnyPasswordFields(bool updateUi);
void ClearZeroAndFreeAnyTextFields(bool updateUi);
Expand Down
18 changes: 13 additions & 5 deletions pGina/src/CredentialProvider/Provider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ namespace pGina
{
namespace CredProv
{
/*static */ bool Provider::m_redraw;

IFACEMETHODIMP Provider::QueryInterface(__in REFIID riid, __deref_out void **ppv)
{
// And more crazy ass v-table madness, yay COM again!
Expand All @@ -62,7 +64,13 @@ namespace pGina

IFACEMETHODIMP_(ULONG) Provider::AddRef()
{
return InterlockedIncrement(&m_referenceCount);
// Win 10 workaround to redraw the CP after an error
if (m_redraw)
{
m_redraw = false;
m_logonUiCallbackEvents->CredentialsChanged(m_logonUiCallbackContext);
}
return InterlockedIncrement(&m_referenceCount);
}

IFACEMETHODIMP_(ULONG) Provider::Release()
Expand Down Expand Up @@ -226,16 +234,16 @@ namespace pGina
}

return result;
}
}

IFACEMETHODIMP Provider::Advise(__in ICredentialProviderEvents* pcpe, __in UINT_PTR upAdviseContext)
{
// If we already have a callback handle, release our reference to it
UnAdvise();

// Store what we've been given
m_logonUiCallbackEvents = pcpe;
m_logonUiCallbackContext = upAdviseContext;

// If we already have a callback handle, release our reference to it
UnAdvise();

// Up ref count as we hold a pointer to this guy
if(m_logonUiCallbackEvents)
Expand Down
1 change: 1 addition & 0 deletions pGina/src/CredentialProvider/Provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ namespace pGina

virtual void ServiceStateChanged(bool newState);
CREDENTIAL_PROVIDER_USAGE_SCENARIO m_usageScenario;
static bool m_redraw;
protected:
Provider();
__override ~Provider();
Expand Down

0 comments on commit e6a8145

Please sign in to comment.