From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- Src/auth/Loginbox/loginbox.cpp | 2804 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2804 insertions(+) create mode 100644 Src/auth/Loginbox/loginbox.cpp (limited to 'Src/auth/Loginbox/loginbox.cpp') diff --git a/Src/auth/Loginbox/loginbox.cpp b/Src/auth/Loginbox/loginbox.cpp new file mode 100644 index 00000000..9161c734 --- /dev/null +++ b/Src/auth/Loginbox/loginbox.cpp @@ -0,0 +1,2804 @@ +#include "./common.h" +#include "./loginBox.h" + +#include "./loginProvider.h" +#include "./providerLoader.h" +#include "./providerEnumerator.h" +#include "./loginTemplate.h" +#include "./loginCommand.h" +#include "./loginPage.h" +#include "./loginData.h" +#include "./loginCredentials.h" +#include "./loginCurtain.h" +#include "./loginNotifier.h" +#include "./loginPopup.h" +#include "./popupAgreement.h" +#include "./popupPasscode.h" +#include "./popupMessage.h" +#include "./pageEmpty.h" +#include "./pageError.h" +#include "./animation.h" +#include "./loginStatus.h" +#include "./providerOperation.h" +#include "./loginConfig.h" +#include "./loginTab.h" +#include "./loginGui.h" + +#include "./download.h" +#include "./downloadResult.h" +#include "./imageCache.h" + +#include "../resource.h" + +#include "../api.h" +#include "../api_auth.h" +#include "../../nu/windowsTheme.h" +#include "../../winamp/commandLink.h" +#include "../../ombrowser/ifc_omcacherecord.h" + + +#include +#include +#include +#include +#include + +#define PROVIDERLIST_URL L"http://client.winamp.com/data/loginproviders" +//#define PROVIDERLIST_URL L"http://dl.getdropbox.com/u/1994752/loginProviders.xml" + +// max mini in dpi +#define LOGINBOX_MINWIDTH 153 +#define LOGINBOX_MINHEIGHT 140 +#define LOGINBOX_MAXWIDTH 800 +#define LOGINBOX_MAXHEIGHT 420 + +#define NLBS_MODAL 0x00010000 + +typedef struct __LOGINBOXCREATEPARAM +{ + HWND hOwner; + api_auth *auth; + UINT style; + const GUID *pRealm; +} LOGINBOXCREATEPARAM; + + +#define PROVIDEROP_UPDATE 0 +#define PROVIDEROP_REMOVE 1 + +typedef struct __LOGINBOX +{ + api_auth *auth; + UINT style; + GUID realm; + RECT gripRect; + LoginDownloadResult *providerUpdate; + LoginResult *loginResult; + LoginStatus *loginStatus; + LoginProviderOperation *providerOp; + BOOL agreementOk; + RECT buttonMargins; + LONG buttonHeight; + LONG buttonSpace; + LONG buttonTop; + RECT minmaxInfo; + + LoginImageCache *imageCache; +} LOGINBOX; + +#define TIMER_ID_CHECKIMAGES 20 +#define TIMER_DELAY_CHECKIMAGES 25 + +typedef struct __LOGINBOXFIND +{ + HWND hwnd; + WCHAR buffer[32]; + GUID realm; +} LOGINBOXFIND; + + +#define LOGINBOX_PROP L"NullsoftAuthLoginBoxProp" +#define GetLoginBox(__hwnd) ((LOGINBOX*)GetProp(__hwnd, LOGINBOX_PROP)) + +#define IDC_TABFRAME 10000 +#define IDC_ACTIVEPAGE 10001 +#define IDC_NOTIFIER 10002 +#define IDC_CURTAIN 10003 +#define IDC_POPUPAGREEMENT 10004 +#define IDC_POPUPPASSCODE 10005 +#define IDC_POPUPPROVIDEROP 10006 + +static INT_PTR CALLBACK LoginBox_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); + +static BOOL LoginBox_InitCreateParam(LOGINBOXCREATEPARAM *param, api_auth *auth, const GUID *pRealm, HWND hOwner, UINT style) +{ + if (NULL == param) + return FALSE; + + ZeroMemory(param, sizeof(LOGINBOXCREATEPARAM)); + + param->style = style; + param->hOwner = hOwner; + param->pRealm = pRealm; + param->auth = auth; + + if (NULL == auth) + return FALSE; + + return TRUE; +} + +HWND LoginBox_CreateWindow(api_auth *auth, const GUID *pRealm, HWND hOwner, UINT fStyle) +{ + LOGINBOXCREATEPARAM param; + if (FALSE == LoginBox_InitCreateParam(¶m, auth, pRealm, hOwner, (0x0000FFFF & fStyle))) + return NULL; + + return WASABI_API_CREATEDIALOGPARAMW(IDD_LOGINBOX, hOwner, LoginBox_DialogProc, (LPARAM)¶m); +} + +INT_PTR LoginBox_Show(api_auth *auth, const GUID *pRealm, HWND hOwner, UINT fStyle) +{ + LOGINBOXCREATEPARAM param; + if (FALSE == LoginBox_InitCreateParam(¶m, auth, pRealm, hOwner, (0x0000FFFF & fStyle) | NLBS_MODAL)) + return -1; + + INT_PTR result = WASABI_API_DIALOGBOXPARAMW(IDD_LOGINBOX, hOwner, LoginBox_DialogProc, (LPARAM)¶m); + + return result; +} + +static BOOL CALLBACK LoginBox_WindowEnumerator(HWND hwnd, LPARAM lParam) +{ + LOGINBOXFIND *find = (LOGINBOXFIND*)lParam; + + if (0 != GetClassName(hwnd, find->buffer, ARRAYSIZE(find->buffer)) && + CSTR_EQUAL == CompareString(CSTR_INVARIANT, 0, L"#32770", -1, find->buffer, -1)) + { + LOGINBOX *login = GetLoginBox(hwnd); + if (NULL != login && IsEqualGUID(find->realm, login->realm)) + { + find->hwnd = hwnd; + return FALSE; + } + } + return TRUE; +} + +HWND LoginBox_FindActive(const GUID *pRealm) +{ + LOGINBOXFIND find; + ZeroMemory(&find, sizeof(find)); + find.realm = (NULL == pRealm) ? GUID_NULL : *pRealm; + + EnumWindows(LoginBox_WindowEnumerator, (LPARAM)&find); + + return find.hwnd; +} + +static void LoginBox_ShowNotifier(HWND hwnd, INT durationMs) +{ + if (NULL == hwnd) return; + HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER); + if (NULL == hNotifier) return; + + LONG targetHeight = (LONG)LoginNotifier_GetIdealHeight(hNotifier); + RECT notifierRect; + GetWindowRect(hNotifier, ¬ifierRect); + LONG currentHeight = notifierRect.bottom - notifierRect.top; + LONG notifierWidth = notifierRect.right - notifierRect.left; + + if (currentHeight < targetHeight) + { + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)¬ifierRect, 2); + + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + RECT pageRect; + if (NULL != hPage) + { + GetWindowRect(hPage, &pageRect); + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&pageRect, 2); + } + + LONG pageWidth = pageRect.right - pageRect.left; + LONG pageHeight = pageRect.bottom - pageRect.top; + + UINT pageStyle = (NULL != hPage) ? GetWindowStyle(hPage) : 0; + if (0 != (WS_VISIBLE & pageStyle)) + SetWindowLongPtr(hPage, GWL_STYLE, pageStyle & ~WS_VISIBLE); + + UINT notifierStyle = GetWindowStyle(hNotifier); + if (0 != (WS_VISIBLE & notifierStyle)) + SetWindowLongPtr(hNotifier, GWL_STYLE, notifierStyle & ~WS_VISIBLE); + + SetWindowPos(hNotifier, NULL, 0, 0, notifierWidth, targetHeight, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOCOPYBITS); + + + if (durationMs > 0) + { + HDC targetDc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS); + if (NULL != targetDc) + { + HDC composeDc = CreateCompatibleDC(targetDc); + if (NULL != composeDc) + { + HBITMAP composeBmp = CreateCompatibleBitmap(targetDc, + (notifierWidth > pageWidth) ? notifierWidth : pageWidth, + targetHeight + pageHeight); + if (NULL != composeBmp) + { + HBITMAP composeBmpOrig = (HBITMAP)SelectObject(composeDc, composeBmp); + + SendMessage(hNotifier, WM_PRINTCLIENT, (WPARAM)composeDc, (LPARAM)(PRF_CLIENT | PRF_ERASEBKGND)); + + + ANIMATIONDATA animation; + if (FALSE != Animation_Initialize(&animation, durationMs)) + { + while(currentHeight++ < targetHeight) + { + Animation_BeginStep(&animation); + Animation_SetWindowPos(hPage, pageRect.left, ++pageRect.top, pageWidth, --pageHeight, + 0, composeDc, 0, targetHeight); + + BitBlt(targetDc, notifierRect.left, notifierRect.top, notifierWidth, currentHeight, composeDc, 0, targetHeight - currentHeight, SRCCOPY); + if (NULL != hPage) + BitBlt(targetDc, pageRect.left, pageRect.top, pageWidth, pageHeight, composeDc, 0, targetHeight, SRCCOPY); + + Animation_EndStep(&animation, targetHeight - currentHeight); + } + } + + SelectObject(composeDc, composeBmpOrig); + DeleteObject(composeBmp); + } + DeleteDC(composeDc); + } + ReleaseDC(hwnd, targetDc); + } + } + + if (0 != (WS_VISIBLE & pageStyle)) + { + SetWindowLongPtr(hPage, GWL_STYLE, pageStyle); + INT delta = (targetHeight - currentHeight); + if (delta > 0) + { + SetWindowPos(hPage, NULL, pageRect.left, pageRect.top + delta, pageWidth, pageHeight - delta, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOCOPYBITS); + } + RedrawWindow(hPage, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_ERASENOW | RDW_ERASE); + } + + LoginNotifier_PlayBeep(hNotifier); + ShowWindow(hNotifier, SW_SHOWNA); + UpdateWindow(hNotifier); + } +} + +static void LoginBox_HideNotifier(HWND hwnd, INT durationMs) +{ + if (NULL == hwnd) return; + HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER); + if (NULL == hNotifier) return; + + UINT notifierStyle = GetWindowStyle(hNotifier); + if (0 == (WS_VISIBLE & notifierStyle)) return; + + SetWindowLongPtr(hNotifier, GWL_STYLE, notifierStyle & ~WS_VISIBLE); + + RECT notifierRect; + GetWindowRect(hNotifier, ¬ifierRect); + LONG currentHeight = notifierRect.bottom - notifierRect.top; + LONG startHeight = currentHeight; + LONG notifierWidth = notifierRect.right - notifierRect.left; + + if (currentHeight > 0) + { + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)¬ifierRect, 2); + + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + RECT pageRect; + if (NULL != hPage) + { + GetWindowRect(hPage, &pageRect); + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&pageRect, 2); + } + + LONG pageWidth = pageRect.right - pageRect.left; + LONG pageHeight = pageRect.bottom - pageRect.top; + + UINT pageStyle = (NULL != hPage) ? GetWindowStyle(hPage) : 0; + if (0 != (WS_VISIBLE & pageStyle)) + SetWindowLongPtr(hPage, GWL_STYLE, pageStyle & ~WS_VISIBLE); + + if (durationMs > 0) + { + HDC targetDc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS); + if (NULL != targetDc) + { + HDC composeDc = CreateCompatibleDC(targetDc); + if (NULL != composeDc) + { + HBITMAP composeBmp = CreateCompatibleBitmap(targetDc, + (notifierWidth > pageWidth) ? notifierWidth : pageWidth, + 2*startHeight + pageHeight); + if (NULL != composeBmp) + { + HBITMAP composeBmpOrig = (HBITMAP)SelectObject(composeDc, composeBmp); + + SendMessage(hNotifier, WM_PRINTCLIENT, (WPARAM)composeDc, (LPARAM)(PRF_CLIENT | PRF_ERASEBKGND)); + + ANIMATIONDATA animation; + if (FALSE != Animation_Initialize(&animation, durationMs)) + { + while(currentHeight-- > 0) + { + Animation_BeginStep(&animation); + if (FALSE != Animation_SetWindowPos(hPage, pageRect.left, --pageRect.top, pageWidth, ++pageHeight, + 0, composeDc, 0, startHeight)) + { + BitBlt(targetDc, pageRect.left, pageRect.top, pageWidth, pageHeight, composeDc, 0, startHeight, SRCCOPY); + } + + BitBlt(targetDc, notifierRect.left, notifierRect.top, notifierWidth, currentHeight, composeDc, 0, startHeight - currentHeight, SRCCOPY); + + Animation_EndStep(&animation, currentHeight); + } + } + + SelectObject(composeDc, composeBmpOrig); + DeleteObject(composeBmp); + } + DeleteDC(composeDc); + } + ReleaseDC(hwnd, targetDc); + } + } + + if (0 != (WS_VISIBLE & pageStyle)) + { + SetWindowLongPtr(hPage, GWL_STYLE, pageStyle); + INT delta = currentHeight; + if (delta > 0) + { + SetWindowPos(hPage, NULL, pageRect.left, pageRect.top - delta, pageWidth, pageHeight + delta, + SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOCOPYBITS); + } + RedrawWindow(hPage, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ALLCHILDREN | RDW_ERASENOW | RDW_ERASE); + } + + SetWindowPos(hNotifier, NULL, 0, 0, notifierWidth, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW | SWP_NOCOPYBITS); + } +} +static HRESULT LoginBox_SaveUsername(const GUID *realm, LoginProvider *provider, LoginCredentials *credentials) +{ + if (NULL == realm || NULL == provider || NULL == credentials) + return E_INVALIDARG; + + HRESULT hr; + + LoginConfig *config; + hr = LoginConfig::CreateInstance(&config); + if (FAILED(hr)) return hr; + + RPC_CSTR pszRealm; + if (RPC_S_OK == UuidToStringA(realm, &pszRealm)) + { + GUID providerId; + RPC_CSTR pszProvider; + + if (SUCCEEDED(provider->GetId(&providerId)) && + RPC_S_OK == UuidToStringA(&providerId, &pszProvider)) + { + LPCWSTR pszUser = credentials->GetUsername(); + + LPSTR pszUserAnsi; + if (NULL != pszUser && L'\0' != *pszUser) + hr = LoginBox_WideCharToMultiByte(CP_UTF8, 0, pszUser, -1, NULL, NULL, &pszUserAnsi); + else + pszUserAnsi = NULL; + + if (SUCCEEDED(hr)) + { + hr = config->WriteAnsiStr((LPCSTR)pszRealm, (LPCSTR)pszProvider, pszUserAnsi); + LoginBox_FreeAnsiString(pszUserAnsi); + } + RpcStringFreeA(&pszProvider); + } + else + hr = E_FAIL; + + RpcStringFreeA(&pszRealm); + } + else + hr = E_FAIL; + + config->Release(); + return hr; +} + +static HRESULT LoginBox_LoadUsername(const GUID *realm, LoginProvider *provider, LPWSTR pszBuffer, UINT cchBufferMax) +{ + if (NULL == pszBuffer) + return E_POINTER; + + if (NULL == realm || NULL == provider) + return E_INVALIDARG; + + HRESULT hr; + + LoginConfig *config; + hr = LoginConfig::CreateInstance(&config); + if (FAILED(hr)) return hr; + + RPC_CSTR pszRealm; + if (RPC_S_OK == UuidToStringA(realm, &pszRealm)) + { + GUID providerId; + RPC_CSTR pszProvider; + + if (SUCCEEDED(provider->GetId(&providerId)) && + RPC_S_OK == UuidToStringA(&providerId, &pszProvider)) + { + CHAR szUserAnsi[1024] = {0}; + INT cchUser = config->ReadAnsiStr((LPCSTR)pszRealm, (LPCSTR)pszProvider, NULL, szUserAnsi, ARRAYSIZE(szUserAnsi)); + + if (0 == cchUser) + pszBuffer[0] = L'\0'; + else + { + cchUser = MultiByteToWideChar(CP_UTF8, 0, szUserAnsi, cchUser, pszBuffer, cchBufferMax); + if (0 == cchUser) + hr = HRESULT_FROM_WIN32(GetLastError()); + else + pszBuffer[cchUser] = L'\0'; + } + + RpcStringFreeA(&pszProvider); + } + else + hr = E_FAIL; + + RpcStringFreeA(&pszRealm); + } + else + hr = E_FAIL; + + config->Release(); + return hr; + + +} +static BOOL LoginBox_SelectActivePage(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return FALSE; + + loginbox->agreementOk = FALSE; + LoginBox_HideNotifier(hwnd, 0); + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return FALSE; + + HWND hPageOld = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + if (NULL != hPageOld) + SetWindowLongPtr(hPageOld, GWLP_ID, 0); + + BOOL enableLogin = FALSE; + + HWND hPage = NULL; + LoginProvider *provider = NULL; + + INT iIndex = LoginTab_GetCurSel(hFrame); + if (-1 != iIndex) + { + NLTITEM tabItem; + tabItem.mask = NLTIF_PARAM; + provider = (TRUE == LoginTab_GetItem(hFrame, iIndex, &tabItem)) ? + (LoginProvider*)tabItem.param : NULL; + + if (NULL != provider) + { + LoginTemplate *pageTemplate; + if (SUCCEEDED(provider->GetTemplate(&pageTemplate)) && NULL != pageTemplate) + { + hPage = pageTemplate->CreatePage(hwnd, hwnd); + pageTemplate->Release(); + } + + LoginCommand *command; + if (SUCCEEDED(provider->GetCommand(&command)) && NULL != command) + { + enableLogin = (S_OK == command->IsValid()); + command->Release(); + } + } + } + + if (NULL == hPage) + { + hPage = (-1 == iIndex) ? + LoginPageEmpty::CreatePage(hwnd, hwnd) : + LoginPageError::CreatePage(hwnd, hwnd); + + } + + if (NULL != hPage) + { + //if (S_OK == UxTheme_IsThemeActive()) + // UxEnableThemeDialogTexture(hPage, ETDT_ENABLETAB); + + SetWindowLongPtr(hPage, GWLP_ID, IDC_ACTIVEPAGE); + + RECT rect; + if (NULL != hPageOld && FALSE != GetWindowRect(hPageOld, &rect)) + { + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2); + SetWindowPos(hPage, HWND_TOP, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW); + } + else + { + SetWindowPos(hPage, HWND_TOP, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOSIZE | SWP_NOMOVE); + SetWindowPos(hwnd, NULL, 0, 0, 0, 0, + SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOZORDER); + } + + WCHAR szUsername[512] = {0}; + if(SUCCEEDED(LoginBox_LoadUsername(&loginbox->realm, provider, szUsername, ARRAYSIZE(szUsername))) && + L'\0' != szUsername[0]) + { + LoginPage_SetUsername(hPage, szUsername); + } + + ShowWindow(hPage, SW_SHOWNORMAL); + + if (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & GetWindowStyle(hPage))) + { + HWND hFocus = GetFocus(); + if (hFrame != hFocus) + { + HWND hTarget = LoginPage_GetFirstItem(hPage); + if (NULL == hTarget || + ((WS_VISIBLE | WS_TABSTOP) != ((WS_VISIBLE | WS_TABSTOP | WS_DISABLED) & GetWindowStyle(hTarget)))) + { + hTarget = GetNextDlgTabItem(hwnd, hFrame, FALSE); + } + + if (NULL != hTarget && hTarget != hFocus) + PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hTarget, TRUE); + } + } + } + else + { + enableLogin = FALSE; + } + + HWND hButton = GetDlgItem(hwnd, IDOK); + if (NULL != hButton) + EnableWindow(hButton, enableLogin); + + if (NULL != hPageOld) + { + DestroyWindow(hPageOld); + } + + return TRUE; +} + +static BOOL LoginBox_RemoveImageHelper(HWND hFrame, HIMAGELIST imageList, UINT imageIndex) +{ + if (NLTM_IMAGE_NONE == imageIndex || NLTM_IMAGE_CALLBACK == imageIndex) + return FALSE; + + UINT imageListCount = ImageList_GetImageCount(imageList); + if (imageIndex > imageListCount) + return FALSE; + + INT iItem = LoginTab_GetItemCount(hFrame); + NLTITEM tab; + + while(iItem--) + { + tab.mask = NLTIF_IMAGE_MASK; + if (FALSE != LoginTab_GetItem(hFrame, iItem, &tab)) + { + tab.mask = 0; + if (tab.iImage >= imageIndex && tab.iImage < imageListCount) + { + tab.iImage = (tab.iImage != imageIndex) ? --tab.iImage : NLTM_IMAGE_NONE; + tab.mask |= NLTIF_IMAGE; + } + + if (tab.iImageActive >= imageIndex && tab.iImageActive < imageListCount) + { + tab.iImageActive = (tab.iImageActive != imageIndex) ? --tab.iImageActive : NLTM_IMAGE_NONE; + tab.mask |= NLTIF_IMAGE_ACTIVE; + } + + if (tab.iImageDisabled >= imageIndex && tab.iImageDisabled < imageListCount) + { + tab.iImageDisabled = (tab.iImageDisabled != imageIndex) ? --tab.iImageDisabled : NLTM_IMAGE_NONE; + tab.mask |= NLTIF_IMAGE_DISABLED; + } + + if (0 != tab.mask) + LoginTab_SetItem(hFrame, iItem, &tab); + } + } + return ImageList_Remove(imageList, imageIndex); +} + + +#define IS_IMAGEINDEX_VALID(__imageIndex) (((INT)(__imageIndex)) >= 0) +static BOOL LoginBox_RemoveImageHelper2(HWND hFrame, NLTITEM *tab) +{ + if (NULL == tab) return FALSE; + + HIMAGELIST imageList = LoginTab_GetImageList(hFrame); + if (NULL == imageList) return FALSE; + + if (IS_IMAGEINDEX_VALID(tab->iImageActive) && + FALSE != LoginBox_RemoveImageHelper(hFrame, imageList, tab->iImageActive)) + { + if (IS_IMAGEINDEX_VALID(tab->iImage)) + { + if (tab->iImage > tab->iImageActive) tab->iImage--; + else if (tab->iImage == tab->iImageActive) tab->iImage = NLTM_IMAGE_CALLBACK; + } + + if (IS_IMAGEINDEX_VALID(tab->iImageDisabled)) + { + if (tab->iImageDisabled > tab->iImageActive) tab->iImageDisabled--; + else if (tab->iImageDisabled == tab->iImageActive) tab->iImageDisabled = NLTM_IMAGE_CALLBACK; + } + + } + + if (IS_IMAGEINDEX_VALID(tab->iImage) && + FALSE != LoginBox_RemoveImageHelper(hFrame, imageList, tab->iImageActive)) + { + if (IS_IMAGEINDEX_VALID(tab->iImageActive)) + { + if (tab->iImageActive > tab->iImage) tab->iImageActive--; + else if (tab->iImageActive == tab->iImage) tab->iImageActive = NLTM_IMAGE_CALLBACK; + } + + if (IS_IMAGEINDEX_VALID(tab->iImageDisabled)) + { + if (tab->iImageDisabled > tab->iImage) tab->iImageDisabled--; + else if (tab->iImageDisabled == tab->iImage) tab->iImageDisabled = NLTM_IMAGE_CALLBACK; + } + + } + + if (IS_IMAGEINDEX_VALID(tab->iImageDisabled) && + FALSE != LoginBox_RemoveImageHelper(hFrame, imageList, tab->iImageDisabled)) + { + if (IS_IMAGEINDEX_VALID(tab->iImageActive)) + { + if (tab->iImageActive > tab->iImageDisabled) tab->iImageActive--; + else if (tab->iImageActive == tab->iImageDisabled) tab->iImageActive = NLTM_IMAGE_CALLBACK; + } + + if (IS_IMAGEINDEX_VALID(tab->iImage)) + { + if (tab->iImage > tab->iImageDisabled) tab->iImage--; + else if (tab->iImage == tab->iImageDisabled) tab->iImage = NLTM_IMAGE_CALLBACK; + } + + } + return TRUE; +} +static INT LoginBox_AppendMultipleTabs(HWND hwnd, LoginProviderEnumerator *enumerator, const GUID *filterOut, INT *filteredIndex) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return -1; + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return -1; + + if (NULL == enumerator) + return 0; + + GUID testId; + INT baseIndex = LoginTab_GetItemCount(hwnd); + INT count = 0; + NLTITEM tab; + WCHAR szTitle[256] = {0}; + + tab.mask = NLTIF_TEXT | NLTIF_PARAM | NLTIF_IMAGE_MASK; + + LoginProvider *provider; + while(S_OK == enumerator->Next(1, &provider, NULL)) + { + if (NULL != filterOut && SUCCEEDED(provider->GetId(&testId)) && FALSE != IsEqualGUID(testId, *filterOut)) + { + if (NULL != filteredIndex) + *filteredIndex = baseIndex + count; + } + else + { + if (FAILED(provider->GetName(szTitle, ARRAYSIZE(szTitle)))) + szTitle[0] = L'\0'; + + tab.param = (LPARAM)provider; + tab.pszText = (LPWSTR)szTitle; + tab.iImage = NLTM_IMAGE_CALLBACK; + tab.iImageActive = NLTM_IMAGE_CALLBACK; + tab.iImageDisabled = NLTM_IMAGE_CALLBACK; + + if (-1 != LoginTab_InsertItem(hFrame, baseIndex + count, &tab)) + { + provider->AddRef(); + count++; + } + } + + provider->Release(); + } + + return count; +} + +static INT LoginBox_InsertTab(HWND hwnd, INT index, LoginProvider *provider) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return -1; + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return -1; + + if (NULL == provider) + return -1; + + INT count = LoginTab_GetItemCount(hFrame); + if (index > count) index = count; + + NLTITEM tab; + WCHAR szTitle[256] = {0}; + + if (FAILED(provider->GetName(szTitle, ARRAYSIZE(szTitle)))) + szTitle[0] = L'\0'; + + tab.mask = NLTIF_TEXT | NLTIF_PARAM | NLTIF_IMAGE_MASK; + tab.param = (LPARAM)provider; + tab.pszText = (LPWSTR)szTitle; + tab.iImage = NLTM_IMAGE_CALLBACK; + tab.iImageActive = NLTM_IMAGE_CALLBACK; + tab.iImageDisabled = NLTM_IMAGE_CALLBACK; + + index = LoginTab_InsertItem(hFrame, index, &tab); + if (-1 != index) + provider->AddRef(); + + return index; +} + +static INT LoginBox_FindTabByProviderId(HWND hwnd, const GUID *providerId) +{ + if (NULL == providerId) + return -1; + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return -1; + + NLTITEM tab; + tab.mask = NLTIF_PARAM; + INT count = LoginTab_GetItemCount(hFrame); + GUID testId; + for (INT i =0; i < count; i++) + { + if (FALSE != LoginTab_GetItem(hFrame, i, &tab)) + { + if (NULL != tab.param) + { + LoginProvider *provider = (LoginProvider*)tab.param; + if (SUCCEEDED(provider->GetId(&testId)) && FALSE != IsEqualGUID(testId, *providerId)) + return i; + } + } + } + return -1; +} + +static void LoginBox_DeleteAllTabs(HWND hwnd) +{ + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return; + + LoginTab_DeleteAllItems(hFrame); +} + +static BOOL LoginBox_ReplaceProvider(HWND hwnd, const GUID *sourceId, LoginProvider *target) +{ + if (NULL == sourceId || NULL == target) + return FALSE; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return FALSE; + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return FALSE; + + GUID testId; + + BOOL resultOk = FALSE; + + NLTITEM tab; + tab.mask = NLTIF_PARAM | NLTIF_IMAGE_MASK; + INT count = LoginTab_GetItemCount(hFrame); + for (INT i =0; i < count; i++) + { + if (FALSE != LoginTab_GetItem(hFrame, i, &tab)) + { + LoginProvider *provider = (LoginProvider*)tab.param; + if (NULL != provider && SUCCEEDED(provider->GetId(&testId)) && IsEqualGUID(*sourceId, testId)) + { + + tab.mask = NLTIF_TEXT | NLTIF_PARAM | NLTIF_IMAGE_MASK; + tab.param = (LPARAM)target; + + WCHAR szTitle[256] = {0}; + if (FAILED(target->GetName(szTitle, ARRAYSIZE(szTitle)))) + szTitle[0] = L'\0'; + + tab.pszText = szTitle; + + LoginBox_RemoveImageHelper2(hFrame, &tab); + + tab.iImage = NLTM_IMAGE_CALLBACK; + tab.iImageActive = NLTM_IMAGE_CALLBACK; + tab.iImageDisabled = NLTM_IMAGE_CALLBACK; + + if (TRUE == LoginTab_SetItem(hFrame,i, &tab)) + { + target->AddRef(); + resultOk = TRUE; + + if (i == LoginTab_GetCurSel(hFrame)) + LoginBox_SelectActivePage(hwnd); + + provider->Release(); + } + + break; + } + } + } + return resultOk; +} + +static BOOL LoginBox_DeleteProvider(HWND hwnd, const GUID *providerId) +{ + if (NULL == providerId) + return FALSE; + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return FALSE; + + GUID testId; + BOOL resultOk = FALSE; + + NLTITEM tab; + tab.mask = NLTIF_PARAM; + INT count = LoginTab_GetItemCount(hFrame); + for (INT i =0; i < count; i++) + { + if (FALSE != LoginTab_GetItem(hFrame, i, &tab)) + { + LoginProvider *provider = (LoginProvider*)tab.param; + if (NULL != provider && SUCCEEDED(provider->GetId(&testId)) && IsEqualGUID(*providerId, testId)) + { + BOOL updateSelection = (i == LoginTab_GetCurSel(hFrame)); + + if (TRUE == LoginTab_DeleteItem(hFrame, i)) + { + resultOk = TRUE; + if (FALSE != updateSelection) + { + LoginTab_SetCurSel(hFrame, 0); + LoginBox_SelectActivePage(hwnd); + } + } + break; + } + } + } + return resultOk; +} + +static BOOL LoginBox_CenterOver(HWND hwnd, HWND hOwner) +{ + RECT rect, rectOwner; + + if (NULL == hwnd || FALSE == GetWindowRect(hwnd, &rect)) + return FALSE; + + if(NULL == hOwner || FALSE == GetWindowRect(hOwner, &rectOwner)) + { + HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTOPRIMARY); + if (NULL == hMonitor) return FALSE; + + MONITORINFO mi; + mi.cbSize = sizeof(mi); + if (FALSE == GetMonitorInfo(hMonitor, &mi)) return FALSE; + CopyRect(&rectOwner, &mi.rcWork); + } + + LONG x = rectOwner.left + ((rectOwner.right - rectOwner.left) - (rect.right - rect.left))/2; + LONG y = rectOwner.top + ((rectOwner.bottom - rectOwner.top) - (rect.bottom - rect.top))/2; + + return SetWindowPos(hwnd, NULL, x, y, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER); +} + +static void LoginBox_UpdateMargins(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + RECT rect; + SetRect(&rect, 4, 14, 0, 0); + MapDialogRect(hwnd, &rect); + + loginbox->buttonHeight = rect.top; + loginbox->buttonSpace = rect.left; + + HWND hControl = GetDlgItem(hwnd, IDOK); + if (NULL != hControl) + { + loginbox->buttonHeight = LoginBox_GetWindowTextHeight(hControl, 3); + } + + if (loginbox->buttonHeight < 23) + loginbox->buttonHeight = 23; + + SetRect(&rect, 2, 8, 8, 6); + MapDialogRect(hwnd, &rect); + CopyRect(&loginbox->buttonMargins, &rect); + + + SetRect(&loginbox->minmaxInfo, LOGINBOX_MINWIDTH, LOGINBOX_MINHEIGHT, LOGINBOX_MAXWIDTH, LOGINBOX_MAXHEIGHT); + MapDialogRect(hwnd, &loginbox->minmaxInfo); +} + +static BOOL LoginBox_GetGripSize(HWND hwnd, HDC hdc, SIZE *gripSize) +{ + BOOL gripSizeOk = FALSE; + if (SUCCEEDED(UxTheme_LoadLibrary()) && FALSE != UxIsAppThemed()) + { + UXTHEME hTheme = UxOpenThemeData(hwnd, L"Scrollbar"); + if (NULL != hTheme) + { + if (SUCCEEDED(UxGetThemePartSize(hTheme, hdc, SBP_SIZEBOX, SZB_RIGHTALIGN, NULL, TS_TRUE, gripSize))) + gripSizeOk = TRUE; + + UxCloseThemeData(hTheme); + } + } + + if (FALSE == gripSizeOk) + { + gripSize->cx = GetSystemMetrics(SM_CXVSCROLL); + gripSize->cy = GetSystemMetrics(SM_CYHSCROLL); + } + + return TRUE; +} + + +static void LoginBox_LayoutGrip(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS); + if (NULL != hdc) + { + SIZE gripSize; + if (FALSE != LoginBox_GetGripSize(hwnd, hdc, &gripSize)) + { + GetClientRect(hwnd, &loginbox->gripRect); + loginbox->gripRect.left = loginbox->gripRect.right - gripSize.cx; + loginbox->gripRect.top = loginbox->gripRect.bottom - gripSize.cy; + + LONG test; + test = gripSize.cx - MulDiv(gripSize.cx, 2, 3); + if (loginbox->buttonMargins.right < test) + loginbox->buttonMargins.right = test; + + test = gripSize.cy - MulDiv(gripSize.cy, 2, 3); + if (loginbox->buttonMargins.bottom < test) + loginbox->buttonMargins.bottom = test; + } + ReleaseDC(hwnd, hdc); + } +} + +static void LoginBox_UpdateLayout(HWND hwnd, BOOL fRedraw) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + RECT clientRect; + if (NULL == hwnd || FALSE == GetClientRect(hwnd, &clientRect)) + return; + + UINT swpFlags = SWP_NOACTIVATE | SWP_NOZORDER; + if (FALSE == fRedraw) swpFlags |= SWP_NOREDRAW; + + const INT szButtons[] = { IDOK, IDCANCEL, }; + const INT szControls[] = { IDC_STATUS, IDC_TABFRAME, IDC_NOTIFIER, IDC_ACTIVEPAGE, IDC_CURTAIN, }; + + HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szButtons) + ARRAYSIZE(szControls)); + if (NULL == hdwp) return; + + RECT rect; + + HRGN rgnUpdate(NULL), rgn(NULL); + if (FALSE != fRedraw) + { + rgnUpdate = CreateRectRgn(0, 0, 0, 0); + rgn = CreateRectRgn(0,0,0,0); + + if (FALSE == IsRectEmpty(&loginbox->gripRect)) + { + SetRectRgn(rgn, loginbox->gripRect.left, loginbox->gripRect.top, + loginbox->gripRect.right, loginbox->gripRect.bottom); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + + if (loginbox->buttonTop > clientRect.top) + { + SetRectRgn(rgn, clientRect.left, loginbox->buttonTop, clientRect.right, loginbox->buttonTop + 1); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + } + + LoginBox_LayoutGrip(hwnd); + + CopyRect(&rect, &clientRect); + rect.left += loginbox->buttonMargins.left; + rect.top += loginbox->buttonMargins.top; + rect.right -= loginbox->buttonMargins.right; + rect.bottom -= loginbox->buttonMargins.bottom; + + hdwp = LoginBox_LayoutButtonBar(hdwp, hwnd, szButtons, ARRAYSIZE(szButtons), &rect, + loginbox->buttonHeight, loginbox->buttonSpace, fRedraw, &rect); + + loginbox->buttonTop = rect.top - loginbox->buttonMargins.top; + + if (NULL != rgn && loginbox->buttonTop > clientRect.top) + { + SetRectRgn(rgn, clientRect.left, loginbox->buttonTop, clientRect.right, loginbox->buttonTop + 1); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + + LONG statusRight = rect.left - loginbox->buttonSpace; + LONG pageTop = clientRect.top; + LONG pageBottom = loginbox->buttonTop; + + UINT flags; + + if (NULL != rgn) + { + SetRectRgn(rgn, loginbox->gripRect.left, loginbox->gripRect.top, + loginbox->gripRect.right, loginbox->gripRect.bottom); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + + for (INT i = 0; i < ARRAYSIZE(szControls); i++) + { + HWND hControl = GetDlgItem(hwnd, szControls[i]); + if (NULL == hControl || FALSE == GetWindowRect(hControl, &rect)) continue; + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2); + flags = swpFlags; + + switch(szControls[i]) + { + case IDC_STATUS: + if (NULL != rgn && 0 != (WS_VISIBLE & GetWindowStyle(hControl))) + { + SetRectRgn(rgn, rect.left, rect.top, rect.right, rect.bottom); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + rect.top = rect.bottom - rect.top; + rect.bottom = clientRect.bottom - loginbox->buttonMargins.bottom; + rect.top = rect.bottom - rect.top; + rect.left = clientRect.left + loginbox->buttonMargins.left; + rect.right = statusRight; + flags |= SWP_NOREDRAW | SWP_NOCOPYBITS; + if (NULL != rgn && 0 != (WS_VISIBLE & GetWindowStyle(hControl))) + { + SetRectRgn(rgn, rect.left, rect.top, rect.right, rect.bottom); + CombineRgn(rgnUpdate, rgnUpdate, rgn, RGN_OR); + } + + break; + + case IDC_TABFRAME: + rect.left = clientRect.left; + rect.top = clientRect.top; + rect.right = clientRect.right; + rect.bottom = rect.top + LoginTab_GetIdealHeight(hControl); + pageTop = rect.bottom; + break; + + case IDC_NOTIFIER: + rect.bottom = pageTop + (rect.bottom - rect.top); + rect.top = pageTop; + rect.left = clientRect.left; + rect.right = clientRect.right; + if (0 != (WS_VISIBLE & GetWindowStyle(hControl))) + pageTop = rect.bottom; + break; + + case IDC_ACTIVEPAGE: + case IDC_CURTAIN: + rect.left = clientRect.left; + rect.top = pageTop; + rect.right = clientRect.right; + rect.bottom = (pageBottom > pageTop) ? pageBottom : pageTop; + break; + } + + hdwp = DeferWindowPos(hdwp, hControl, NULL, rect.left, rect.top, + rect.right - rect.left, rect.bottom - rect.top, flags); + + if (NULL == hdwp) break; + } + + if (NULL != hdwp) + { + EndDeferWindowPos(hdwp); + } + + if (NULL != rgnUpdate) + { + RedrawWindow(hwnd, NULL, rgnUpdate, RDW_INVALIDATE | RDW_ALLCHILDREN); + DeleteObject(rgnUpdate); + } + + if (NULL != rgn) + DeleteObject(rgn); +} + +static BOOL LoginBox_DrawResizeGrip(HWND hwnd, HDC hdc, const RECT *gripRect, HBRUSH brushBk) +{ + BOOL gripDrawOk = FALSE; + + if (SUCCEEDED(UxTheme_LoadLibrary()) && FALSE != UxIsAppThemed()) + { + UXTHEME hTheme = UxOpenThemeData(hwnd, L"Scrollbar"); + if (NULL != hTheme) + { + if (UxIsThemeBackgroundPartiallyTransparent(hTheme, SBP_SIZEBOX, SZB_RIGHTALIGN)) + { + UXTHEME windowTheme = UxOpenThemeData(hwnd, L"Window"); + if (NULL != windowTheme) + { + if (UxIsThemeBackgroundPartiallyTransparent(windowTheme, WP_DIALOG, 0)) + UxDrawThemeParentBackground(hwnd, hdc, gripRect); + + //UxDrawThemeBackground(windowTheme, hdc, WP_DIALOG, 0, &gripRect, &gripRect); + FillRect(hdc, gripRect, brushBk); + UxCloseThemeData(windowTheme); + } + } + + if (SUCCEEDED(UxDrawThemeBackground(hTheme, hdc, SBP_SIZEBOX, SZB_RIGHTALIGN, gripRect, gripRect))) + gripDrawOk = TRUE; + + UxCloseThemeData(hTheme); + } + } + + if (FALSE == gripDrawOk) + gripDrawOk = DrawFrameControl(hdc, (RECT*)gripRect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP); + + return gripDrawOk; +} + +static void LoginBox_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + if (FALSE != fErase) + { + HBRUSH brushBk = (HBRUSH)SendMessage(hwnd, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd); + if (NULL == brushBk) + { + brushBk = GetSysColorBrush(COLOR_3DFACE); + } + + HRGN regionFill = CreateRectRgnIndirect(prcPaint); + HRGN regionClip = NULL; + + if (RectInRegion(regionFill, &loginbox->gripRect) && + FALSE != LoginBox_DrawResizeGrip(hwnd, hdc, &loginbox->gripRect, brushBk)) + { + regionClip = CreateRectRgnIndirect(&loginbox->gripRect); + if (NULL != regionClip) + CombineRgn(regionFill, regionFill, regionClip, RGN_DIFF); + } + + if (loginbox->buttonTop > 0) + { + RECT lineRect; + GetClientRect(hwnd, &lineRect); + lineRect.top = loginbox->buttonTop; + lineRect.bottom = loginbox->buttonTop + 1; + + if (RectInRegion(regionFill, &lineRect)) + { + COLORREF rgbLine = GetSysColor(COLOR_3DLIGHT); + if (rgbLine == GetSysColor(COLOR_3DFACE)) + rgbLine = ColorAdjustLuma(rgbLine, -50, TRUE); + + COLORREF rgbOrig = SetBkColor(hdc, rgbLine); + if (0 != ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &lineRect, NULL, 0, NULL)) + { + if (NULL == regionClip) regionClip = CreateRectRgnIndirect(&lineRect); + else SetRectRgn(regionClip, lineRect.left, lineRect.top, lineRect.right, lineRect.bottom); + + if (NULL != regionClip) + CombineRgn(regionFill, regionFill, regionClip, RGN_DIFF); + + } + if (rgbOrig != rgbLine) SetBkColor(hdc, rgbOrig); + } + } + + if (NULL != regionFill) + { + FillRgn(hdc, regionFill, brushBk); + DeleteObject(regionFill); + } + + if (NULL != regionClip) + DeleteObject(regionClip); + } +} + + +static LoginProvider *LoginBox_GetActiveProviderInternal(HWND hwnd) +{ + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return NULL; + + INT iSelected = LoginTab_GetCurSel(hFrame); + if (-1 == iSelected) return NULL; + + NLTITEM tab; + tab.mask = NLTIF_PARAM; + return (TRUE == LoginTab_GetItem(hFrame, iSelected, &tab)) ? + (LoginProvider*)tab.param : NULL; +} + +static void CALLBACK LoginBox_LoginCompletedEvent(LoginResult *result) +{ + HWND hLoginbox; + if (SUCCEEDED(result->GetUser((void**)&hLoginbox)) && NULL != hLoginbox) + PostMessage(hLoginbox, NLBM_LOGINCOMPLETED, 0, (LPARAM)result); +} + +static void Loginbox_LockTabFrame(HWND hwnd, BOOL fLock) +{ + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL == hFrame) return; + + UINT frameStyle = GetWindowStyle(hFrame); + if (FALSE != fLock) + frameStyle &= ~WS_TABSTOP; + else + frameStyle |= WS_TABSTOP; + + SetWindowLongPtr(hFrame, GWL_STYLE, frameStyle); + + LoginTab_LockSelection(hFrame, fLock); +} + +static BOOL LoginBox_EnableLoginMode(HWND hwnd, BOOL fEnable, BOOL fValidateTos) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return FALSE; + + const static INT szControls[] = { IDC_ACTIVEPAGE, IDOK, }; + + BOOL resultCode = TRUE; + + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + + if (FALSE != LoginPopup::AnyPopup(hwnd)) + return FALSE; + + if (FALSE != fEnable) + { + HWND hPopup = NULL; + + if (NULL == hCurtain) + { + hCurtain = LoginCurtain_CreateWindow(hwnd, (NULL != hPage) ? hPage : hwnd); + if (NULL != hCurtain) + SetWindowLongPtr(hCurtain, GWLP_ID, IDC_CURTAIN); + } + + if (FALSE != fValidateTos && TRUE != loginbox->agreementOk) + { + + LoginProvider *provider = LoginBox_GetActiveProviderInternal(hwnd); + hPopup = LoginPopupAgreement::CreatePopup((NULL != hCurtain) ? hCurtain : hwnd, provider); + if (NULL != hPopup) + { + SetWindowLongPtr(hPopup, GWLP_ID, IDC_POPUPAGREEMENT); + + if (NULL != loginbox->loginStatus) + { + WCHAR szBuffer[128] = {0}; + WASABI_API_LNGSTRINGW_BUF(IDS_STATUS_AGREEMENT_REQUIRED, szBuffer, ARRAYSIZE(szBuffer)); + if (L'\0' != szBuffer[0]) + { + UINT statusCookie = loginbox->loginStatus->Add(SysAllocString(szBuffer)); + if (-1 != statusCookie && FALSE == SetProp(hPopup, L"StatusCookie", (HANDLE)(UINT_PTR)(statusCookie + 1))) + loginbox->loginStatus->Remove(statusCookie); + } + } + + + SetWindowPos(hPopup, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(hPopup, SW_SHOW); + if (NULL != hCurtain) + SetWindowPos(hCurtain, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ); + + resultCode = FALSE; + + } + else + { + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + return FALSE; + } + + + } + + if (NULL != hCurtain) + { + ShowWindow(hCurtain, SW_SHOW); + UpdateWindow(hCurtain); + } + + if (NULL != hPopup && IsWindowVisible(hPopup) && IsWindowEnabled(hPopup)) + { + HWND hRoot = GetAncestor(hPopup, GA_ROOT); + if (NULL != hRoot) + SendMessage(hRoot, WM_NEXTDLGCTL, (WPARAM)hPopup, TRUE); + LoginPopup_PlayBeep(hPopup); + } + + Loginbox_LockTabFrame(hwnd, TRUE); + for (INT i = 0; i < ARRAYSIZE(szControls); i++) + { + HWND hControl = GetDlgItem(hwnd, szControls[i]); + if (NULL != hControl) + { + EnableWindow(hControl, FALSE); + } + } + + + } + else + { + Loginbox_LockTabFrame(hwnd, FALSE); + for (INT i = 0; i < ARRAYSIZE(szControls); i++) + { + HWND hControl = GetDlgItem(hwnd, szControls[i]); + if (NULL != hControl) EnableWindow(hControl, TRUE); + } + + if (NULL != hPage && IsWindowVisible(hPage) && IsWindowEnabled(hPage)) + { + HWND hRoot = GetAncestor(hPage, GA_ROOT); + if (NULL != hRoot) + SendMessage(hRoot, WM_NEXTDLGCTL, (WPARAM)hPage, TRUE); + } + + if (NULL != hCurtain) + { + DestroyWindow(hCurtain); + } + } + + return resultCode; +} + +static void LoginBox_PerformLogin(HWND hwnd, LoginData *loginData) +{ + LoginBox_HideNotifier(hwnd, 150); + + if (FALSE == LoginBox_EnableLoginMode(hwnd, TRUE, TRUE)) + return; + + INT authError; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) authError = AUTH_UNEXPECTED; + else + { + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + if (NULL == hPage) authError = AUTH_UNEXPECTED; + else + { + LoginProvider *provider = LoginBox_GetActiveProviderInternal(hwnd); + if (NULL == provider) authError = AUTH_UNEXPECTED; + else + { + LoginCommand *command; + if (FAILED(provider->GetCommand(&command))) authError = AUTH_UNEXPECTED; + else + { + if (NULL == loginData) + { + if (FALSE == LoginPage_GetData(hPage, &loginData)) + loginData = NULL; + } + else + loginData->AddRef(); + + HRESULT hr = command->BeginLogin(loginData, LoginBox_LoginCompletedEvent, hwnd, &loginbox->loginResult); + authError = (SUCCEEDED(hr)) ? AUTH_SUCCESS : AUTH_UNEXPECTED; + command->Release(); + + if (NULL != loginData) + loginData->Release(); + } + } + } + } + + if (AUTH_SUCCESS != authError) + { + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + if (AUTH_ABORT != authError) + { + HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER); + if (NULL != hNotifier) + { + LoginNotifier_Notify(hNotifier, NLNTYPE_ERROR, MAKEINTRESOURCE(authError)); + LoginBox_ShowNotifier(hwnd, 200); + } + } + } +} + +static INT LoginBox_SetCredentials(HWND hwnd, LoginCredentials *credentials) +{ + if (NULL == credentials) + return AUTH_UNEXPECTED; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox || NULL == loginbox->auth) + return AUTH_UNEXPECTED; + + INT result = loginbox->auth->SetCredentials(credentials->GetRealm(), credentials->GetSessionKey(), + credentials->GetToken(), credentials->GetUsername(), credentials->GetExpiration()); + + return result; +} + +static INT LoginBox_RequestPasscode(HWND hwnd, LoginResult *loginResult) +{ + LoginData *loginData; + if (NULL == loginResult || FAILED(loginResult->GetLoginData(&loginData)) || NULL == loginData) + return AUTH_UNEXPECTED; + + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + HWND hPopup = LoginPopupPasscode::CreatePopup((NULL != hCurtain) ? hCurtain : hwnd, loginData); + if (NULL != hPopup) + { + SetWindowLongPtr(hPopup, GWLP_ID, IDC_POPUPPASSCODE); + + SetWindowPos(hPopup, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(hPopup, SW_SHOW); + + if (NULL != hCurtain) + SetWindowPos(hCurtain, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ); + + if (IsWindowVisible(hPopup) && IsWindowEnabled(hPopup)) + { + HWND hRoot = GetAncestor(hPopup, GA_ROOT); + if (NULL != hRoot) + SendMessage(hRoot, WM_NEXTDLGCTL, (WPARAM)hPopup, TRUE); + LoginPopup_PlayBeep(hPopup); + } + + } + + loginData->Release(); + + return (NULL != hPopup) ? AUTH_SUCCESS : AUTH_UNEXPECTED; +} + +static BOOL LoginBox_EndDialog(HWND hwnd, INT authResult) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + + if (0 != (NLBS_MODAL & loginbox->style)) + { + EndDialog(hwnd, authResult); + } + else + { + DestroyWindow(hwnd); + } + return TRUE; +} + +static BOOL LoginBox_ReloadProviders(HWND hwnd, INT *loaded, INT *prefVisible) +{ + if (NULL != loaded) + *loaded = NULL; + + WCHAR szPath[MAX_PATH] = {0}; + if (FAILED(LoginBox_GetConfigPath(szPath, FALSE))) + return FALSE; + + if (FALSE == PathAppend(szPath, L"loginProviders.xml")) + return FALSE; + + LoginProviderEnumerator *enumerator; + LoginProviderLoader loader; + + if (FAILED(loader.ReadXml(szPath,&enumerator, prefVisible))) + return FALSE; + + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL != hFrame) + { + UINT frameStyle = GetWindowStyle(hFrame); + if (0 != (WS_VISIBLE & frameStyle)) + SetWindowLongPtr(hFrame, GWL_STYLE, frameStyle & ~WS_VISIBLE); + + LoginBox_DeleteAllTabs(hwnd); + INT r = LoginBox_AppendMultipleTabs(hwnd, enumerator, NULL, NULL); + if (NULL != loaded) + *loaded = r; + + if (0 != (WS_VISIBLE & frameStyle)) + { + frameStyle = GetWindowStyle(hFrame); + if (0 == (WS_VISIBLE & frameStyle)) + SetWindowLongPtr(hFrame, GWL_STYLE, frameStyle | WS_VISIBLE); + } + } + + enumerator->Release(); + return TRUE; +} + + +static void LoginBox_PerformProviderOp(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox || NULL == loginbox->providerOp) + return; + + if (FALSE == LoginBox_EnableLoginMode(hwnd, TRUE, FALSE)) + return; + + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + + LPCWSTR pszMessage; + switch(loginbox->providerOp->GetCode()) + { + case LoginProviderOperation::operationReplace: + pszMessage = MAKEINTRESOURCE(IDS_PROVIDER_CHANGED); break; + case LoginProviderOperation::operationDelete: + pszMessage = MAKEINTRESOURCE(IDS_PROVIDER_REMOVED); break; + default: + pszMessage = NULL; + break; + } + HWND hPopup = LoginPopupMessage::CreatePopup((NULL != hCurtain) ? hCurtain : hwnd, + MAKEINTRESOURCE(IDS_PROVIDERUPDATE_TITLE), pszMessage, + LoginPopupMessage::typeContinue | LoginPopupMessage::iconWarning, NULL, NULL); + if (NULL != hPopup) + { + SetWindowLongPtr(hPopup, GWLP_ID, IDC_POPUPPROVIDEROP); + + SetWindowPos(hPopup, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); + ShowWindow(hPopup, SW_SHOW); + + if (NULL != hCurtain) + SetWindowPos(hCurtain, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ); + + if (IsWindowVisible(hPopup) && IsWindowEnabled(hPopup)) + { + HWND hRoot = GetAncestor(hPopup, GA_ROOT); + if (NULL != hRoot) + SendMessage(hRoot, WM_NEXTDLGCTL, (WPARAM)hPopup, TRUE); + LoginPopup_PlayBeep(hPopup); + } + } + else + { + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + } +} +static INT_PTR LoginBox_OnInitDialog(HWND hwnd, HWND hFocus, LPARAM param) +{ + LOGINBOXCREATEPARAM *createParam = (LOGINBOXCREATEPARAM*)param; + LOGINBOX *login = (LOGINBOX*)calloc(1, sizeof(LOGINBOX)); + if (NULL == login) + { + return 0; + } + + SetProp(hwnd, LOGINBOX_PROP, login); + + if (NULL != createParam) + { + login->style = createParam->style; + login->realm = (NULL == createParam->pRealm) ? GUID_NULL : *createParam->pRealm; + login->auth = createParam->auth; + } + + if (NULL != login->auth) + login->auth->AddRef(); + + LoginGuiObject::InitializeThread(); + + HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L); + + HWND hFrame = LoginTab_CreateWindow(0, L"Select provider:", + WS_CHILD | WS_CLIPSIBLINGS | WS_TABSTOP | WS_VISIBLE, 0, 0, 0, 0, hwnd, IDC_TABFRAME); + + if (NULL != hFrame) + { + HIMAGELIST imageList = ImageList_Create(40, 40, ILC_COLOR32, 7*3, 3*3); + if (NULL != imageList) + LoginTab_SetImageList(hFrame, imageList); + } + + HWND hNotifier = LoginNotifier_CreateWindow(0, WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0, hwnd, IDC_NOTIFIER); + if (NULL != hNotifier) + { + if (NULL != hFont) + SendMessage(hNotifier, WM_SETFONT, (WPARAM)hFont, 0L); + SetWindowPos(hNotifier, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE); + } + + HWND hStatus = GetDlgItem(hwnd, IDC_STATUS); + if (NULL != hStatus) + { + LoginStatus::CreateInstance(hStatus, &login->loginStatus); + } + + LoginGuiObject *loginGui; + if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui))) + { + HFONT fontButton = loginGui->GetTextFont(); + if (NULL != fontButton) + { + INT szButtons[] = {IDOK, IDCANCEL, }; + for (INT i = 0; i < ARRAYSIZE(szButtons); i++) + { + HWND hButton = GetDlgItem(hwnd, szButtons[i]); + if(NULL != hButton) + SNDMSG(hButton, WM_SETFONT, (WPARAM)fontButton, 0L); + } + } + loginGui->Release(); + } + INT loaded, prefVisible, prefWidth; + + prefWidth = 0; + if (FALSE == LoginBox_ReloadProviders(hwnd, &loaded, &prefVisible)) + { + loaded = 0; + prefVisible = 0; + } + + if (NULL != hFrame && prefVisible > 0) + prefWidth = LoginTab_GetIdealWidth(hFrame, prefVisible); + + if (NULL != hFrame) + { + INT activeId = -1; + LoginConfig *config; + if (SUCCEEDED(LoginConfig::CreateInstance(&config))) + { + RPC_CSTR pszRealm; + if (RPC_S_OK == UuidToStringA(&login->realm, &pszRealm)) + { + CHAR szProvider[128] = {0}; + config->ReadAnsiStr((LPCSTR)pszRealm, "lastProvider", NULL, szProvider, ARRAYSIZE(szProvider)); + if (NULL != szProvider && L'\0' != *szProvider) + { + GUID providerId; + if (RPC_S_OK == UuidFromStringA((RPC_CSTR)szProvider, &providerId)) + activeId = LoginBox_FindTabByProviderId(hwnd, &providerId); + } + RpcStringFreeA(&pszRealm); + } + + config->Release(); + } + + if (-1 == activeId) + activeId = 0; + + LoginTab_SetCurSel(hFrame, activeId); + LoginBox_SelectActivePage(hwnd); + + } + + LoginBox_UpdateMargins(hwnd); + + if (0 != prefWidth) + { + RECT rect; + + GetClientRect(hwnd, &rect); + prefWidth -= rect.right - rect.left; + + GetWindowRect(hwnd, &rect); + prefWidth += rect.right - rect.left; + + + if (prefWidth < login->minmaxInfo.left) prefWidth = login->minmaxInfo.left; + else if (prefWidth > login->minmaxInfo.right) prefWidth = login->minmaxInfo.right; + + SetWindowPos(hwnd, NULL, 0, 0, prefWidth, rect.bottom - rect.top, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE | SWP_NOREDRAW); + + } + + LoginBox_UpdateLayout(hwnd, FALSE); + + if (NULL != createParam && 0 == (LBS_NOCENTEROWNER & createParam->style)) + LoginBox_CenterOver(hwnd, createParam->hOwner); + + SendMessage(hwnd, DM_REPOSITION, 0, 0L); + + PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L); + PostMessage(hwnd, NLBM_UPDATEPROVIDERS, (0 == loaded), 0L); + + return 0; +} + +static void LoginBox_OnDestroy(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + RemoveProp(hwnd, LOGINBOX_PROP); + + if (NULL == loginbox) + return; + + LoginConfig *config; + if (SUCCEEDED(LoginConfig::CreateInstance(&config))) + { + RPC_CSTR pszRealm, pszProvider; + if (RPC_S_OK == UuidToStringA(&loginbox->realm, &pszRealm)) + { + GUID providerId; + LoginProvider *activeProvider = LoginBox_GetActiveProviderInternal(hwnd); + if (NULL == activeProvider || FAILED(activeProvider->GetId(&providerId)) || + RPC_S_OK != UuidToStringA(&providerId, &pszProvider)) + { + pszProvider = NULL; + } + + config->WriteAnsiStr((LPCSTR)pszRealm, "lastProvider", (LPCSTR)pszProvider); + if (NULL != pszProvider) + RpcStringFreeA(&pszProvider); + + RpcStringFreeA(&pszRealm); + } + + config->Release(); + } + + if (NULL != loginbox->imageCache) + { + loginbox->imageCache->Finish(); + loginbox->imageCache->Release(); + loginbox->imageCache = NULL; + } + + LoginBox_DeleteAllTabs(hwnd); + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL != hFrame) + { + HIMAGELIST imageList = LoginTab_SetImageList(hFrame, NULL); + if (NULL != imageList) + { + ImageList_Destroy(imageList); + } + } + + if (NULL != loginbox->loginResult) + { + LoginResult *result = loginbox->loginResult; + result->RequestAbort(TRUE); + HANDLE resultAborted; + if (SUCCEEDED(result->GetWaitHandle(&resultAborted))) + { + WaitForSingleObjectEx(resultAborted, INFINITE, TRUE); + CloseHandle(resultAborted); + } + + loginbox->loginResult = NULL; + result->Release(); + } + + if (NULL != loginbox->auth) + loginbox->auth->Release(); + + if (NULL != loginbox->providerUpdate) + { + UINT state; + if (FAILED(loginbox->providerUpdate->GetState(&state)) || + LoginDownloadResult::stateCompleted != state) + { + loginbox->providerUpdate->RequestAbort(TRUE); + HANDLE completed; + if (SUCCEEDED(loginbox->providerUpdate->GetWaitHandle(&completed)) && NULL != completed) + { + WaitForSingleObject(completed, INFINITE); + CloseHandle(completed); + } + } + loginbox->providerUpdate->Release(); + } + + if (NULL != loginbox->providerOp) + loginbox->providerOp->Release(); + + if (NULL != loginbox->loginStatus) + { + loginbox->loginStatus->DetachWindow(); + loginbox->loginStatus->Release(); + } + + LoginGuiObject::UninitializeThread(); + + free(loginbox); +} + +static void LoginBox_OnGetMinMaxInfo(HWND hwnd, MINMAXINFO *mmi) +{ + if (NULL == mmi) return; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox) + { + mmi->ptMinTrackSize.x = loginbox->minmaxInfo.left; + mmi->ptMinTrackSize.y = loginbox->minmaxInfo.top; + mmi->ptMaxTrackSize.x = loginbox->minmaxInfo.right; + mmi->ptMaxTrackSize.y = loginbox->minmaxInfo.bottom; + } +} + +static void LoginBox_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags)) + { + LoginBox_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags)); + } +} + +static void LoginBox_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND hControl) +{ + switch(commandId) + { + case IDOK: + LoginBox_PerformLogin(hwnd, NULL); + break; + case IDCANCEL: + LoginBox_EndDialog(hwnd, AUTH_ABORT); + break; + case ID_LOGINBOX_UPDATEPROVIDERS: + LoginBox_UpdateProviders(hwnd, TRUE); + break; + case ID_LOGINTAB_RESETORDER: + LoginTab_ResetOrder(GetDlgItem(hwnd, IDC_TABFRAME)); + break; + } + +} + +static void LoginBox_OnTabSelected(HWND hwnd, HWND hFrame) +{ + LoginBox_SelectActivePage(hwnd); +} + +static void LoginBox_OnTabDeleted(HWND hwnd, HWND hFrame, INT iItem) +{ + if (NULL == hFrame || iItem < 0) return; + + NLTITEM tab; + tab.mask = NLTIF_PARAM | NLTIF_IMAGE_MASK; + if (FALSE != LoginTab_GetItem(hFrame, iItem, &tab)) + { + LoginBox_RemoveImageHelper2(hFrame, &tab); + + LoginProvider *provider = (LoginProvider*)tab.param; + if (NULL != provider) + provider->Release(); + + } +} + +static BOOL LoginBox_OnTabDeleteAll(HWND hwnd, HWND hFrame) +{ + if (NULL == hFrame) return FALSE; + + HIMAGELIST imageList = LoginTab_GetImageList(hFrame); + if (NULL != imageList) + ImageList_RemoveAll(imageList); + + NLTITEM tab; + tab.mask = NLTIF_PARAM; + + INT iItem = LoginTab_GetItemCount(hFrame); + while (iItem--) + { + if (FALSE != LoginTab_GetItem(hFrame, iItem, &tab)) + { + + LoginProvider *provider = (LoginProvider*)tab.param; + if (NULL != provider) + provider->Release(); + } + } + + return TRUE; +} +static void LoginBox_OnTabRClick(HWND hwnd, HWND hFrame, POINT pt) +{ + HMENU hMenu = WASABI_API_LOADMENUW(IDR_MENU_TABCONTEXT); + HMENU hContext = (NULL != hMenu) ? GetSubMenu(hMenu, 0) : NULL; + if (NULL == hContext) return; + + MapWindowPoints(hFrame, HWND_DESKTOP, &pt, 1); + + LOGINBOX *loginbox = GetLoginBox(hwnd); + UINT fEnable = (NULL != loginbox && NULL == loginbox->providerUpdate) ? MF_ENABLED : MF_DISABLED; + EnableMenuItem(hContext, ID_LOGINBOX_UPDATEPROVIDERS, fEnable | MF_BYCOMMAND); + + TrackPopupMenuEx(hContext, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_VERPOSANIMATION, pt.x, pt.y, hwnd, NULL); + +} +static void LoginBox_OnTabHelp(HWND hwnd, HWND hFrame, NMLOGINTABHELP *plth) +{ + if (NULL == plth || NULL == plth->param) + return; + LoginProvider *provider = (LoginProvider*)plth->param; + + WCHAR szBuffer[2048] = {0}; + if (SUCCEEDED(provider->GetDescription(szBuffer, ARRAYSIZE(szBuffer)))) + plth->bstrHelp = SysAllocString(szBuffer); +} +static void LoginBox_OnTabImage(HWND hwnd, HWND hFrame, NMLOGINTABIMAGE *plti) +{ + if (NULL == plti || NULL == plti->imageList) + return; + + if (NLTM_IMAGE_CALLBACK == plti->iImage) + { + plti->maskUpdate = NLTIF_IMAGE_MASK; + plti->iImage = NLTM_IMAGE_NONE; + plti->iImageActive = NLTM_IMAGE_NONE; + plti->iImageDisabled = NLTM_IMAGE_NONE; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox) + { + if (NULL == loginbox->imageCache) + LoginImageCache::CreateInstance(hwnd, &loginbox->imageCache); + + LoginProvider *provider = (LoginProvider*)plti->param; + if (NULL != provider && NULL != loginbox->imageCache) + { + WCHAR szImage[4096] = {0}; + if (SUCCEEDED(provider->GetImagePath(szImage, ARRAYSIZE(szImage)))) + { + loginbox->imageCache->GetImageListIndex(szImage, plti->imageList, + &plti->iImage, &plti->iImageActive, &plti->iImageDisabled); + } + } + } + return; + } + + if (0 != (NLTIF_IMAGE_ACTIVE & plti->maskRequest)) + { + plti->iImageActive = plti->iImage; + plti->maskUpdate |= NLTIF_IMAGE_ACTIVE; + } + + if (0 != (NLTIF_IMAGE_DISABLED & plti->maskRequest)) + { + plti->iImageDisabled = plti->iImage; + plti->maskUpdate |= NLTIF_IMAGE_DISABLED; + + } +} +static void LoginBox_OnPopupAgreementResult(HWND hwnd, NLPNRESULT *pnr) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + UINT curtainStyle = (NULL != hCurtain) ? GetWindowStyle(hCurtain) : 0; + if (0 != (WS_VISIBLE & curtainStyle)) + SetWindowLongPtr(hCurtain, GWL_STYLE, curtainStyle & ~WS_VISIBLE); + + UINT statusCookie = (UINT)(UINT_PTR)GetProp(pnr->hdr.hwndFrom, L"StatusCookie"); + RemoveProp(pnr->hdr.hwndFrom, L"StatusCookie"); + if (0 != statusCookie) + loginbox->loginStatus->Remove(statusCookie - 1); + + DestroyWindow(pnr->hdr.hwndFrom); + + + if (IDOK == pnr->exitCode) + { + loginbox->agreementOk = TRUE; + LoginBox_PerformLogin(hwnd, NULL); // this will restore curtain visibility + } + else + { + loginbox->agreementOk = FALSE; + + RECT invalidRect; + if (NULL != hCurtain) + { + GetWindowRect(hCurtain, &invalidRect); + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&invalidRect, 2); + } + else + SetRectEmpty(&invalidRect); + + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + if (FALSE == IsRectEmpty(&invalidRect)) + RedrawWindow(hwnd, &invalidRect, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_ERASENOW); + + LoginBox_PerformProviderOp(hwnd); + } +} + +static void LoginBox_OnPopupPasscodeResult(HWND hwnd, NPPNRESULT *pnr) +{ + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + UINT curtainStyle = (NULL != hCurtain) ? GetWindowStyle(hCurtain) : 0; + if (0 != (WS_VISIBLE & curtainStyle)) + SetWindowLongPtr(hCurtain, GWL_STYLE, curtainStyle & ~WS_VISIBLE); + + DestroyWindow(pnr->hdr.hwndFrom); + + if (IDOK == pnr->exitCode) + { + LoginBox_PerformLogin(hwnd, pnr->loginData); // this will restore curtain visibility + } + else + { + RECT invalidRect; + if (NULL != hCurtain) + { + GetWindowRect(hCurtain, &invalidRect); + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&invalidRect, 2); + } + else + SetRectEmpty(&invalidRect); + + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + if (FALSE == IsRectEmpty(&invalidRect)) + RedrawWindow(hwnd, &invalidRect, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_ERASENOW); + + LoginBox_PerformProviderOp(hwnd); + } +} + +static void LoginBox_OnPopupProviderOpResult(HWND hwnd, NLPNRESULT *pnr) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + HWND hCurtain = GetDlgItem(hwnd, IDC_CURTAIN); + UINT curtainStyle = (NULL != hCurtain) ? GetWindowStyle(hCurtain) : 0; + if (0 != (WS_VISIBLE & curtainStyle)) + SetWindowLongPtr(hCurtain, GWL_STYLE, curtainStyle & ~WS_VISIBLE); + + DestroyWindow(pnr->hdr.hwndFrom); + + RECT invalidRect; + if (NULL != hCurtain) + { + GetWindowRect(hCurtain, &invalidRect); + MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&invalidRect, 2); + } + else + SetRectEmpty(&invalidRect); + + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + if (FALSE == IsRectEmpty(&invalidRect)) + RedrawWindow(hwnd, &invalidRect, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_UPDATENOW | RDW_ERASENOW); + + if (NULL != loginbox->providerOp) + { + LoginProvider *source, *target; + GUID sourceId; + if(SUCCEEDED(loginbox->providerOp->GetSource(&source)) && NULL != source) + { + if (FAILED(source->GetId(&sourceId))) + sourceId = GUID_NULL; + + source->Release(); + + switch(loginbox->providerOp->GetCode()) + { + case LoginProviderOperation::operationReplace: + if(SUCCEEDED(loginbox->providerOp->GetTarget(&target))) + { + LoginBox_ReplaceProvider(hwnd, &sourceId, target); + target->Release(); + } + break; + case LoginProviderOperation::operationDelete: + LoginBox_DeleteProvider(hwnd, &sourceId); + break; + } + } + + loginbox->providerOp->Release(); + loginbox->providerOp = NULL; + } +} + +static LRESULT LoginBox_OnNotify(HWND hwnd, INT controlId, NMHDR *pnmh) +{ + switch(controlId) + { + case IDC_TABFRAME: + switch(pnmh->code) + { + case NLTN_SELCHANGE: + LoginBox_OnTabSelected(hwnd, pnmh->hwndFrom); + break; + case NLTN_DELETEITEM: + LoginBox_OnTabDeleted(hwnd, pnmh->hwndFrom, ((NMLOGINTAB*)pnmh)->iItem); + break; + case NLTN_DELETEALLITEMS: + return LoginBox_OnTabDeleteAll(hwnd, pnmh->hwndFrom); + case NM_RCLICK: + LoginBox_OnTabRClick(hwnd, pnmh->hwndFrom, ((NMLOGINTABCLICK*)pnmh)->pt); + break; + case NLTN_GETITEMHELP: + LoginBox_OnTabHelp(hwnd, pnmh->hwndFrom, (NMLOGINTABHELP*)pnmh); + break; + case NLTN_GETITEMIMAGE: + LoginBox_OnTabImage(hwnd, pnmh->hwndFrom, (NMLOGINTABIMAGE*)pnmh); + break; + } + break; + case IDC_POPUPAGREEMENT: + switch(pnmh->code) + { + case NLPN_RESULT: + LoginBox_OnPopupAgreementResult(hwnd, (NLPNRESULT*)pnmh); + break; + } + break; + case IDC_POPUPPASSCODE: + switch(pnmh->code) + { + case NPPN_RESULT: + LoginBox_OnPopupPasscodeResult(hwnd, (NPPNRESULT*)pnmh); + break; + } + break; + case IDC_POPUPPROVIDEROP: + switch(pnmh->code) + { + case NLPN_RESULT: + LoginBox_OnPopupProviderOpResult(hwnd, (NLPNRESULT*)pnmh); + break; + } + break; + + } + return 0; +} + +static INT_PTR LoginBox_OnNcHitTest(HWND hwnd, POINTS pts) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox) + { + POINT pt; + POINTSTOPOINT(pt, pts); + MapWindowPoints(HWND_DESKTOP, hwnd, &pt, 1); + + LONG offsetX = (loginbox->gripRect.right - loginbox->gripRect.left)/3; + LONG offsetY = (loginbox->gripRect.bottom - loginbox->gripRect.top)/3; + if (pt.x < loginbox->gripRect.right && pt.y < loginbox->gripRect.bottom && + pt.x > (loginbox->gripRect.left + offsetX) && pt.y > (loginbox->gripRect.top + offsetY)) + { + SetWindowLongPtr(hwnd, DWLP_MSGRESULT, HTBOTTOMRIGHT); + return TRUE; + } + } + return FALSE; +} + + +static void LoginBox_OnSetFont(HWND hwnd, HFONT hFont, BOOL fRedraw) +{ + DefWindowProc(hwnd, WM_SETFONT, (WPARAM)hFont, MAKELPARAM(fRedraw, 0)); + LoginBox_UpdateMargins(hwnd); +} +static void LoginBox_OnPaint(HWND hwnd) +{ + PAINTSTRUCT ps; + if (BeginPaint(hwnd, &ps)) + { + if (ps.rcPaint.left != ps.rcPaint.right) + LoginBox_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase); + EndPaint(hwnd, &ps); + } +} + +static void LoginBox_OnPrintClient(HWND hwnd, HDC hdc, UINT options) +{ + if (0 != (PRF_CLIENT & options)) + { + RECT clientRect; + if (GetClientRect(hwnd, &clientRect)) + LoginBox_Paint(hwnd, hdc, &clientRect, TRUE); + } +} +static HBRUSH LoginBox_OnGetStaticColor(HWND hwnd, HDC hdc, HWND hControl) +{ + HBRUSH hb; + INT_PTR controlId = (INT_PTR)GetWindowLongPtr(hControl, GWLP_ID); + switch(controlId) + { + case IDC_STATUS: + hb = (HBRUSH)SendMessage(hwnd, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd); + SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT)); + return hb; + } + return 0; +} + +static BOOL LoginBox_OnGetAuthApi(HWND hwnd, api_auth **authApi) +{ + if (NULL == authApi) return FALSE; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox || NULL == loginbox->auth) + { + *authApi = NULL; + return FALSE; + } + + *authApi = loginbox->auth; + loginbox->auth->AddRef(); + + return TRUE; +} + +static BOOL LoginBox_OnGetRealm(HWND hwnd, GUID *realm) +{ + if (NULL == realm) return FALSE; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) + { + *realm = GUID_NULL; + return FALSE; + } + + *realm = loginbox->realm; + return TRUE; +} + +static BOOL LoginBox_OnGetActiveProvider(HWND hwnd, LoginProvider **provider) +{ + if (NULL == provider) + return FALSE; + + *provider = LoginBox_GetActiveProviderInternal(hwnd); + if (NULL == (*provider)) + return FALSE; + + (*provider)->AddRef(); + return TRUE; +} + +static void LoginBox_OnLoginCompleted(HWND hwnd, LoginResult *result) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox || NULL == result || loginbox->loginResult != result) + return; + + INT authError = AUTH_ABORT; + LoginProvider *provider = LoginBox_GetActiveProviderInternal(hwnd); + if (NULL != provider) + { + LoginCommand *command; + if (SUCCEEDED(provider->GetCommand(&command))) + { + LoginCredentials *credentials; + if (SUCCEEDED(command->EndLogin(result, &authError, &credentials))) + { + switch(authError) + { + case AUTH_SUCCESS: + authError = LoginBox_SetCredentials(hwnd, credentials); + LoginBox_SaveUsername(&loginbox->realm, provider, credentials); + break; + + case AUTH_SECURID: + authError = LoginBox_RequestPasscode(hwnd, result); + if (AUTH_SUCCESS == authError) + authError = AUTH_SECURID; + break; + } + + if (NULL != credentials) + credentials->Release(); + } + command->Release(); + } + } + + + loginbox->loginResult = NULL; + result->Release(); + + switch(authError) + { + case AUTH_SUCCESS: + LoginBox_EndDialog(hwnd, AUTH_SUCCESS); + break; + case AUTH_SECURID: + break; + default: + LoginBox_EnableLoginMode(hwnd, FALSE, FALSE); + if (AUTH_ABORT != authError) + { + HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER); + if (NULL != hNotifier) + { + LoginNotifier_Notify(hNotifier, NLNTYPE_ERROR, MAKEINTRESOURCE(authError)); + LoginBox_ShowNotifier(hwnd, 200); + } + } + + LoginBox_PerformProviderOp(hwnd); + break; + } + +} + +static BOOL LoginBox_OnGetStatus(HWND hwnd, LoginStatus **loginStatus) +{ + if (NULL == loginStatus) + return FALSE; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox && NULL !=loginbox->loginStatus) + { + *loginStatus = loginbox->loginStatus; + (*loginStatus)->AddRef(); + return TRUE; + } + + return FALSE; +} +static UINT LoginBox_OnAddStatus(HWND hwnd, BSTR pszStatus) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox && NULL !=loginbox->loginStatus) + return loginbox->loginStatus->Add(pszStatus); + + return 0; +} + +static BOOL LoginBox_OnSetStatus(HWND hwnd, UINT cookie, BSTR pszStatus) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox && NULL !=loginbox->loginStatus) + return loginbox->loginStatus->Set(cookie, pszStatus); + + return TRUE; +} + +static void LoginBox_OnRemoveStatus(HWND hwnd, UINT cookie) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox && NULL !=loginbox->loginStatus) + loginbox->loginStatus->Remove(cookie); +} + +static BOOL LoginBox_ApplyProvidersUpdate(HWND hwnd, LoginProviderEnumerator *providerEnum) +{ + if (NULL == providerEnum) + return FALSE; + + GUID activeId(GUID_NULL); + INT activeIndex(-1); + LoginProviderOperation *providerOp(NULL); + LoginProvider *providerActive = LoginBox_GetActiveProviderInternal(hwnd); + if (NULL != providerActive) + { + providerActive->GetId(&activeId); + + if (S_OK != LoginProviderOperation::CreateFromUpdate(providerActive, providerEnum, &providerOp)) + providerOp = NULL; + } + + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL != hFrame) + { + UINT frameStyle = GetWindowStyle(hFrame); + if (0 != (WS_VISIBLE & frameStyle)) + SetWindowLongPtr(hFrame, GWL_STYLE, frameStyle & ~WS_VISIBLE); + + LoginBox_DeleteAllTabs(hwnd); + providerEnum->Reset(); + + if(NULL != providerOp) + LoginBox_AppendMultipleTabs(hwnd, providerEnum, &activeId, &activeIndex); + else + LoginBox_AppendMultipleTabs(hwnd, providerEnum, NULL, NULL); + + LoginProvider *provider; + if (NULL != providerOp && SUCCEEDED(providerOp->GetSource(&provider))) + { + LoginBox_InsertTab(hwnd, activeIndex, provider); + provider->Release(); + } + + activeIndex = (FALSE == IsEqualGUID(activeId, GUID_NULL)) ? + LoginBox_FindTabByProviderId(hwnd, &activeId) : -1; + + if (-1 != activeIndex) + { + LoginTab_SetCurSel(hFrame, activeIndex); + } + else + { + LoginTab_SetCurSel(hFrame, 0); + LoginBox_SelectActivePage(hwnd); + } + + if (0 != (WS_VISIBLE & frameStyle)) + { + frameStyle = GetWindowStyle(hFrame); + if (0 == (WS_VISIBLE & frameStyle)) + SetWindowLongPtr(hFrame, GWL_STYLE, frameStyle | WS_VISIBLE); + + RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN); + UpdateWindow(hFrame); + } + } + + if (NULL != providerOp) + { + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL != loginbox) + { + if (NULL != loginbox->providerOp) + loginbox->providerOp->Release(); + loginbox->providerOp = providerOp; + providerOp->AddRef(); + + } + providerOp->Release(); + } + LoginBox_PerformProviderOp(hwnd); + + return TRUE; +} + +static void LoginBox_OnProvidersUpdated(HWND hwnd, PROVIDERUPDATERESULT *result) +{ + if (NULL == result) + return; + + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox) return; + + + BOOL dataIdentical; + LoginProviderEnumerator *providerEnum; + HRESULT resultCode = result->errorCode; + + if (SUCCEEDED(resultCode)) + { + providerEnum = result->enumerator; + if(NULL != providerEnum) providerEnum->AddRef(); + + dataIdentical = result->dataIdentical; + } + else + { + providerEnum = NULL; + dataIdentical = FALSE; + } + + BOOL storedUpdate = (NULL != loginbox->providerUpdate && + loginbox->providerUpdate == result->downloader); + + ReplyMessage(0); + + if (SUCCEEDED(resultCode)) + { + BOOL updateOk; + + if(FALSE == dataIdentical) + updateOk = LoginBox_ApplyProvidersUpdate(hwnd, providerEnum); + else + updateOk = TRUE; + + if(FALSE != updateOk) + { + LoginConfig *config; + if (SUCCEEDED(LoginConfig::CreateInstance(&config))) + { + UINT ts = LoginBox_GetCurrentTime(); + config->WriteInt("LoginBox", "lastCheck", ts); + + LPSTR lang; + if (FAILED(LoginBox_GetCurrentLang(&lang))) + lang = NULL; + + config->WriteAnsiStr("LoginBox", "lastLang", lang); + LoginBox_FreeAnsiString(lang); + + config->Release(); + } + } + + } + + if (NULL != providerEnum) + providerEnum->Release(); + + if (FALSE != storedUpdate) + { + loginbox->providerUpdate->Release(); + loginbox->providerUpdate = NULL; + + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + if (NULL != hPage) + LoginPage_UpdateStateChange(hPage, FALSE); + } +} + +static void CALLBACK LoginBox_DownloadCompleted(LoginDownloadResult *result, void *data) +{ + HWND hLoginbox = (HWND)data; + if(NULL == result || FALSE == IsWindow(hLoginbox)) return; + + UINT type; + if (FAILED(result->GetType(&type)) || LoginDownloadResult::typeProviderList != type) + return; + + BSTR fileName = NULL; + LoginDownload download; + HRESULT hr = download.End(result, &fileName); + + LoginProviderEnumerator *enumerator = NULL; + + if (SUCCEEDED(hr)) + { + if (S_FALSE != hr) + { + LoginProviderLoader loader; + hr = loader.ReadXml(fileName, &enumerator, NULL); + if (FAILED(hr)) + enumerator = NULL; + } + } + + LoginBox_ProvidersUpdated(hLoginbox, result, hr, (S_FALSE == hr), enumerator); + + if (NULL != enumerator) + enumerator->Release(); + + SysFreeString(fileName); + +} + +static BOOL LoginBox_OnUpdateProviders(HWND hwnd, BOOL forceUpdate) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + if (NULL == loginbox || NULL != loginbox->providerUpdate) + return FALSE; + + if (FALSE == forceUpdate) + { + LoginConfig *config; + if (SUCCEEDED(LoginConfig::CreateInstance(&config))) + { + BOOL checkRequired = TRUE; + UINT ts = LoginBox_GetCurrentTime(); + UINT lastCheck = config->ReadInt("LoginBox", "lastCheck", 0); + + if ((ts - lastCheck) < (60*60*24)) // check once 24 hours + { + checkRequired = FALSE; + + LPSTR lang; + if (SUCCEEDED(LoginBox_GetCurrentLang(&lang))) + { + CHAR lastLang[32] = {0}; + config->ReadAnsiStr("LoginBox", "lastLang", NULL, lastLang, ARRAYSIZE(lastLang)); + checkRequired = (NULL == lang || NULL == lastLang) ? + ((NULL == lang) != (NULL == lastLang)) : + (CSTR_EQUAL != CompareStringA(CSTR_INVARIANT, NORM_IGNORECASE, lang, -1, lastLang, -1)); + + LoginBox_FreeAnsiString(lang); + } + } + + config->Release(); + + if (FALSE == checkRequired) + return FALSE; + } + } + + WCHAR szUrl[4096] = {0}; + LPWSTR cursor = szUrl; + size_t remaining = ARRAYSIZE(szUrl); + + HRESULT hr; + hr = StringCchCopyEx(cursor, remaining, PROVIDERLIST_URL, &cursor, &remaining, 0); + if (SUCCEEDED(hr)) + { + if (NULL != WASABI_API_LNG) + { + LPCWSTR lang = WASABI_API_LNG->GetLanguageIdentifier(LANG_LANG_CODE); + if (NULL != lang && L'\0' != *lang) + { + hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, 0, L"?lang=%s", lang); + } + } + } + + if (SUCCEEDED(hr)) + { + HWND hPage = GetDlgItem(hwnd, IDC_ACTIVEPAGE); + if (NULL != hPage) + LoginPage_UpdateStateChange(hPage, TRUE); + + LoginDownload download; + hr = download.Begin(szUrl, LoginDownloadResult::typeProviderList, LoginBox_DownloadCompleted, + hwnd, loginbox->loginStatus, &loginbox->providerUpdate); + if (FAILED(hr)) + { + loginbox->providerUpdate = NULL; + if (NULL != hPage) + LoginPage_UpdateStateChange(hPage, FALSE); + } + } + + return SUCCEEDED(hr); +} + +static BOOL LoginBox_OnGetUpdateState(HWND hwnd) +{ + LOGINBOX *loginbox = GetLoginBox(hwnd); + return (NULL != loginbox && NULL != loginbox->providerUpdate); +} + +static void LoginBox_OnImageCached(HWND hwnd, IMAGECACHERESULT *result) +{ + LoginImageCache *cache = NULL; + ifc_omcacherecord *record = NULL; + if (NULL != result) + { + cache = result->imageCache; + record = result->cacheRecord; + } + + if (NULL != cache) cache->AddRef(); + if (NULL != record) record->AddRef(); + + ReplyMessage(0); + + if (NULL != cache && NULL != record) + { + WCHAR szName[4096] = {0}; + if (SUCCEEDED(record->GetName(szName, ARRAYSIZE(szName)))) + { + HWND hFrame = GetDlgItem(hwnd, IDC_TABFRAME); + if (NULL != hFrame) + { + NLTITEM tab; + tab.mask = NLTIF_PARAM; + INT count = LoginTab_GetItemCount(hFrame); + for (INT i = 0; i < count; i++) + { + if (FALSE != LoginTab_GetItem(hFrame, i, &tab)) + { + WCHAR szImage[4096] = {0}; + LoginProvider *provider = (LoginProvider*)tab.param; + if (NULL != provider && + SUCCEEDED(provider->GetImagePath(szImage, ARRAYSIZE(szImage))) && + S_OK == LoginBox_IsStrEqInvI(szImage, szName)) + { + + + LoginBox_RemoveImageHelper2(hFrame, &tab); + + tab.mask = NLTIF_IMAGE_MASK; + tab.iImage = NLTM_IMAGE_CALLBACK; + tab.iImageActive = NLTM_IMAGE_CALLBACK; + tab.iImageDisabled = NLTM_IMAGE_CALLBACK; + LoginTab_SetItem(hFrame, i, &tab); + tab.mask = NLTIF_PARAM; + } + } + } + } + } + + } + + if (NULL != cache) cache->Release(); + if (NULL != record) record->Release(); +} + +static INT_PTR CALLBACK LoginBox_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch(uMsg) + { + case WM_INITDIALOG: return LoginBox_OnInitDialog(hwnd, (HWND)wParam, lParam); + case WM_DESTROY: LoginBox_OnDestroy(hwnd); return 0; + case WM_WINDOWPOSCHANGED: LoginBox_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return TRUE; + case WM_COMMAND: LoginBox_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE; + case WM_NOTIFY: MSGRESULT(hwnd, LoginBox_OnNotify(hwnd, (INT)wParam, (NMHDR*)lParam)); + case WM_GETMINMAXINFO: LoginBox_OnGetMinMaxInfo(hwnd, (MINMAXINFO*)lParam); return TRUE; + case WM_ERASEBKGND: MSGRESULT(hwnd, 0); + case WM_PAINT: LoginBox_OnPaint(hwnd); return TRUE; + case WM_PRINTCLIENT: LoginBox_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return TRUE; + case WM_CTLCOLORSTATIC: return (INT_PTR)LoginBox_OnGetStaticColor(hwnd, (HDC)wParam, (HWND)lParam); + case WM_NCHITTEST: return LoginBox_OnNcHitTest(hwnd, MAKEPOINTS(lParam)); + case WM_SETFONT: LoginBox_OnSetFont(hwnd, (HFONT)wParam, LOWORD(lParam)); return TRUE; + case WM_SIZE: MSGRESULT(hwnd, 0); + + case NLBM_GETAUTHAPI: MSGRESULT(hwnd, LoginBox_OnGetAuthApi(hwnd, (api_auth**)lParam)); + case NLBM_GETREALM: MSGRESULT(hwnd, LoginBox_OnGetRealm(hwnd, (GUID*)lParam)); + case NLBM_GETACTIVEPROVIDER:MSGRESULT(hwnd, LoginBox_OnGetActiveProvider(hwnd, (LoginProvider**)lParam)); + case NLBM_GETSTATUS: MSGRESULT(hwnd, LoginBox_OnGetStatus(hwnd, (LoginStatus**)lParam)); + case NLBM_ADDSTATUS: MSGRESULT(hwnd, LoginBox_OnAddStatus(hwnd, (BSTR)lParam)); + case NLBM_SETSTATUS: MSGRESULT(hwnd, LoginBox_OnSetStatus(hwnd, (UINT)wParam, (BSTR)lParam)); + case NLBM_REMOVESTATUS: LoginBox_OnRemoveStatus(hwnd, (UINT)wParam); + case NLBM_UPDATEPROVIDERS: MSGRESULT(hwnd, LoginBox_OnUpdateProviders(hwnd, (BOOL)wParam)); + case NLBM_GETUPDATESTATE: MSGRESULT(hwnd, LoginBox_OnGetUpdateState(hwnd)); + case NLBM_LOGINCOMPLETED: LoginBox_OnLoginCompleted(hwnd, (LoginResult*)lParam); return TRUE; + case NLBM_PROVIDERSUPDATED: LoginBox_OnProvidersUpdated(hwnd, (PROVIDERUPDATERESULT*)lParam); return TRUE; + case NLBM_IMAGECACHED: LoginBox_OnImageCached(hwnd, (IMAGECACHERESULT*)lParam); return TRUE; + } + + return FALSE; +} -- cgit