diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/auth/Loginbox/popupPasscode.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/auth/Loginbox/popupPasscode.cpp')
-rw-r--r-- | Src/auth/Loginbox/popupPasscode.cpp | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/Src/auth/Loginbox/popupPasscode.cpp b/Src/auth/Loginbox/popupPasscode.cpp new file mode 100644 index 00000000..583a817d --- /dev/null +++ b/Src/auth/Loginbox/popupPasscode.cpp @@ -0,0 +1,405 @@ +#include "./popupPasscode.h" +#include "./common.h" +#include "./loginNotifier.h" +#include "./dataCredentials.h" +#include "./editboxExtender.h" + +#include "../resource.h" +#include "../api.h" +#include "../api_auth.h" + +#include <windows.h> +#include <commctrl.h> +#include <strsafe.h> + +#define MAX_PASSCODE_LENGTH 6 +#define MIN_PASSCODE_LENGTH 6 + +#define TIMER_UPDATETITLE_ID 14 +#define TIMER_UPDATETITLE_DELAY 50 + +static HRESULT CALLBACK LoginPopupPasscode_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance) +{ + if (NULL == instance) return E_POINTER; + if (NULL == hwnd) return E_INVALIDARG; + + *instance = new LoginPopupPasscode(hwnd); + if (NULL == instance) return E_OUTOFMEMORY; + + return S_OK; +} + +LoginPopupPasscode::LoginPopupPasscode(HWND hwnd) + : LoginPopup(hwnd, -1, MAKEINTRESOURCE(IDS_POPUP_PASSCODE_TITLE)), + loginData(NULL), message(NULL), messageType(-1) +{ +} + +LoginPopupPasscode::~LoginPopupPasscode() +{ + if (NULL != loginData) + loginData->Release(); + + LoginBox_FreeString(message); +} + +HWND LoginPopupPasscode::CreatePopup(HWND hParent, LoginData *loginData) +{ + LoginDataCredentials *credentials; + if (NULL == loginData || + FAILED(loginData->QueryInterface(IID_LoginDataCredentials, (void**)&credentials))) + { + return NULL; + } + + HWND hwnd = LoginPopup::CreatePopup(MAKEINTRESOURCE(IDD_POPUP_PASSCODE), hParent, (LPARAM)credentials, LoginPopupPasscode_CreateInstance); + credentials->Release(); + return hwnd; +} + +void LoginPopupPasscode::UpdateLayout(BOOL fRedraw) +{ + LoginPopup::UpdateLayout(fRedraw); + + RECT rect; + if (FALSE == GetInfoRect(&rect)) return; + + const INT szButtons[] = { IDOK, }; + const INT szControls[] = { IDC_PASSCODE_TITLE, IDC_PASSCODE_EDIT, IDC_PASSCODE_HINT, }; + + HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls) + ARRAYSIZE(szButtons)); + if (NULL == hdwp) return; + + hdwp = LayoutButtons(hdwp, szButtons, ARRAYSIZE(szButtons), fRedraw, NULL); + + LONG top = rect.top; + RECT controlRect; + + for(INT i = 0; i < ARRAYSIZE(szControls); i++) + { + HWND hControl = GetDlgItem(hwnd, szControls[i]); + if (NULL == hControl || FALSE == GetWindowRect(hControl, &controlRect)) + continue; + + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&controlRect, 2); + + hdwp = DeferWindowPos(hdwp, hControl, NULL, + rect.left, top, rect.right - rect.left, controlRect.bottom - controlRect.top, + SWP_NOACTIVATE | SWP_NOZORDER); + + if (NULL == hdwp) + return; + + top += controlRect.bottom - controlRect.top; + + switch(szControls[i]) + { + case IDC_PASSCODE_TITLE: top += 2; break; + } + + } + + + + EndDeferWindowPos(hdwp); +} + + +void LoginPopupPasscode::EndDialog(INT_PTR code) +{ + if (IDOK == code) + { + code = -1; + if (NULL != loginData) + { + HWND hEdit = GetDlgItem(hwnd, IDC_PASSCODE_EDIT); + if (NULL != hEdit) + { + WCHAR szBuffer[64] = {0}; + GetWindowText(hEdit, szBuffer, ARRAYSIZE(szBuffer)); + if(SUCCEEDED(loginData->SetPasscode(szBuffer))) + code = IDOK; + } + } + } + + NPPNRESULT result; + result.exitCode = code; + result.loginData = loginData; + if (NULL != result.loginData) + result.loginData->AddRef(); + + SendNotification(NPPN_RESULT, (NMHDR*)&result); + + if (NULL != result.loginData) + result.loginData->Release(); + + LoginPopup::EndDialog(code); +} + +BOOL LoginPopupPasscode::Validate() +{ + BOOL validatedOk = TRUE; + + HWND hEdit = GetDlgItem(hwnd, IDC_PASSCODE_EDIT); + if (NULL == hEdit) + { + SetAlert(NLNTYPE_ERROR, MAKEINTRESOURCE(IDS_ERR_UNEXPECTED)); + validatedOk = FALSE; + } + else + { + INT cchText = (INT)SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0L); + if (cchText < MIN_PASSCODE_LENGTH || cchText > MAX_PASSCODE_LENGTH) + { + WCHAR szBuffer[256] = {0}, szTemplate[256] = {0}; + WASABI_API_LNGSTRINGW_BUF(IDS_ERR_PASSCODE_BADLENGTH_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, MAX_PASSCODE_LENGTH); + SetAlert(NLNTYPE_ERROR, szBuffer); + validatedOk = FALSE; + } + else + { + WCHAR szPasscode[MAX_PASSCODE_LENGTH + 1] = {0}; + WORD szType[MAX_PASSCODE_LENGTH] = {0}; + SendMessage(hEdit, WM_GETTEXT, (WPARAM)ARRAYSIZE(szPasscode), (LPARAM)szPasscode); + if (FALSE != GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, szPasscode, cchText, szType)) + { + for(INT i = 0; i < cchText; i++) + { + if (0 == (C1_DIGIT & szType[i])) + { + SetAlert(NLNTYPE_ERROR, MAKEINTRESOURCE(IDS_ERR_PASSCODE_ONLYDIGITS)); + validatedOk = FALSE; + break; + } + } + } + else + { + SetAlert(NLNTYPE_ERROR, MAKEINTRESOURCE(IDS_ERR_UNEXPECTED)); + validatedOk = FALSE; + } + } + } + + UpdateTitle(TRUE); + return validatedOk; +} + +BOOL LoginPopupPasscode::OnInitDialog(HWND hFocus, LPARAM param) +{ + loginData = (LoginDataCredentials*)param; + if (NULL != loginData) + loginData->AddRef(); + + if (NULL != loginData) + { + LPCWSTR pcode = loginData->GetPasscode(); + if (NULL != pcode && L'\0' != *pcode) + { + SetAlert(NLNTYPE_ERROR, MAKEINTRESOURCE(IDS_ERR_PASSCODE_INVALID)); + UpdateTitle(FALSE); + } + } + + HWND hEdit = GetDlgItem(hwnd, IDC_PASSCODE_EDIT); + if (NULL != hEdit) + { + EditboxExtender_AttachWindow(hEdit); + } + + HWND hHint = GetDlgItem(hwnd, IDC_PASSCODE_HINT); + if (NULL != hHint) + { + WCHAR szBuffer[128], szTemplate[128] = {0}; + WASABI_API_LNGSTRINGW_BUF(IDS_PASSCODE_EDIT_HINT, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, MAX_PASSCODE_LENGTH); + SendMessage(hHint, WM_SETTEXT, 0, (LPARAM)szBuffer); + } + + return LoginPopup::OnInitDialog(hFocus, param); +} + +void LoginPopupPasscode::OnCommand(UINT commandId, UINT eventType, HWND hControl) +{ + if (IDOK == commandId && FALSE == Validate()) + return; + + LoginPopup::OnCommand(commandId, eventType, hControl); +} + +LRESULT LoginPopupPasscode::OnNotify(UINT controlId, const NMHDR *pnmh) +{ + switch(controlId) + { + case IDC_PASSCODE_EDIT: + switch(pnmh->code) + { + case NM_CHAR: + return OnEditboxChar(pnmh->hwndFrom, ((NMCHAR*)pnmh)->ch); + case NM_KEYDOWN: + return OnEditboxKey(pnmh->hwndFrom, ((NMKEY*)pnmh)->nVKey, ((NMKEY*)pnmh)->uFlags); + case EENM_PASTE: + return OnEditboxPaste(pnmh->hwndFrom, ((EENMPASTE*)pnmh)->text); + } + return 0; + } + return LoginPopup::OnNotify(controlId, pnmh); +} + +HBRUSH LoginPopupPasscode::OnGetStaticColor(HDC hdc, HWND hControl) +{ + HBRUSH hb = LoginPopup::OnGetStaticColor(hdc, hControl); + + INT controlId = (NULL != hControl) ? (INT)GetWindowLongPtr(hControl, GWLP_ID) : 0; + switch(controlId) + { + case IDC_PASSCODE_HINT: + SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); + break; + } + + return hb; +} + + +LRESULT LoginPopupPasscode::OnEditboxKey(HWND hEdit, UINT vKey, UINT flags) +{ + if (-1 != alertType) + { + RemoveAlert(); + SetTimer(hwnd, TIMER_UPDATETITLE_ID, TIMER_UPDATETITLE_DELAY, NULL); + } + return 0L; +} + +LRESULT LoginPopupPasscode::OnEditboxChar(HWND hEdit, UINT ch) +{ + if (VK_BACK == ch) + return FALSE; + + BOOL filtered = FALSE; + + INT selBegin, selEnd; + SendMessage(hEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + + INT cchText = (INT)SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0L); + if (selBegin == selEnd && cchText >= MAX_PASSCODE_LENGTH) + { + WCHAR szBuffer[256] = {0}, szTemplate[256] = {0}; + WASABI_API_LNGSTRINGW_BUF(IDS_ERR_PASSCODE_BADLENGTH_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, MAX_PASSCODE_LENGTH); + SetAlert(NLNTYPE_WARNING, szBuffer); + KillTimer(hwnd, TIMER_UPDATETITLE_ID); + UpdateTitle(TRUE); + filtered = TRUE; + } + else + { + WORD charType; + if (FALSE != GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, (WCHAR*)&ch, 1, &charType)) + { + if (0 == (C1_DIGIT & charType)) + { + SetAlert(NLNTYPE_WARNING, MAKEINTRESOURCE(IDS_ERR_PASSCODE_ONLYDIGITS)); + KillTimer(hwnd, TIMER_UPDATETITLE_ID); + UpdateTitle(TRUE); + filtered = TRUE; + } + } + } + + return filtered; +} + +LRESULT LoginPopupPasscode::OnEditboxPaste(HWND hEdit, LPCWSTR pszText) +{ + if (NULL == pszText) + return TRUE; + + INT cchText = lstrlen(pszText); + if (0 == cchText) return TRUE; + + WCHAR szBuffer[MAX_PASSCODE_LENGTH + 1] = {0}; + INT iBuffer = 0; + + WORD charType; + + BOOL validatedOk = TRUE; + + + INT maxSize = MAX_PASSCODE_LENGTH - (INT)SendMessage(hEdit, WM_GETTEXTLENGTH, 0, 0L); + if (maxSize < MAX_PASSCODE_LENGTH) + { + INT selBegin, selEnd; + SendMessage(hEdit, EM_GETSEL, (WPARAM)&selBegin, (LPARAM)&selEnd); + selEnd -= selBegin; + if (selEnd < 0) selEnd = -selBegin; + maxSize += selEnd; + } + for (INT i =0; i <cchText; i++) + { + if (FALSE == GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, &pszText[i], 1, &charType)) + { + SetAlert(NLNTYPE_WARNING, MAKEINTRESOURCE(IDS_ERR_UNEXPECTED)); + validatedOk = FALSE; + break; + } + else if (0 == (C1_DIGIT & charType)) + { + if (0 == ((C1_SPACE | C1_CNTRL | C1_BLANK) & charType)) + { + SetAlert(NLNTYPE_WARNING, MAKEINTRESOURCE(IDS_ERR_PASSCODE_ONLYDIGITS)); + validatedOk = FALSE; + break; + } + } + else + { + if (iBuffer > maxSize) + { + WCHAR szBuffer[256], szTemplate[256] = {0}; + WASABI_API_LNGSTRINGW_BUF(IDS_ERR_PASSCODE_BADLENGTH_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate)); + StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, MAX_PASSCODE_LENGTH); + SetAlert(NLNTYPE_WARNING, szBuffer); + validatedOk = FALSE; + break; + } + else + { + szBuffer[iBuffer] = pszText[i]; + iBuffer++; + } + } + } + + if(FALSE != validatedOk) + { + szBuffer[iBuffer] = L'\0'; + SendMessage(hEdit, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)szBuffer); + } + else + { + UpdateTitle(TRUE); + } + + return TRUE; +} + +INT_PTR LoginPopupPasscode::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + case WM_TIMER: + switch(wParam) + { + case TIMER_UPDATETITLE_ID: + KillTimer(hwnd, wParam); + UpdateTitle((-1 != alertType)); + return TRUE; + } + break; + } + return LoginPopup::DialogProc(uMsg, wParam, lParam); +} |