Initial community commit
This commit is contained in:
660
Src/auth/Loginbox/addressEditbox.cpp
Normal file
660
Src/auth/Loginbox/addressEditbox.cpp
Normal file
@@ -0,0 +1,660 @@
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include "./addressEditbox.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <richedit.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define NAEF_USERFLAGSMASK 0x00FFFFFF
|
||||
#define NAEF_UNICODE 0x01000000
|
||||
|
||||
|
||||
typedef struct __ADDRESSEDITBOX
|
||||
{
|
||||
WNDPROC originalProc;
|
||||
UINT flags;
|
||||
DWORD dblclkTime; LPWSTR rollbackText;
|
||||
} ADDRESSEDITBOX;
|
||||
|
||||
#define ADDRESSEDITBOX_PROP L"NullsoftAddressEditbox"
|
||||
|
||||
#define GetEditbox(__hwnd) ((ADDRESSEDITBOX*)GetProp((__hwnd), ADDRESSEDITBOX_PROP))
|
||||
|
||||
static LRESULT CALLBACK AddressEditbox_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static INT CALLBACK AddressEditbox_WordBreakProc(LPWSTR pszText, INT iCurrent, INT cchLen, INT code);
|
||||
static INT CALLBACK AddressEditbox_WordBreakProc2(LPWSTR pszText, INT iCurrent, INT cchLen, INT code);
|
||||
|
||||
BOOL AddressEditbox_AttachWindow(HWND hEditbox)
|
||||
{
|
||||
if (!IsWindow(hEditbox))
|
||||
return FALSE;
|
||||
|
||||
ADDRESSEDITBOX *editbox = (ADDRESSEDITBOX*)GetProp(hEditbox, ADDRESSEDITBOX_PROP);
|
||||
if (NULL != editbox) return TRUE;
|
||||
|
||||
editbox = (ADDRESSEDITBOX*)calloc(1, sizeof(ADDRESSEDITBOX));
|
||||
if (NULL == editbox) return FALSE;
|
||||
|
||||
|
||||
ZeroMemory(editbox, sizeof(ADDRESSEDITBOX));
|
||||
|
||||
if (IsWindowUnicode(hEditbox))
|
||||
editbox->flags |= NAEF_UNICODE;
|
||||
|
||||
editbox->originalProc = (WNDPROC)(LONG_PTR)((0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)AddressEditbox_WindowProc) :
|
||||
SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)AddressEditbox_WindowProc));
|
||||
|
||||
if (NULL == editbox->originalProc || !SetProp(hEditbox, ADDRESSEDITBOX_PROP, editbox))
|
||||
{
|
||||
if (NULL != editbox->originalProc)
|
||||
{
|
||||
if (0 != (NAEF_UNICODE & editbox->flags))
|
||||
SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
}
|
||||
|
||||
free(editbox);
|
||||
return FALSE;
|
||||
}
|
||||
SendMessage(hEditbox, EM_SETWORDBREAKPROC, 0, (LPARAM)AddressEditbox_WordBreakProc);
|
||||
|
||||
|
||||
if (FAILED(LoginBox_GetWindowText(hEditbox, &editbox->rollbackText, NULL)))
|
||||
editbox->rollbackText = NULL;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void AddressEditbox_Detach(HWND hwnd)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
RemoveProp(hwnd, ADDRESSEDITBOX_PROP);
|
||||
|
||||
if (NULL == editbox)
|
||||
return;
|
||||
|
||||
if (NULL != editbox->originalProc)
|
||||
{
|
||||
if (0 != (NAEF_UNICODE & editbox->flags))
|
||||
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
}
|
||||
|
||||
free(editbox);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT AddressEditbox_CallOrigWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
|
||||
if (NULL == editbox || NULL == editbox->originalProc)
|
||||
{
|
||||
return (0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
DefWindowProcW(hwnd, uMsg, wParam, lParam) :
|
||||
DefWindowProcA(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
return (0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
CallWindowProcW(editbox->originalProc, hwnd, uMsg, wParam, lParam) :
|
||||
CallWindowProcA(editbox->originalProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void AddressEditbox_SelectReplacementBlock(HWND hwnd, LPCWSTR pszText)
|
||||
{
|
||||
INT begin(-1), end(-1);
|
||||
|
||||
if (NULL != pszText)
|
||||
{
|
||||
LPCWSTR cursor = pszText;
|
||||
while(L'\0' != *cursor)
|
||||
{
|
||||
if (-1 == begin)
|
||||
{
|
||||
if (REPLACE_MARKER_BEGIN == *cursor)
|
||||
begin = (INT)(INT_PTR)(cursor - pszText);
|
||||
}
|
||||
else if (REPLACE_MARKER_END == *cursor)
|
||||
{
|
||||
end = (INT)(INT_PTR)(cursor - pszText) + 1;
|
||||
break;
|
||||
}
|
||||
cursor = CharNext(cursor);
|
||||
}
|
||||
if (-1 == begin || -1 == end)
|
||||
{
|
||||
begin = (INT)(INT_PTR)(cursor - pszText);
|
||||
end = begin + 1;
|
||||
}
|
||||
}
|
||||
|
||||
SendMessage(hwnd, EM_SETSEL, begin, end);
|
||||
}
|
||||
static void AddressEditbox_ResetText(HWND hwnd)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
if (NULL != editbox)
|
||||
{
|
||||
AddressEditbox_CallOrigWindowProc(hwnd, WM_SETTEXT, 0, (LPARAM)editbox->rollbackText);
|
||||
AddressEditbox_SelectReplacementBlock(hwnd, editbox->rollbackText);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL AddressEditbox_IsDelimiterChar(WCHAR testChar)
|
||||
{
|
||||
WORD info;
|
||||
if (FALSE == GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, &testChar, 1, &info))
|
||||
return 0;
|
||||
|
||||
if (0 != ((C1_SPACE | C1_PUNCT | C1_CNTRL | C1_BLANK) & info) &&
|
||||
REPLACE_MARKER_BEGIN != testChar && REPLACE_MARKER_END != testChar)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static INT AddressEditbox_FindLeft(LPCWSTR pszText, INT iCurrent, INT cchLen)
|
||||
{
|
||||
if (iCurrent <= 0)
|
||||
return 0;
|
||||
|
||||
LPCWSTR pszCursor = &pszText[iCurrent];
|
||||
BOOL charDelim = AddressEditbox_IsDelimiterChar(*pszCursor);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
pszCursor = CharPrev(pszText, pszCursor);
|
||||
if (charDelim != AddressEditbox_IsDelimiterChar(*pszCursor))
|
||||
return (INT)(INT_PTR)(CharNext(pszCursor) - pszText);
|
||||
|
||||
if (pszCursor == pszText)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT AddressEditbox_FindRight(LPCWSTR pszText, INT iCurrent, INT cchLen)
|
||||
{
|
||||
if (iCurrent >= cchLen)
|
||||
return cchLen;
|
||||
|
||||
LPCWSTR pszEnd = &pszText[cchLen];
|
||||
LPCWSTR pszCursor = &pszText[iCurrent];
|
||||
|
||||
if (iCurrent > 0)
|
||||
pszCursor = CharNext(pszCursor);
|
||||
|
||||
BOOL charDelim = AddressEditbox_IsDelimiterChar(*pszCursor);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
pszCursor = CharNext(pszCursor);
|
||||
if (pszCursor >= pszEnd)
|
||||
break;
|
||||
|
||||
if (charDelim != AddressEditbox_IsDelimiterChar(*pszCursor))
|
||||
return (INT)(INT_PTR)(pszCursor - pszText);
|
||||
}
|
||||
return cchLen;
|
||||
}
|
||||
|
||||
static INT AddressEditbox_FindWordLeft(LPCWSTR pszText, INT iCurrent, INT cchLen, BOOL fRightCtrl)
|
||||
{
|
||||
if (iCurrent < 2)
|
||||
return 0;
|
||||
|
||||
LPCWSTR pszCursor = &pszText[iCurrent];
|
||||
|
||||
if (FALSE == fRightCtrl)
|
||||
pszCursor = CharPrev(pszText, pszCursor);
|
||||
|
||||
BOOL prevCharDelim = AddressEditbox_IsDelimiterChar(*pszCursor);
|
||||
for(;;)
|
||||
{
|
||||
pszCursor = CharPrev(pszText, pszCursor);
|
||||
if (TRUE == AddressEditbox_IsDelimiterChar(*pszCursor))
|
||||
{
|
||||
if (FALSE == prevCharDelim)
|
||||
return (INT)(INT_PTR)(CharNext(pszCursor) - pszText);
|
||||
|
||||
prevCharDelim = TRUE;
|
||||
}
|
||||
else
|
||||
prevCharDelim = FALSE;
|
||||
|
||||
if (pszCursor == pszText)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT AddressEditbox_FindWordRight(LPCWSTR pszText, INT iCurrent, INT cchLen)
|
||||
{
|
||||
if ( iCurrent >= (cchLen - 1))
|
||||
return cchLen;
|
||||
|
||||
LPCWSTR pszEnd = &pszText[cchLen];
|
||||
LPCWSTR pszCursor = &pszText[iCurrent];
|
||||
|
||||
BOOL prevCharDelim = AddressEditbox_IsDelimiterChar(*pszCursor);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
pszCursor = CharNext(pszCursor);
|
||||
if (pszCursor >= pszEnd)
|
||||
break;
|
||||
|
||||
if (prevCharDelim != AddressEditbox_IsDelimiterChar(*pszCursor))
|
||||
{
|
||||
prevCharDelim = TRUE;
|
||||
return (INT)(INT_PTR)(pszCursor - pszText);
|
||||
}
|
||||
else
|
||||
prevCharDelim = FALSE;
|
||||
|
||||
}
|
||||
return cchLen;
|
||||
}
|
||||
|
||||
static INT CALLBACK AddressEditbox_WordBreakProc(LPWSTR pszText, INT iCurrent, INT cchLen, INT code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case WB_ISDELIMITER: return (iCurrent < 0) ? 0 : ((iCurrent > cchLen) ? (cchLen + 1) : AddressEditbox_IsDelimiterChar(pszText[iCurrent]));
|
||||
case WB_LEFT: return AddressEditbox_FindLeft(pszText, iCurrent, cchLen);
|
||||
case WB_RIGHT: return AddressEditbox_FindRight(pszText, iCurrent, cchLen);
|
||||
case WB_MOVEWORDLEFT: return AddressEditbox_FindWordLeft(pszText, iCurrent, cchLen, FALSE);
|
||||
case WB_MOVEWORDRIGHT: return AddressEditbox_FindWordRight(pszText, iCurrent, cchLen);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT CALLBACK AddressEditbox_WordBreakProcOverrideLeft(LPWSTR pszText, INT iCurrent, INT cchLen, INT code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case WB_LEFT: return AddressEditbox_FindWordLeft(pszText, iCurrent, cchLen, FALSE);
|
||||
case WB_RIGHT: return AddressEditbox_FindWordRight(pszText, iCurrent, cchLen);
|
||||
}
|
||||
return AddressEditbox_WordBreakProc(pszText, iCurrent, cchLen, code);
|
||||
}
|
||||
|
||||
static INT CALLBACK AddressEditbox_WordBreakProcOverrideRight(LPWSTR pszText, INT iCurrent, INT cchLen, INT code)
|
||||
{
|
||||
switch(code)
|
||||
{
|
||||
case WB_LEFT: return AddressEditbox_FindWordLeft(pszText, iCurrent, cchLen, TRUE);
|
||||
case WB_RIGHT: return AddressEditbox_FindWordRight(pszText, iCurrent, cchLen);
|
||||
}
|
||||
return AddressEditbox_WordBreakProc(pszText, iCurrent, cchLen, code);
|
||||
}
|
||||
|
||||
|
||||
static void AddressEditbox_OnDestroy(HWND hwnd)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
|
||||
WNDPROC originalProc = editbox->originalProc;
|
||||
BOOL fUnicode = (0 != (NAEF_UNICODE & editbox->flags));
|
||||
|
||||
AddressEditbox_Detach(hwnd);
|
||||
|
||||
if (NULL != originalProc)
|
||||
{
|
||||
if (FALSE != fUnicode)
|
||||
CallWindowProcW(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
else
|
||||
CallWindowProcA(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static LRESULT AddressEditbox_OnGetDlgCode(HWND hwnd, INT vKey, MSG* pMsg)
|
||||
{
|
||||
LRESULT result = AddressEditbox_CallOrigWindowProc(hwnd, WM_GETDLGCODE, (WPARAM)vKey, (LPARAM)pMsg);
|
||||
|
||||
switch(vKey)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
return result |= DLGC_WANTALLKEYS;
|
||||
}
|
||||
|
||||
result &= ~DLGC_HASSETSEL;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static void AddressEditbox_OnLButtonDown(HWND hwnd, UINT vKey, POINTS pts)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
if (NULL != editbox)
|
||||
{
|
||||
DWORD clickTime = GetTickCount();
|
||||
if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + GetDoubleClickTime()))
|
||||
{
|
||||
SendMessage(hwnd, EM_SETSEL, 0, -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
AddressEditbox_CallOrigWindowProc(hwnd, WM_LBUTTONDOWN, (WPARAM)vKey, *((LPARAM*)&pts));
|
||||
}
|
||||
|
||||
static void AddressEditbox_OnLButtonDblClk(HWND hwnd, UINT vKey, POINTS pts)
|
||||
{
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
if (NULL == editbox) return;
|
||||
|
||||
DWORD clickTime = GetTickCount();
|
||||
if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + 2*GetDoubleClickTime()))
|
||||
{
|
||||
INT r = (INT)SendMessage(hwnd, EM_CHARFROMPOS, 0, *(LPARAM*)&pts);
|
||||
r = LOWORD(r);
|
||||
SendMessage(hwnd, EM_SETSEL, (WPARAM)r, (LPARAM)r);
|
||||
editbox->dblclkTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
editbox->dblclkTime = clickTime;
|
||||
}
|
||||
|
||||
INT f, l;
|
||||
SendMessage(hwnd, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
|
||||
if (f != l) return;
|
||||
|
||||
|
||||
AddressEditbox_CallOrigWindowProc(hwnd, WM_LBUTTONDBLCLK, (WPARAM)vKey, *((LPARAM*)&pts));
|
||||
|
||||
}
|
||||
|
||||
|
||||
static void AddressEditbox_DeleteWord(HWND hwnd, UINT vKey, UINT state)
|
||||
{
|
||||
BOOL resetVisible = FALSE;
|
||||
INT first, last;
|
||||
SendMessage(hwnd, EM_GETSEL, (WPARAM)&first, (LPARAM)&last);
|
||||
if (first == last)
|
||||
{
|
||||
UINT windowStyle = GetWindowStyle(hwnd);
|
||||
if (0 != (WS_VISIBLE & windowStyle))
|
||||
{
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
|
||||
resetVisible = TRUE;
|
||||
}
|
||||
|
||||
SendMessage(hwnd, WM_KEYDOWN, (WPARAM)vKey, (LPARAM)state);
|
||||
INT newFirst, newLast;
|
||||
SendMessage(hwnd, EM_GETSEL, (WPARAM)&newFirst, (LPARAM)&newLast);
|
||||
if (newFirst != first || newLast != last)
|
||||
SendMessage(hwnd, EM_SETSEL, (WPARAM)first, (LPARAM)newLast);
|
||||
}
|
||||
|
||||
SendMessage(hwnd, EM_REPLACESEL, TRUE, NULL);
|
||||
if (FALSE != resetVisible)
|
||||
{
|
||||
UINT windowStyle = GetWindowStyle(hwnd);
|
||||
if (0 == (WS_VISIBLE & windowStyle))
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
|
||||
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
static void AddressEditbox_OnKeyDown(HWND hwnd, UINT vKey, UINT state)
|
||||
{
|
||||
EDITWORDBREAKPROC fnOrigBreak = NULL;
|
||||
if(0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
|
||||
{
|
||||
switch(vKey)
|
||||
{
|
||||
case VK_LEFT:
|
||||
case VK_RIGHT:
|
||||
fnOrigBreak = (EDITWORDBREAKPROC)SendMessage(hwnd, EM_GETWORDBREAKPROC, 0, 0L);
|
||||
if (AddressEditbox_WordBreakProc == fnOrigBreak)
|
||||
{
|
||||
EDITWORDBREAKPROC fnOverride = (VK_LEFT == vKey) ?
|
||||
AddressEditbox_WordBreakProcOverrideLeft : AddressEditbox_WordBreakProcOverrideRight;
|
||||
SendMessage(hwnd, EM_SETWORDBREAKPROC, 0, (LPARAM)fnOverride);
|
||||
}
|
||||
break;
|
||||
case VK_DELETE:
|
||||
AddressEditbox_DeleteWord(hwnd, VK_RIGHT, state);
|
||||
return;
|
||||
case VK_BACK:
|
||||
AddressEditbox_DeleteWord(hwnd, VK_LEFT, state);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AddressEditbox_CallOrigWindowProc(hwnd, WM_KEYDOWN, (WPARAM)vKey, (LPARAM)state);
|
||||
|
||||
if (NULL != fnOrigBreak)
|
||||
SendMessage(hwnd, EM_SETWORDBREAKPROC, 0, (LPARAM)fnOrigBreak);
|
||||
}
|
||||
|
||||
static void AddressEditbox_OnChar(HWND hwnd, UINT vKey, UINT state)
|
||||
{
|
||||
if (0 != (0x8000 & GetAsyncKeyState(VK_CONTROL)))
|
||||
{
|
||||
UINT scanCode = (HIWORD(state) & 0x00FF);
|
||||
vKey = MapVirtualKey(scanCode, MAPVK_VSC_TO_VK);
|
||||
}
|
||||
|
||||
switch(vKey)
|
||||
{
|
||||
case VK_ESCAPE: AddressEditbox_ResetText(hwnd); return;
|
||||
}
|
||||
|
||||
|
||||
AddressEditbox_CallOrigWindowProc(hwnd, WM_CHAR, (WPARAM)vKey, (LPARAM)state);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static BOOL AddressEditbox_RemoveBadChars(LPCWSTR pszText, LPWSTR *bufferOut)
|
||||
{
|
||||
LPWSTR buffer = NULL;
|
||||
if (NULL == pszText) return FALSE;
|
||||
|
||||
const WCHAR szBadChars[] = { L'\r', L'\n', L'\t', L'\0'};
|
||||
BOOL fDetected = FALSE;
|
||||
|
||||
for (LPCWSTR p = pszText; L'\0' != *p && FALSE == fDetected; p++)
|
||||
{
|
||||
for (LPCWSTR b = szBadChars; L'\0' != *b; b++)
|
||||
{
|
||||
if (*p == *b)
|
||||
{
|
||||
fDetected = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == fDetected)
|
||||
return FALSE;
|
||||
|
||||
if (NULL == bufferOut)
|
||||
return TRUE;
|
||||
|
||||
INT cchText = lstrlen(pszText);
|
||||
buffer = LoginBox_MallocString(cchText + 1);
|
||||
if (NULL == buffer) return FALSE;
|
||||
|
||||
LPCWSTR s = pszText;
|
||||
LPWSTR d = buffer;
|
||||
LPCWSTR b;
|
||||
for(;;)
|
||||
{
|
||||
for (b = szBadChars; L'\0' != *b && *s != *b; b++);
|
||||
if(L'\0' != *b)
|
||||
{
|
||||
if (L'\t' == *b)
|
||||
{
|
||||
*d = L' ';
|
||||
d++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
*d = *s;
|
||||
d++;
|
||||
}
|
||||
|
||||
if (L'\0' == *s)
|
||||
break;
|
||||
|
||||
s++;
|
||||
|
||||
}
|
||||
|
||||
*bufferOut = buffer;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static LRESULT AddressEditbox_OnSetText(HWND hwnd, LPCWSTR pszText)
|
||||
{
|
||||
LPWSTR buffer;
|
||||
if (FALSE == AddressEditbox_RemoveBadChars(pszText, &buffer))
|
||||
buffer = NULL;
|
||||
else
|
||||
pszText = buffer;
|
||||
|
||||
LRESULT result = AddressEditbox_CallOrigWindowProc(hwnd, WM_SETTEXT, 0, (LPARAM)pszText);
|
||||
|
||||
ADDRESSEDITBOX *editbox = GetEditbox(hwnd);
|
||||
if (NULL != editbox)
|
||||
{
|
||||
LoginBox_FreeString(editbox->rollbackText);
|
||||
editbox->rollbackText = LoginBox_CopyString(pszText);
|
||||
AddressEditbox_SelectReplacementBlock(hwnd, pszText);
|
||||
}
|
||||
|
||||
if (NULL != buffer)
|
||||
LoginBox_FreeString(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LRESULT AddressEditbox_OnReplaceSel(HWND hwnd, BOOL fUndo, LPCWSTR pszText)
|
||||
{
|
||||
LPWSTR buffer;
|
||||
if (FALSE == AddressEditbox_RemoveBadChars(pszText, &buffer))
|
||||
buffer = NULL;
|
||||
else
|
||||
pszText = buffer;
|
||||
|
||||
LRESULT result = AddressEditbox_CallOrigWindowProc(hwnd, EM_REPLACESEL, (WPARAM)fUndo, (LPARAM)pszText);
|
||||
|
||||
if (NULL != buffer)
|
||||
LoginBox_FreeString(buffer);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void AddressEditbox_ReplaceText(HWND hwnd, LPCWSTR pszText, BOOL fUndo, BOOL fScrollCaret)
|
||||
{
|
||||
UINT windowStyle = GetWindowStyle(hwnd);
|
||||
if (0 != (WS_VISIBLE & windowStyle))
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
|
||||
|
||||
SendMessage(hwnd, EM_REPLACESEL, (WPARAM)fUndo, (LPARAM)pszText);
|
||||
if (FALSE != fScrollCaret)
|
||||
{
|
||||
INT f, l;
|
||||
SendMessage(hwnd, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
|
||||
SendMessage(hwnd, EM_SETSEL, (WPARAM)f, (LPARAM)l);
|
||||
}
|
||||
|
||||
if (0 != (WS_VISIBLE & windowStyle))
|
||||
{
|
||||
windowStyle = GetWindowStyle(hwnd);
|
||||
if (0 == (WS_VISIBLE & windowStyle))
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddressEditbox_OnPaste(HWND hwnd)
|
||||
{
|
||||
IDataObject *pObject;
|
||||
HRESULT hr = OleGetClipboard(&pObject);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
FORMATETC fmt = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
STGMEDIUM stgm;
|
||||
hr = pObject->GetData(&fmt, &stgm);
|
||||
if(S_OK == hr)
|
||||
{
|
||||
LPCWSTR pClipboard = (LPCWSTR)GlobalLock(stgm.hGlobal);
|
||||
AddressEditbox_ReplaceText(hwnd, pClipboard, TRUE, TRUE);
|
||||
GlobalUnlock(stgm.hGlobal);
|
||||
ReleaseStgMedium(&stgm);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.cfFormat = CF_TEXT;
|
||||
hr = pObject->GetData(&fmt, &stgm);
|
||||
if(S_OK == hr)
|
||||
{
|
||||
LPCSTR pClipboardAnsi = (LPCSTR)GlobalLock(stgm.hGlobal);
|
||||
LPWSTR pClipboard;
|
||||
if (FAILED(LoginBox_MultiByteToWideChar(CP_ACP, 0, pClipboardAnsi, -1, &pClipboard)))
|
||||
pClipboard = NULL;
|
||||
|
||||
AddressEditbox_ReplaceText(hwnd, pClipboard, TRUE, TRUE);
|
||||
LoginBox_FreeString(pClipboard);
|
||||
GlobalUnlock(stgm.hGlobal);
|
||||
ReleaseStgMedium(&stgm);
|
||||
}
|
||||
}
|
||||
pObject->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT AddressEditbox_OnFindWordBreak(HWND hwnd, INT code, INT start)
|
||||
{
|
||||
EDITWORDBREAKPROC fnBreak = (EDITWORDBREAKPROC)SendMessage(hwnd, EM_GETWORDBREAKPROC, 0, 0L);
|
||||
if (NULL == fnBreak) return 0;
|
||||
|
||||
UINT cchText = GetWindowTextLength(hwnd);
|
||||
if (0 == cchText) return 0;
|
||||
|
||||
LPWSTR pszText = LoginBox_MallocString(cchText + 1);
|
||||
if (NULL == pszText) return 0;
|
||||
|
||||
LRESULT result = 0;
|
||||
cchText = GetWindowText(hwnd, pszText, cchText + 1);
|
||||
if (0 != cchText)
|
||||
{
|
||||
result = fnBreak(pszText, start, cchText, code);
|
||||
}
|
||||
LoginBox_FreeString(pszText);
|
||||
return result;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK AddressEditbox_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_DESTROY: AddressEditbox_OnDestroy(hwnd); return 0;
|
||||
case WM_GETDLGCODE: return AddressEditbox_OnGetDlgCode(hwnd, (INT)wParam, (MSG*)lParam);
|
||||
case WM_LBUTTONDOWN: AddressEditbox_OnLButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
|
||||
case WM_LBUTTONDBLCLK: AddressEditbox_OnLButtonDblClk(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
|
||||
case WM_KEYDOWN: AddressEditbox_OnKeyDown(hwnd, (UINT)wParam, (UINT)lParam); return 0;
|
||||
case WM_CHAR: AddressEditbox_OnChar(hwnd, (UINT)wParam, (UINT)lParam); return 0;
|
||||
case WM_SETTEXT: return AddressEditbox_OnSetText(hwnd, (LPCWSTR)lParam);
|
||||
case WM_PASTE: AddressEditbox_OnPaste(hwnd); return 1;
|
||||
case EM_REPLACESEL: AddressEditbox_OnReplaceSel(hwnd, (BOOL)wParam, (LPCWSTR)lParam); return 0;
|
||||
case EM_FINDWORDBREAK: return AddressEditbox_OnFindWordBreak(hwnd, (INT)wParam, (INT)lParam);
|
||||
}
|
||||
|
||||
return AddressEditbox_CallOrigWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
15
Src/auth/Loginbox/addressEditbox.h
Normal file
15
Src/auth/Loginbox/addressEditbox.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_ADDRESS_EDITBOX_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_ADDRESS_EDITBOX_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#define REPLACE_MARKER_BEGIN L'<'
|
||||
#define REPLACE_MARKER_END L'>'
|
||||
|
||||
BOOL AddressEditbox_AttachWindow(HWND hEditbox);
|
||||
|
||||
#endif // NULLSOFT_AUTH_LOGINBOX_ADDRESS_EDITBOX_HEADER
|
||||
514
Src/auth/Loginbox/addressEncoder.cpp
Normal file
514
Src/auth/Loginbox/addressEncoder.cpp
Normal file
@@ -0,0 +1,514 @@
|
||||
#include "./addressEncoder.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <wininet.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
|
||||
typedef struct __ENCODEBUFFER
|
||||
{
|
||||
LPWSTR buffer;
|
||||
size_t bufferMax;
|
||||
LPWSTR cursor;
|
||||
size_t remaining;
|
||||
} ENCODEBUFFER;
|
||||
|
||||
HRESULT AddressEncoder_ReAllocBuffer(ENCODEBUFFER *decoder, size_t cchBufferSize)
|
||||
{
|
||||
if (NULL == decoder)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (cchBufferSize == decoder->bufferMax)
|
||||
return S_FALSE;
|
||||
|
||||
if (cchBufferSize < decoder->bufferMax)
|
||||
return E_FAIL;
|
||||
|
||||
LPWSTR test = LoginBox_ReAllocString(decoder->buffer, cchBufferSize);
|
||||
if (NULL == test)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
decoder->cursor = test + (decoder->cursor - decoder->buffer);
|
||||
decoder->remaining += (cchBufferSize - decoder->bufferMax);
|
||||
decoder->buffer = test;
|
||||
decoder->bufferMax = cchBufferSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT AddressEncoder_AppendAnsiString(ENCODEBUFFER *decoder, LPCSTR pszString, size_t cchString)
|
||||
{
|
||||
if (NULL == decoder)
|
||||
return E_INVALIDARG;
|
||||
|
||||
INT cchConverted;
|
||||
while(0 ==(cchConverted = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, pszString, (INT)cchString, decoder->cursor, (INT)decoder->remaining)))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if (ERROR_INSUFFICIENT_BUFFER == errorCode)
|
||||
{
|
||||
INT cchNeed = MultiByteToWideChar(CP_UTF8, 0, pszString, (INT)cchString, NULL, 0) - (INT)decoder->remaining;
|
||||
if (cchNeed < 32) cchNeed = 32;
|
||||
HRESULT hr = AddressEncoder_ReAllocBuffer(decoder, decoder->bufferMax + cchNeed);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != cchConverted)
|
||||
{
|
||||
decoder->cursor += cchConverted;
|
||||
decoder->remaining -= cchConverted;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT AddressEncoder_AppendString(ENCODEBUFFER *decoder, LPCWSTR pszString, size_t cchString)
|
||||
{
|
||||
if (NULL == decoder)
|
||||
return E_INVALIDARG;
|
||||
|
||||
LPWSTR cursor;
|
||||
size_t remaining;
|
||||
|
||||
HRESULT hr;
|
||||
if (cchString >= decoder->remaining)
|
||||
{
|
||||
hr = AddressEncoder_ReAllocBuffer(decoder, decoder->bufferMax + (cchString - decoder->remaining) + 1);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
|
||||
hr = StringCchCopyNEx(decoder->cursor, decoder->remaining, pszString, cchString, &cursor, &remaining, 0);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
decoder->cursor = cursor;
|
||||
decoder->remaining = remaining;
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AddressEncoder_GetEscapeBlock(LPCWSTR pszEscape, LPCWSTR *ppszEnd, size_t *pcchEscapeLen, LPSTR pszBuffer, UINT *pcbBufferMax)
|
||||
{
|
||||
if (NULL == pszEscape || (NULL != pszBuffer && NULL == pcbBufferMax))
|
||||
return E_INVALIDARG;
|
||||
|
||||
UINT cbBinary = 0;
|
||||
WORD charInfo;
|
||||
WCHAR szDigit[3] = {0};
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
LPCWSTR cursor = pszEscape;
|
||||
while (L'%' == *cursor)
|
||||
{
|
||||
LPCWSTR testChar = CharNext(cursor);
|
||||
if (L'\0' == *testChar ||
|
||||
FALSE == GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, testChar, 1, &charInfo) ||
|
||||
0 == (C1_XDIGIT & charInfo))
|
||||
{
|
||||
break;
|
||||
}
|
||||
szDigit[0] = *testChar;
|
||||
|
||||
testChar = CharNext(testChar);
|
||||
if (L'\0' == *testChar ||
|
||||
FALSE == GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, testChar, 1, &charInfo) ||
|
||||
0 == (C1_XDIGIT & charInfo))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
szDigit[1] = *testChar;
|
||||
CharUpperBuff(szDigit, 2);
|
||||
|
||||
BYTE binaryData = ((szDigit[0] - ((szDigit[0] <= L'9' ? L'0' : L'A' - 10))) << 4) & 0xf0;
|
||||
binaryData += (szDigit[1] - ((szDigit[1] <= L'9' ? L'0' : L'A' - 10))) & 0x0f;
|
||||
if (NULL != pszBuffer)
|
||||
{
|
||||
if (cbBinary < *pcbBufferMax)
|
||||
pszBuffer[cbBinary] = binaryData;
|
||||
else
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
cbBinary++;
|
||||
|
||||
cursor = CharNext(testChar);
|
||||
}
|
||||
|
||||
if (cursor == pszEscape)
|
||||
hr = HRESULT_FROM_WIN32(ERROR_INVALID_BLOCK_LENGTH);
|
||||
|
||||
if (NULL != ppszEnd)
|
||||
*ppszEnd = cursor;
|
||||
|
||||
if (NULL != pcchEscapeLen)
|
||||
*pcchEscapeLen = (size_t)(cursor - pszEscape);
|
||||
|
||||
if (NULL != pcbBufferMax)
|
||||
*pcbBufferMax = cbBinary;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AddressEncoder_DecodeString(LPCWSTR pszUrl, LPWSTR *ppResult)
|
||||
{
|
||||
if (NULL == pszUrl)
|
||||
{
|
||||
*ppResult = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
UINT cchUrl = 0;
|
||||
UINT escapeSize = 0;
|
||||
UINT escapeBlockSize,escapeBlockMaxSize = 0;
|
||||
LPCWSTR escapeBlockEnd;
|
||||
for (LPCWSTR cursor = pszUrl; L'\0' != *cursor;)
|
||||
{
|
||||
if (L'%' == *cursor && SUCCEEDED(AddressEncoder_GetEscapeBlock(cursor, &escapeBlockEnd, NULL, NULL, &escapeBlockSize)))
|
||||
{
|
||||
escapeSize += escapeBlockSize;
|
||||
if (escapeBlockSize > escapeBlockMaxSize)
|
||||
escapeBlockMaxSize = escapeBlockSize;
|
||||
|
||||
cursor = escapeBlockEnd;
|
||||
}
|
||||
else
|
||||
{
|
||||
cchUrl++;
|
||||
cursor = CharNext(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == escapeSize)
|
||||
{
|
||||
*ppResult = LoginBox_CopyString(pszUrl);
|
||||
if (NULL == *ppResult) return E_OUTOFMEMORY;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ENCODEBUFFER decoder;
|
||||
ZeroMemory(&decoder, sizeof(decoder));
|
||||
|
||||
LPSTR escapeBuffer = LoginBox_MallocAnsiString(escapeBlockMaxSize);
|
||||
if (NULL == escapeBuffer)
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = AddressEncoder_ReAllocBuffer(&decoder, cchUrl + (escapeSize + 1)* sizeof(WCHAR));
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LPCWSTR cursor = pszUrl;
|
||||
LPCWSTR copyBlock = cursor;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
escapeBlockSize = escapeBlockMaxSize;
|
||||
if (L'%' == *cursor && SUCCEEDED(AddressEncoder_GetEscapeBlock(cursor, &escapeBlockEnd, NULL, escapeBuffer, &escapeBlockSize)))
|
||||
{
|
||||
if (copyBlock != cursor)
|
||||
{
|
||||
hr = AddressEncoder_AppendString(&decoder, copyBlock, cursor - copyBlock);
|
||||
if (FAILED(hr))
|
||||
break;
|
||||
copyBlock = cursor;
|
||||
}
|
||||
|
||||
HRESULT convertResult = AddressEncoder_AppendAnsiString(&decoder, escapeBuffer, escapeBlockSize);
|
||||
if (L'\0' == *cursor)
|
||||
break;
|
||||
|
||||
cursor = escapeBlockEnd;
|
||||
if (SUCCEEDED(convertResult))
|
||||
{
|
||||
copyBlock = cursor;
|
||||
}
|
||||
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (L'\0' == *cursor)
|
||||
{
|
||||
if (copyBlock != cursor)
|
||||
hr = AddressEncoder_AppendString(&decoder, copyBlock, cursor - copyBlock);
|
||||
break;
|
||||
}
|
||||
else
|
||||
cursor = CharNext(cursor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (NULL != escapeBuffer)
|
||||
LoginBox_FreeAnsiString(escapeBuffer);
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LoginBox_FreeString(decoder.buffer);
|
||||
decoder.buffer = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*decoder.cursor = L'\0';
|
||||
}
|
||||
|
||||
*ppResult = decoder.buffer;
|
||||
|
||||
return hr;
|
||||
}
|
||||
HRESULT AddressEncoder_GetWideBlock(LPCWSTR pszWide, LPCWSTR *pszEnd, LPWSTR pszBuffer, size_t *pcchBufferMax)
|
||||
{
|
||||
LPCWSTR cursor = pszWide;
|
||||
if (NULL == pszWide)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (NULL != pszBuffer && NULL == pcchBufferMax)
|
||||
return E_INVALIDARG;
|
||||
|
||||
while (L'\0' == *cursor || *cursor > 0xFF)
|
||||
{
|
||||
if (L'\0' == *cursor)
|
||||
break;
|
||||
cursor = CharNext(cursor);
|
||||
}
|
||||
|
||||
if (NULL != pszEnd)
|
||||
*pszEnd = cursor;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
size_t cchBuffer = 0;
|
||||
|
||||
if (cursor == pszWide)
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t bytesCount = WideCharToMultiByte(CP_UTF8, 0, pszWide, (INT)(INT_PTR)(cursor - pszWide), NULL, 0, NULL, NULL);
|
||||
if (0 == bytesCount)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if (ERROR_SUCCESS != errorCode)
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
cchBuffer = 3 * bytesCount;
|
||||
if (NULL != pszBuffer)
|
||||
{
|
||||
if (*pcchBufferMax >= cchBuffer)
|
||||
{
|
||||
LPWSTR p = pszBuffer;
|
||||
BYTE *bytes = ((BYTE*)(pszBuffer + *pcchBufferMax)) - bytesCount;
|
||||
WideCharToMultiByte(CP_UTF8, 0, pszWide, (INT)(INT_PTR)(cursor - pszWide), (LPSTR)bytes, (INT)bytesCount, NULL, NULL);
|
||||
for (size_t i = 0; i < bytesCount; i++)
|
||||
{
|
||||
BYTE b = bytes[i];
|
||||
*p++ = L'%';
|
||||
BYTE c = (b >> 4) & 0x0F;
|
||||
*p++ = (c < 10) ? (L'0' + c) : (L'A' + (c -10));
|
||||
c = b & 0x0F;
|
||||
*p++ = (c < 10) ? (L'0' + c) : (L'A' + (c -10));
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_OUTOFMEMORY;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pcchBufferMax)
|
||||
{
|
||||
*pcchBufferMax = cchBuffer;
|
||||
}
|
||||
|
||||
|
||||
return hr;
|
||||
}
|
||||
HRESULT AddressEncoder_EncodeWideChars(LPCWSTR pszAddress, size_t cchAddress, LPWSTR *ppResult)
|
||||
{
|
||||
if (NULL == ppResult)
|
||||
return E_POINTER;
|
||||
|
||||
if (NULL == pszAddress)
|
||||
{
|
||||
*ppResult = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
LPCWSTR blockEnd;
|
||||
size_t blockSize;
|
||||
size_t cchResultMax = 0;
|
||||
BOOL needEncode = FALSE;
|
||||
for (LPCWSTR cursor = pszAddress; L'\0' != *cursor;)
|
||||
{
|
||||
if (*cursor > 0xFF && SUCCEEDED(AddressEncoder_GetWideBlock(cursor, &blockEnd, NULL, &blockSize)))
|
||||
{
|
||||
cursor = blockEnd;
|
||||
cchResultMax += blockSize;
|
||||
needEncode = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
cursor = CharNext(cursor);
|
||||
cchResultMax++;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE == needEncode)
|
||||
{
|
||||
*ppResult = NULL;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
cchResultMax++;
|
||||
LPWSTR result = LoginBox_MallocString(cchResultMax);
|
||||
if (NULL == result)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
LPWSTR cursor = result;
|
||||
size_t remaining = cchResultMax;
|
||||
LPCWSTR address = pszAddress;
|
||||
LPCWSTR addressBlock = address;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (*address > 0xFF)
|
||||
{
|
||||
if (addressBlock != address)
|
||||
{
|
||||
hr = StringCchCopyNEx(cursor, remaining, addressBlock, (size_t)(address - addressBlock), &cursor, &remaining, 0);
|
||||
if (FAILED(hr)) break;
|
||||
}
|
||||
|
||||
blockSize = remaining;
|
||||
hr = AddressEncoder_GetWideBlock(address, &address, cursor, &blockSize);
|
||||
if (FAILED(hr)) break;
|
||||
|
||||
cursor += blockSize;
|
||||
remaining -= blockSize;
|
||||
|
||||
addressBlock = address;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (L'\0' == *address)
|
||||
{
|
||||
if (addressBlock != address)
|
||||
{
|
||||
hr = StringCchCopyNEx(cursor, remaining, addressBlock, (size_t)(address - addressBlock), &cursor, &remaining, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
address = CharNext(address);
|
||||
}
|
||||
|
||||
*cursor = L'\0';
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
LoginBox_FreeString(result);
|
||||
result = NULL;
|
||||
}
|
||||
|
||||
*ppResult = result;
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT AddressEncoder_EncodeString(LPCWSTR pszAddress, LPWSTR pszBuffer, size_t *pcchBufferMax, UINT flags)
|
||||
{
|
||||
if (NULL == pszBuffer || NULL == pcchBufferMax)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (NULL == pszAddress || L'\0' == *pszAddress)
|
||||
{
|
||||
*pszBuffer = L'\0';
|
||||
*pcchBufferMax = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
INT cchAddress = lstrlen(pszAddress);
|
||||
LPCWSTR begin, end;
|
||||
begin = pszAddress;
|
||||
end = pszAddress + cchAddress;
|
||||
WORD charType;
|
||||
while (L'\0' != *begin &&
|
||||
FALSE != GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, begin, 1, &charType) && 0 != (C1_SPACE & charType))
|
||||
{
|
||||
begin = CharNext(begin);
|
||||
}
|
||||
while (begin != end &&
|
||||
FALSE != GetStringTypeEx(LOCALE_USER_DEFAULT, CT_CTYPE1, begin, 1, &charType) && 0 != (C1_SPACE & charType))
|
||||
{
|
||||
end = CharPrev(begin, end);
|
||||
}
|
||||
|
||||
if (end <= begin)
|
||||
{
|
||||
*pszBuffer = L'\0';
|
||||
*pcchBufferMax = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LPWSTR encoded;
|
||||
HRESULT hr = AddressEncoder_EncodeWideChars(begin, (end - begin), &encoded);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (S_OK == hr)
|
||||
{
|
||||
begin = encoded;
|
||||
end = begin + lstrlen(begin);
|
||||
}
|
||||
|
||||
DWORD bufferLen = (DWORD)(*pcchBufferMax);
|
||||
if (FALSE == InternetCanonicalizeUrl(begin, pszBuffer, &bufferLen, flags))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
if (ERROR_INSUFFICIENT_BUFFER == errorCode)
|
||||
{
|
||||
*pcchBufferMax = bufferLen;
|
||||
hr = ENC_E_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t cchNeeded = (end - begin);
|
||||
if (cchNeeded < *pcchBufferMax)
|
||||
{
|
||||
hr = StringCchCopyN(pszBuffer, *pcchBufferMax, begin, cchNeeded);
|
||||
if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
|
||||
{
|
||||
hr = ENC_E_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = ENC_E_INSUFFICIENT_BUFFER;
|
||||
}
|
||||
*pcchBufferMax = cchNeeded + 1;
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
hr = S_OK;
|
||||
|
||||
|
||||
LoginBox_FreeString(encoded);
|
||||
return hr;
|
||||
}
|
||||
15
Src/auth/Loginbox/addressEncoder.h
Normal file
15
Src/auth/Loginbox/addressEncoder.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_ADDRESS_ENCODER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_ADDRESS_ENCODER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#define ENC_E_INSUFFICIENT_BUFFER (HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
|
||||
|
||||
HRESULT AddressEncoder_DecodeString(LPCWSTR pszAddress, LPWSTR *ppResult);
|
||||
HRESULT AddressEncoder_EncodeString(LPCWSTR pszAddress, LPWSTR pszBuffer, size_t *pcchBufferMax, UINT flags);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_ADDRESS_ENCODER_HEADER
|
||||
77
Src/auth/Loginbox/animation.cpp
Normal file
77
Src/auth/Loginbox/animation.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "./animation.h"
|
||||
#include "./common.h"
|
||||
|
||||
BOOL Animation_Initialize(ANIMATIONDATA *animation, UINT durationMs)
|
||||
{
|
||||
if (NULL == animation)
|
||||
return FALSE;
|
||||
|
||||
if (FALSE == QueryPerformanceFrequency(&animation->frequency))
|
||||
return FALSE;
|
||||
|
||||
QueryPerformanceCounter(&animation->completion);
|
||||
animation->completion.QuadPart += animation->frequency.QuadPart*durationMs/1000LL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Animation_BeginStep(ANIMATIONDATA *animation)
|
||||
{
|
||||
if (NULL == animation || FALSE == QueryPerformanceCounter(&animation->stepBegin))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Animation_EndStep(ANIMATIONDATA *animation, size_t stepsRemaining)
|
||||
{
|
||||
if (NULL == animation || FALSE == QueryPerformanceCounter(&animation->stepEnd))
|
||||
return FALSE;
|
||||
|
||||
if (0 == stepsRemaining || animation->stepEnd.QuadPart >= animation->completion.QuadPart)
|
||||
return TRUE;
|
||||
|
||||
LARGE_INTEGER sleep;
|
||||
sleep.QuadPart = (animation->completion.QuadPart - animation->stepEnd.QuadPart) -
|
||||
(stepsRemaining * (animation->stepEnd.QuadPart - animation->stepBegin.QuadPart));
|
||||
|
||||
if (stepsRemaining > 1)
|
||||
sleep.QuadPart /= (stepsRemaining -1);
|
||||
|
||||
if (sleep.QuadPart <= 0)
|
||||
return TRUE;
|
||||
|
||||
sleep.QuadPart += animation->stepEnd.QuadPart;
|
||||
do
|
||||
{
|
||||
SleepEx(0, FALSE);
|
||||
QueryPerformanceCounter(&animation->stepEnd);
|
||||
} while(sleep.QuadPart > animation->stepEnd.QuadPart);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Animation_SetWindowPos(HWND hwnd, INT x, INT y, INT cx, INT cy, UINT flags, HDC hdc, INT contextX, INT contextY)
|
||||
{
|
||||
if (NULL == hwnd ||
|
||||
FALSE == SetWindowPos(hwnd, NULL, x, y, cx, cy,
|
||||
flags | SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW | SWP_NOCOPYBITS))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
UINT windowStyle = GetWindowStyle(hwnd);
|
||||
|
||||
POINT origPoint;
|
||||
SetViewportOrgEx(hdc, contextX, contextY, &origPoint);
|
||||
if (0 == (WS_VISIBLE & windowStyle))
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle | WS_VISIBLE);
|
||||
|
||||
if (FALSE == LoginBox_PrintWindow(hwnd, hdc, 0))
|
||||
SendMessage(hwnd, WM_PRINT, (WPARAM)hdc, (LPARAM)(PRF_CLIENT | PRF_ERASEBKGND | PRF_CHILDREN | PRF_NONCLIENT));
|
||||
|
||||
if (0 == (WS_VISIBLE & windowStyle))
|
||||
SetWindowLongPtr(hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE);
|
||||
|
||||
SetViewportOrgEx(hdc, origPoint.x, origPoint.y, NULL);
|
||||
return TRUE;
|
||||
}
|
||||
23
Src/auth/Loginbox/animation.h
Normal file
23
Src/auth/Loginbox/animation.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_ANIMATION_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_ANIMATION_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
typedef struct __ANIMATIONDATA
|
||||
{
|
||||
LARGE_INTEGER frequency;
|
||||
LARGE_INTEGER completion;
|
||||
LARGE_INTEGER stepBegin;
|
||||
LARGE_INTEGER stepEnd;
|
||||
} ANIMATIONDATA;
|
||||
|
||||
BOOL Animation_Initialize(ANIMATIONDATA *animation, UINT durationMs);
|
||||
BOOL Animation_BeginStep(ANIMATIONDATA *animation);
|
||||
BOOL Animation_EndStep(ANIMATIONDATA *animation, size_t stepsRemaining);
|
||||
BOOL Animation_SetWindowPos(HWND hwnd, INT x, INT y, INT cx, INT cy, UINT flags, HDC hdc, INT contextX, INT contextY);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_ANIMATION_HEADER
|
||||
19
Src/auth/Loginbox/browserEvent.h
Normal file
19
Src/auth/Loginbox/browserEvent.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_BROWSER_EVENT_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_BROWSER_EVENT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class __declspec(novtable) BrowserEvent : public IUnknown
|
||||
{
|
||||
public:
|
||||
STDMETHOD_(void, Event_BrowserReady)(HWND hBrowser) = 0;
|
||||
STDMETHOD_(void, Event_DocumentReady)(HWND hBrowser) = 0;
|
||||
STDMETHOD_(void, Event_BrowserClosing)(HWND hBrowser) = 0;
|
||||
STDMETHOD_(void, Event_InvokeApc)(HWND hBrowser, LPARAM param) = 0;
|
||||
};
|
||||
|
||||
#endif // NULLSOFT_AUTH_LOGINBOX_BROWSER_EVENT_HEADER
|
||||
198
Src/auth/Loginbox/browserWindow.cpp
Normal file
198
Src/auth/Loginbox/browserWindow.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
#include "./browserWindow.h"
|
||||
#include "./browserEvent.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include "../../ombrowser/browserHost.h"
|
||||
|
||||
#define NBWF_USERFLAGSMASK 0x00FFFFFF
|
||||
#define NBWF_UNICODE 0x01000000
|
||||
|
||||
typedef struct __BROWSERWND
|
||||
{
|
||||
WNDPROC originalProc;
|
||||
UINT flags;
|
||||
BrowserEvent *eventHandler;
|
||||
} BROWSERWND;
|
||||
|
||||
#define BROWSERWND_PROP L"NullsoftLoginboxBrowserWindow"
|
||||
|
||||
#define GetBrowserWnd(__hwnd) ((BROWSERWND*)GetProp((__hwnd), BROWSERWND_PROP))
|
||||
|
||||
static UINT NBWM_QUEUEAPC = 0;
|
||||
|
||||
static LRESULT CALLBACK BrowserWindow_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
BOOL BrowserWindow_Attach(HWND hBrowser, BrowserEvent *eventHandler)
|
||||
{
|
||||
if (!IsWindow(hBrowser))
|
||||
return FALSE;
|
||||
|
||||
if (0 == NBWM_QUEUEAPC)
|
||||
NBWM_QUEUEAPC = RegisterWindowMessage(L"NullsoftBrowserExtMessage");
|
||||
|
||||
BROWSERWND *browserWnd = (BROWSERWND*)GetProp(hBrowser, BROWSERWND_PROP);
|
||||
if (NULL != browserWnd) return TRUE;
|
||||
|
||||
browserWnd = (BROWSERWND*)calloc(1, sizeof(BROWSERWND));
|
||||
if (NULL == browserWnd) return FALSE;
|
||||
|
||||
|
||||
ZeroMemory(browserWnd, sizeof(BROWSERWND));
|
||||
|
||||
if (IsWindowUnicode(hBrowser))
|
||||
browserWnd->flags |= NBWF_UNICODE;
|
||||
|
||||
browserWnd->originalProc = (WNDPROC)(LONG_PTR)((0 != (NBWF_UNICODE & browserWnd->flags)) ?
|
||||
SetWindowLongPtrW(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)BrowserWindow_WindowProc) :
|
||||
SetWindowLongPtrA(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)BrowserWindow_WindowProc));
|
||||
|
||||
if (NULL == browserWnd->originalProc || !SetProp(hBrowser, BROWSERWND_PROP, browserWnd))
|
||||
{
|
||||
if (NULL != browserWnd->originalProc)
|
||||
{
|
||||
if (0 != (NBWF_UNICODE & browserWnd->flags))
|
||||
SetWindowLongPtrW(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)browserWnd->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)browserWnd->originalProc);
|
||||
}
|
||||
|
||||
free(browserWnd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NULL != eventHandler)
|
||||
{
|
||||
browserWnd->eventHandler = eventHandler;
|
||||
eventHandler->AddRef();
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL BrowserWindow_Detach(HWND hBrowser)
|
||||
{
|
||||
if (NULL == hBrowser || FALSE == IsWindow(hBrowser))
|
||||
return FALSE;
|
||||
|
||||
BROWSERWND *browserWnd = GetBrowserWnd(hBrowser);
|
||||
RemoveProp(hBrowser, BROWSERWND_PROP);
|
||||
|
||||
if (NULL == browserWnd)
|
||||
return FALSE;
|
||||
|
||||
if (NULL != browserWnd->originalProc)
|
||||
{
|
||||
if (0 != (NBWF_UNICODE & browserWnd->flags))
|
||||
SetWindowLongPtrW(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)browserWnd->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hBrowser, GWLP_WNDPROC, (LONGX86)(LONG_PTR)browserWnd->originalProc);
|
||||
}
|
||||
|
||||
if (NULL != browserWnd->eventHandler)
|
||||
browserWnd->eventHandler->Release();
|
||||
|
||||
free(browserWnd);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL BrowserWindow_QueueApc(HWND hBrowser, LPARAM param)
|
||||
{
|
||||
if (0 == NBWM_QUEUEAPC ||
|
||||
NULL == hBrowser || FALSE == IsWindow(hBrowser))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return PostMessage(hBrowser, NBWM_QUEUEAPC, 0, (LPARAM)param);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT BrowserWindow_CallOrigWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
BROWSERWND *browserWnd = GetBrowserWnd(hwnd);
|
||||
|
||||
if (NULL == browserWnd || NULL == browserWnd->originalProc)
|
||||
{
|
||||
return (0 != (NBWF_UNICODE & browserWnd->flags)) ?
|
||||
DefWindowProcW(hwnd, uMsg, wParam, lParam) :
|
||||
DefWindowProcA(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
return (0 != (NBWF_UNICODE & browserWnd->flags)) ?
|
||||
CallWindowProcW(browserWnd->originalProc, hwnd, uMsg, wParam, lParam) :
|
||||
CallWindowProcA(browserWnd->originalProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void BrowserWindow_OnDestroy(HWND hwnd)
|
||||
{
|
||||
BROWSERWND *browserWnd = GetBrowserWnd(hwnd);
|
||||
|
||||
WNDPROC originalProc = browserWnd->originalProc;
|
||||
BOOL fUnicode = (0 != (NBWF_UNICODE & browserWnd->flags));
|
||||
|
||||
BrowserWindow_Detach(hwnd);
|
||||
|
||||
if (NULL != originalProc)
|
||||
{
|
||||
if (FALSE != fUnicode)
|
||||
CallWindowProcW(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
else
|
||||
CallWindowProcA(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
static void BrowserWindow_OnQueueApc(HWND hwnd, LPARAM param)
|
||||
{
|
||||
BROWSERWND *browserWnd = GetBrowserWnd(hwnd);
|
||||
if (NULL != browserWnd && NULL != browserWnd->eventHandler)
|
||||
browserWnd->eventHandler->Event_InvokeApc(hwnd, param);
|
||||
}
|
||||
|
||||
static void BrowserWindow_OnBrowserNotify(HWND hwnd, NMHDR *pnmh)
|
||||
{
|
||||
BROWSERWND *browserWnd = GetBrowserWnd(hwnd);
|
||||
if (NULL == browserWnd || NULL == browserWnd->eventHandler)
|
||||
return;
|
||||
|
||||
switch(pnmh->code)
|
||||
{
|
||||
case NBHN_READY:
|
||||
browserWnd->eventHandler->Event_BrowserReady(hwnd);
|
||||
break;
|
||||
case NBHN_DOCUMENTREADY:
|
||||
browserWnd->eventHandler->Event_DocumentReady(hwnd);
|
||||
break;
|
||||
case NBHN_CLOSING:
|
||||
browserWnd->eventHandler->Event_BrowserClosing(hwnd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT BrowserWindow_OnNotify(HWND hwnd, INT controlId, NMHDR *pnmh)
|
||||
{
|
||||
LRESULT result = BrowserWindow_CallOrigWindowProc(hwnd, WM_NOTIFY, (WPARAM)controlId, (LPARAM)pnmh);
|
||||
switch(controlId)
|
||||
{
|
||||
case 0x1000/*IDC_BROWSER*/:
|
||||
BrowserWindow_OnBrowserNotify(hwnd, pnmh);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK BrowserWindow_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_DESTROY: BrowserWindow_OnDestroy(hwnd); return 0;
|
||||
case WM_NOTIFY: return BrowserWindow_OnNotify(hwnd, (INT)wParam, (NMHDR*)lParam);
|
||||
}
|
||||
|
||||
if (NULL != NBWM_QUEUEAPC && NBWM_QUEUEAPC == uMsg)
|
||||
{
|
||||
BrowserWindow_OnQueueApc(hwnd, lParam);
|
||||
return 0;
|
||||
}
|
||||
return BrowserWindow_CallOrigWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
16
Src/auth/Loginbox/browserWindow.h
Normal file
16
Src/auth/Loginbox/browserWindow.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_BROWSER_WINDOW_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_BROWSER_WINDOW_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class BrowserEvent;
|
||||
|
||||
BOOL BrowserWindow_Attach(HWND hBrowser, BrowserEvent *eventHandler);
|
||||
BOOL BrowserWindow_Detach(HWND hBrowser);
|
||||
BOOL BrowserWindow_QueueApc(HWND hBrowser, LPARAM param);
|
||||
|
||||
#endif // NULLSOFT_AUTH_LOGINBOX_BROWSER_WINDOW_HEADER
|
||||
82
Src/auth/Loginbox/commandNodeParser.cpp
Normal file
82
Src/auth/Loginbox/commandNodeParser.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "./commandNodeParser.h"
|
||||
#include "./loginCommand.h"
|
||||
#include "./loginProvider.h"
|
||||
|
||||
#include "../../xml/obj_xml.h"
|
||||
|
||||
LoginCommandNodeParser::LoginCommandNodeParser()
|
||||
: reader(NULL), provider(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoginCommandNodeParser::~LoginCommandNodeParser()
|
||||
{
|
||||
End();
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginCommandNodeParser::Begin(obj_xml *pReader, LoginProvider *pProvider)
|
||||
{
|
||||
if (NULL != reader || NULL != provider)
|
||||
return E_PENDING;
|
||||
|
||||
if (NULL == pReader || NULL == pProvider)
|
||||
return E_INVALIDARG;
|
||||
|
||||
reader = pReader;
|
||||
reader->AddRef();
|
||||
|
||||
provider = pProvider;
|
||||
provider->AddRef();
|
||||
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fcommand", this);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandNodeParser::End()
|
||||
{
|
||||
if (NULL != reader)
|
||||
{
|
||||
reader->xmlreader_unregisterCallback(this);
|
||||
reader->Release();
|
||||
reader = NULL;
|
||||
}
|
||||
|
||||
if (NULL != provider)
|
||||
{
|
||||
provider->Release();
|
||||
provider = NULL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void LoginCommandNodeParser::Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
|
||||
{
|
||||
elementParser.Begin(reader, params);
|
||||
}
|
||||
|
||||
void LoginCommandNodeParser::Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag)
|
||||
{
|
||||
LoginCommand *result;
|
||||
if (SUCCEEDED(elementParser.End(reader, &result)))
|
||||
{
|
||||
if (NULL != provider)
|
||||
provider->SetCommand(result);
|
||||
|
||||
result->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void LoginCommandNodeParser::Event_XmlError(int linenum, int errcode, const wchar_t *errstr)
|
||||
{
|
||||
}
|
||||
|
||||
#define CBCLASS LoginCommandNodeParser
|
||||
START_DISPATCH;
|
||||
VCB(ONSTARTELEMENT, Event_XmlStartElement)
|
||||
VCB(ONENDELEMENT, Event_XmlEndElement)
|
||||
VCB(ONERROR, Event_XmlError)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
41
Src/auth/Loginbox/commandNodeParser.h
Normal file
41
Src/auth/Loginbox/commandNodeParser.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_COMMAND_NODE_PARSER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_COMMAND_NODE_PARSER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../xml/ifc_xmlreadercallback.h"
|
||||
#include "./commandParser.h"
|
||||
|
||||
class obj_xml;
|
||||
class LoginCommand;
|
||||
class LoginProvider;
|
||||
|
||||
class LoginCommandNodeParser : public ifc_xmlreadercallback
|
||||
{
|
||||
|
||||
public:
|
||||
LoginCommandNodeParser();
|
||||
~LoginCommandNodeParser();
|
||||
|
||||
public:
|
||||
HRESULT Begin(obj_xml *reader, LoginProvider *provider);
|
||||
HRESULT End();
|
||||
|
||||
protected:
|
||||
void Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
|
||||
void Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag);
|
||||
void Event_XmlError(int linenum, int errcode, const wchar_t *errstr);
|
||||
|
||||
protected:
|
||||
obj_xml *reader;
|
||||
LoginCommandParser elementParser;
|
||||
LoginProvider *provider;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_COMMAND_NODE_PARSER_HEADER
|
||||
108
Src/auth/Loginbox/commandParser.cpp
Normal file
108
Src/auth/Loginbox/commandParser.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "./commandParser.h"
|
||||
#include "./loginCommand.h"
|
||||
#include "./commandWinampAuth.h"
|
||||
#include "./commandWebAuth.h"
|
||||
|
||||
#include "./common.h"
|
||||
|
||||
#include "../../xml/obj_xml.h"
|
||||
|
||||
|
||||
LoginCommandParser::LoginCommandParser()
|
||||
: object(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoginCommandParser::~LoginCommandParser()
|
||||
{
|
||||
if (NULL != object)
|
||||
object->Release();
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginCommandParser::Begin(obj_xml *reader, ifc_xmlreaderparams *params)
|
||||
{
|
||||
if (NULL != object)
|
||||
return E_PENDING;
|
||||
|
||||
if (NULL == reader || NULL == params)
|
||||
return E_INVALIDARG;
|
||||
|
||||
GUID commandId;
|
||||
LPCWSTR pszId = params->getItemValue(L"id");
|
||||
if (NULL == pszId || RPC_S_OK != UuidFromString((RPC_WSTR)pszId, &commandId))
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
if (IsEqualGUID(LCUID_WINAMPAUTH, commandId))
|
||||
hr = LoginCommandWinampAuth::CreateInstance((LoginCommandWinampAuth**)&object);
|
||||
else if (IsEqualGUID(LCUID_WEBAUTH, commandId))
|
||||
hr = LoginCommandWebAuth::CreateInstance((LoginCommandWebAuth**)&object);
|
||||
else
|
||||
hr = E_INVALIDARG;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fcommand\f*", this);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandParser::End(obj_xml *reader, LoginCommand **instance)
|
||||
{
|
||||
if (NULL == object)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (SUCCEEDED(object->IsValid()))
|
||||
{
|
||||
if (NULL != instance)
|
||||
{
|
||||
*instance = object;
|
||||
object->AddRef();
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
else
|
||||
hr = E_FAIL;
|
||||
|
||||
object->Release();
|
||||
object = NULL;
|
||||
|
||||
if (NULL != reader)
|
||||
reader->xmlreader_unregisterCallback(this);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
void LoginCommandParser::Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
|
||||
{
|
||||
elementString.Clear();
|
||||
}
|
||||
|
||||
void LoginCommandParser::Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag)
|
||||
{
|
||||
if (NULL != object)
|
||||
object->SetParameter(xmltag, elementString.Get());
|
||||
}
|
||||
|
||||
void LoginCommandParser::Event_XmlCharData(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *value)
|
||||
{
|
||||
elementString.Append(value);
|
||||
}
|
||||
|
||||
void LoginCommandParser::Event_XmlError(int linenum, int errcode, const wchar_t *errstr)
|
||||
{
|
||||
elementString.Clear();
|
||||
}
|
||||
|
||||
#define CBCLASS LoginCommandParser
|
||||
START_DISPATCH;
|
||||
VCB(ONSTARTELEMENT, Event_XmlStartElement)
|
||||
VCB(ONENDELEMENT, Event_XmlEndElement)
|
||||
VCB(ONCHARDATA, Event_XmlCharData)
|
||||
VCB(ONERROR, Event_XmlError)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
40
Src/auth/Loginbox/commandParser.h
Normal file
40
Src/auth/Loginbox/commandParser.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_COMMAND_PARSER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_COMMAND_PARSER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../xml/ifc_xmlreadercallback.h"
|
||||
#include "./stringBuilder.h"
|
||||
|
||||
class obj_xml;
|
||||
class LoginCommand;
|
||||
|
||||
class LoginCommandParser : public ifc_xmlreadercallback
|
||||
{
|
||||
|
||||
public:
|
||||
LoginCommandParser();
|
||||
~LoginCommandParser();
|
||||
|
||||
public:
|
||||
HRESULT Begin(obj_xml *reader, ifc_xmlreaderparams *params);
|
||||
HRESULT End(obj_xml *reader, LoginCommand **instance);
|
||||
|
||||
protected:
|
||||
void Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
|
||||
void Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag);
|
||||
void Event_XmlCharData(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *value);
|
||||
void Event_XmlError(int linenum, int errcode, const wchar_t *errstr);
|
||||
|
||||
protected:
|
||||
LoginCommand *object;
|
||||
StringBuilder elementString;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_COMMAND_PARSER_HEADER
|
||||
159
Src/auth/Loginbox/commandWebAuth.cpp
Normal file
159
Src/auth/Loginbox/commandWebAuth.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "./commandWebAuth.h"
|
||||
#include "./resultWebAuth.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include "../api.h"
|
||||
|
||||
#include "../../omBrowser/obj_ombrowser.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
LoginCommandWebAuth::LoginCommandWebAuth()
|
||||
: ref(1), targetUrl(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LoginCommandWebAuth::~LoginCommandWebAuth()
|
||||
{
|
||||
LoginBox_FreeString(targetUrl);
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::CreateInstance(LoginCommandWebAuth **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = new LoginCommandWebAuth();
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginCommandWebAuth::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginCommandWebAuth::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::GetType(GUID *commandUid)
|
||||
{
|
||||
if (NULL == commandUid) return E_INVALIDARG;
|
||||
*commandUid = LCUID_WEBAUTH;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::SetParameter(LPCWSTR pszKey, LPCWSTR pszValue)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszKey, -1, L"url", -1))
|
||||
{
|
||||
LoginBox_FreeString(targetUrl);
|
||||
targetUrl = LoginBox_CopyString(pszValue);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::IsValid()
|
||||
{
|
||||
if (NULL == targetUrl || L'\0' == *targetUrl)
|
||||
return S_FALSE;
|
||||
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(OBJ_OmBrowser);
|
||||
if (NULL != sf)
|
||||
{
|
||||
obj_ombrowser *browserMngr = (obj_ombrowser*)sf->getInterface();
|
||||
if (NULL != browserMngr)
|
||||
{
|
||||
hr = S_OK;
|
||||
browserMngr->Release();
|
||||
}
|
||||
sf->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::IsIdentical(LoginCommand *test)
|
||||
{
|
||||
if (NULL == test)
|
||||
return E_INVALIDARG;
|
||||
|
||||
GUID typeId;
|
||||
if (FAILED(test->GetType(&typeId)) || FALSE == IsEqualGUID(LCUID_WEBAUTH, typeId))
|
||||
return S_FALSE;
|
||||
|
||||
LoginCommandWebAuth *testWeb = (LoginCommandWebAuth*)test;
|
||||
|
||||
if(S_OK != LoginBox_IsStrEqInvI(targetUrl, testWeb->targetUrl))
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::BeginLogin(LoginData *data, LoginResult::Callback callback, void *user, LoginResult **result)
|
||||
{
|
||||
HRESULT hr;
|
||||
LoginResultWebAuth *webAuth;
|
||||
|
||||
hr = LoginResultWebAuth::CreateInstance(targetUrl, data, callback, user, &webAuth);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (NULL != result)
|
||||
*result = webAuth;
|
||||
else
|
||||
webAuth->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != result)
|
||||
*result = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::EndLogin(LoginResult *result, INT *authCode, LoginCredentials **credentials)
|
||||
{
|
||||
if (NULL == result)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr = result->IsCompleted();
|
||||
if (S_OK != hr)
|
||||
{
|
||||
HANDLE completed;
|
||||
hr = result->GetWaitHandle(&completed);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WaitForSingleObjectEx(completed, INFINITE, TRUE);
|
||||
CloseHandle(completed);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LoginResultWebAuth *webAuth;
|
||||
hr = result->QueryInterface(LCUID_WEBAUTH, (void**)&webAuth);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = webAuth->GetResult(authCode, credentials);
|
||||
webAuth->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWebAuth::RequestAbort(LoginResult *result, BOOL drop)
|
||||
{
|
||||
if (NULL == result) return E_INVALIDARG;
|
||||
return result->RequestAbort(drop);
|
||||
}
|
||||
42
Src/auth/Loginbox/commandWebAuth.h
Normal file
42
Src/auth/Loginbox/commandWebAuth.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINCOMMAND_WEBAUTH_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINCOMMAND_WEBAUTH_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginCommand.h"
|
||||
|
||||
// {48F006E2-EC11-4171-833B-A9CD14F6D727}
|
||||
static const GUID LCUID_WEBAUTH =
|
||||
{ 0x48f006e2, 0xec11, 0x4171, { 0x83, 0x3b, 0xa9, 0xcd, 0x14, 0xf6, 0xd7, 0x27 } };
|
||||
|
||||
class LoginCommandWebAuth : public LoginCommand
|
||||
{
|
||||
protected:
|
||||
LoginCommandWebAuth();
|
||||
~LoginCommandWebAuth();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(LoginCommandWebAuth **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
HRESULT GetType(GUID *commandUid);
|
||||
|
||||
HRESULT SetParameter(LPCWSTR pszKey, LPCWSTR pszValue);
|
||||
HRESULT IsValid();
|
||||
HRESULT IsIdentical(LoginCommand *test);
|
||||
|
||||
HRESULT BeginLogin(LoginData *data, LoginResult::Callback callback, void *user, LoginResult **result);
|
||||
HRESULT EndLogin(LoginResult *result, INT *authCode, LoginCredentials **credentials);
|
||||
HRESULT RequestAbort(LoginResult *result, BOOL drop);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
LPWSTR targetUrl;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINCOMMAND_WEBAUTH_HEADER
|
||||
125
Src/auth/Loginbox/commandWinampAuth.cpp
Normal file
125
Src/auth/Loginbox/commandWinampAuth.cpp
Normal file
@@ -0,0 +1,125 @@
|
||||
#include "./commandWinampAuth.h"
|
||||
#include "./resultWinampAuth.h"
|
||||
|
||||
|
||||
LoginCommandWinampAuth::LoginCommandWinampAuth()
|
||||
: ref(1)
|
||||
{
|
||||
}
|
||||
|
||||
LoginCommandWinampAuth::~LoginCommandWinampAuth()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::CreateInstance(LoginCommandWinampAuth **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = new LoginCommandWinampAuth();
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginCommandWinampAuth::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginCommandWinampAuth::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::GetType(GUID *commandUid)
|
||||
{
|
||||
if (NULL == commandUid) return E_INVALIDARG;
|
||||
*commandUid = LCUID_WINAMPAUTH;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::SetParameter(LPCWSTR pszKey, LPCWSTR pszValue)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::IsValid()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::IsIdentical(LoginCommand *test)
|
||||
{
|
||||
if (NULL == test)
|
||||
return E_INVALIDARG;
|
||||
|
||||
GUID typeId;
|
||||
if (FAILED(test->GetType(&typeId)) || FALSE == IsEqualGUID(LCUID_WINAMPAUTH, typeId))
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginCommandWinampAuth::BeginLogin(LoginData *data, LoginResult::Callback callback, void *user, LoginResult **result)
|
||||
{
|
||||
LoginResultWinampAuth *winampAuth;
|
||||
HRESULT hr = LoginResultWinampAuth::CreateInstance(data, callback, user, &winampAuth);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (NULL != result)
|
||||
*result = winampAuth;
|
||||
else
|
||||
winampAuth->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != result)
|
||||
*result = NULL;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::EndLogin(LoginResult *result, INT *authCode, LoginCredentials **credentials)
|
||||
{
|
||||
if (NULL == result)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr = result->IsCompleted();
|
||||
if (S_OK != hr)
|
||||
{
|
||||
HANDLE completed;
|
||||
hr = result->GetWaitHandle(&completed);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
WaitForSingleObjectEx(completed, INFINITE, TRUE);
|
||||
CloseHandle(completed);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LoginResultWinampAuth *winampAuth;
|
||||
hr = result->QueryInterface(LCUID_WINAMPAUTH, (void**)&winampAuth);
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
hr = winampAuth->GetResult(authCode, credentials);
|
||||
winampAuth->Release();
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginCommandWinampAuth::RequestAbort(LoginResult *result, BOOL drop)
|
||||
{
|
||||
if (NULL == result) return E_INVALIDARG;
|
||||
return result->RequestAbort(drop);
|
||||
}
|
||||
44
Src/auth/Loginbox/commandWinampAuth.h
Normal file
44
Src/auth/Loginbox/commandWinampAuth.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINCOMMAND_WINAMPAUTH_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINCOMMAND_WINAMPAUTH_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginCommand.h"
|
||||
|
||||
// {36B883C8-5400-4d43-89EA-96B1CBEFC605}
|
||||
static const GUID LCUID_WINAMPAUTH =
|
||||
{ 0x36b883c8, 0x5400, 0x4d43, { 0x89, 0xea, 0x96, 0xb1, 0xcb, 0xef, 0xc6, 0x5 } };
|
||||
|
||||
|
||||
class LoginCommandWinampAuth : public LoginCommand
|
||||
{
|
||||
protected:
|
||||
LoginCommandWinampAuth();
|
||||
~LoginCommandWinampAuth();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(LoginCommandWinampAuth **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
HRESULT GetType(GUID *commandUid);
|
||||
|
||||
HRESULT SetParameter(LPCWSTR pszKey, LPCWSTR pszValue);
|
||||
HRESULT IsValid();
|
||||
HRESULT IsIdentical(LoginCommand *test);
|
||||
|
||||
|
||||
HRESULT BeginLogin(LoginData *data, LoginResult::Callback callback, void *user, LoginResult **result);
|
||||
HRESULT EndLogin(LoginResult *result, INT *authCode, LoginCredentials **credentials);
|
||||
HRESULT RequestAbort(LoginResult *result, BOOL drop);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINCOMMAND_WINAMPAUTH_HEADER
|
||||
618
Src/auth/Loginbox/common.cpp
Normal file
618
Src/auth/Loginbox/common.cpp
Normal file
@@ -0,0 +1,618 @@
|
||||
#include "./common.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include "../../winamp/accessibilityConfigGroup.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
|
||||
LPWSTR LoginBox_MallocString(size_t cchLen)
|
||||
{
|
||||
return (LPWSTR)calloc(cchLen, sizeof(WCHAR));
|
||||
}
|
||||
|
||||
void LoginBox_FreeString(LPWSTR pszString)
|
||||
{
|
||||
if (NULL != pszString)
|
||||
{
|
||||
free(pszString);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginBox_FreeStringSecure(LPWSTR pszString)
|
||||
{
|
||||
if (NULL != pszString)
|
||||
{
|
||||
size_t size = LoginBox_GetAllocSize(pszString);
|
||||
if (0 != size)
|
||||
SecureZeroMemory(pszString, size);
|
||||
|
||||
free(pszString);
|
||||
}
|
||||
}
|
||||
|
||||
LPWSTR LoginBox_ReAllocString(LPWSTR pszString, size_t cchLen)
|
||||
{
|
||||
return (LPWSTR)realloc(pszString, sizeof(WCHAR) * cchLen);
|
||||
}
|
||||
|
||||
LPWSTR LoginBox_CopyString(LPCWSTR pszSource)
|
||||
{
|
||||
if (NULL == pszSource)
|
||||
return NULL;
|
||||
|
||||
INT cchSource = lstrlenW(pszSource) + 1;
|
||||
|
||||
LPWSTR copy = LoginBox_MallocString(cchSource);
|
||||
if (NULL != copy)
|
||||
{
|
||||
CopyMemory(copy, pszSource, sizeof(WCHAR) * cchSource);
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
|
||||
LPSTR LoginBox_MallocAnsiString(size_t cchLen)
|
||||
{
|
||||
return (LPSTR)calloc(cchLen, sizeof(CHAR));
|
||||
}
|
||||
|
||||
LPSTR LoginBox_CopyAnsiString(LPCSTR pszSource)
|
||||
{
|
||||
if (NULL == pszSource)
|
||||
return NULL;
|
||||
|
||||
INT cchSource = lstrlenA(pszSource) + 1;
|
||||
|
||||
LPSTR copy = LoginBox_MallocAnsiString(cchSource);
|
||||
if (NULL != copy)
|
||||
{
|
||||
CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
|
||||
}
|
||||
return copy;
|
||||
|
||||
}
|
||||
void LoginBox_FreeAnsiString(LPSTR pszString)
|
||||
{
|
||||
LoginBox_FreeString((LPWSTR)pszString);
|
||||
}
|
||||
|
||||
void LoginBox_FreeAnsiStringSecure(LPSTR pszString)
|
||||
{
|
||||
LoginBox_FreeStringSecure((LPWSTR)pszString);
|
||||
}
|
||||
|
||||
size_t LoginBox_GetAllocSize(void *memory)
|
||||
{
|
||||
return (NULL != memory) ? _msize(memory) : 0;
|
||||
}
|
||||
|
||||
size_t LoginBox_GetStringMax(LPWSTR pszString)
|
||||
{
|
||||
return LoginBox_GetAllocSize(pszString)/sizeof(WCHAR);
|
||||
}
|
||||
|
||||
size_t LoginBox_GetAnsiStringMax(LPSTR pszString)
|
||||
{
|
||||
return LoginBox_GetAllocSize(pszString)/sizeof(CHAR);
|
||||
}
|
||||
|
||||
HRESULT LoginBox_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar, LPSTR *ppResult)
|
||||
{
|
||||
if (NULL == ppResult)
|
||||
return E_POINTER;
|
||||
|
||||
INT resultMax = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar);
|
||||
if (0 == resultMax)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
*ppResult = NULL;
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
if (cchWideChar > 0)
|
||||
resultMax++;
|
||||
|
||||
|
||||
*ppResult = LoginBox_MallocAnsiString(resultMax);
|
||||
if (NULL == *ppResult) return E_OUTOFMEMORY;
|
||||
resultMax = WideCharToMultiByte(codePage, dwFlags, lpWideCharStr, cchWideChar, *ppResult, resultMax, lpDefaultChar, lpUsedDefaultChar);
|
||||
if (0 == resultMax)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
LoginBox_FreeAnsiString(*ppResult);
|
||||
*ppResult = NULL;
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
if (cchWideChar > 0)
|
||||
(*ppResult)[resultMax] = '\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginBox_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte, LPWSTR *ppResult)
|
||||
{
|
||||
if (NULL == ppResult)
|
||||
return E_POINTER;
|
||||
|
||||
INT resultMax = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0);
|
||||
if (0 == resultMax)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
*ppResult = NULL;
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
if (cbMultiByte > 0)
|
||||
resultMax++;
|
||||
|
||||
*ppResult = LoginBox_MallocString(resultMax);
|
||||
if (NULL == *ppResult) return E_OUTOFMEMORY;
|
||||
resultMax = MultiByteToWideChar(codePage, dwFlags, lpMultiByteStr, cbMultiByte, *ppResult, resultMax);
|
||||
if (0 == resultMax)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
LoginBox_FreeString(*ppResult);
|
||||
*ppResult = NULL;
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
if (cbMultiByte > 0)
|
||||
(*ppResult)[resultMax] = L'\0';
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginBox_GetConfigPath(LPWSTR pszConfig, BOOL fEnsureExist)
|
||||
{
|
||||
if (NULL == pszConfig)
|
||||
return E_INVALIDARG;
|
||||
|
||||
LPCWSTR pszWinamp;
|
||||
pszWinamp = (NULL != WASABI_API_APP) ? WASABI_API_APP->path_getUserSettingsPath(): NULL;
|
||||
if (NULL == pszWinamp)
|
||||
return E_FAIL;
|
||||
|
||||
if (NULL == PathCombine(pszConfig, pszWinamp, L"Plugins\\loginBox"))
|
||||
return E_FAIL;
|
||||
|
||||
if (FALSE != fEnsureExist)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = LoginBox_EnsurePathExist(pszConfig);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginBox_EnsurePathExist(LPCWSTR pszDirectory)
|
||||
{
|
||||
DWORD ec = ERROR_SUCCESS;
|
||||
UINT errorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
|
||||
|
||||
if (0 == CreateDirectory(pszDirectory, NULL))
|
||||
{
|
||||
ec = GetLastError();
|
||||
if (ERROR_PATH_NOT_FOUND == ec)
|
||||
{
|
||||
LPCWSTR pszBlock = pszDirectory;
|
||||
WCHAR szBuffer[MAX_PATH] = {0};
|
||||
|
||||
LPCTSTR pszCursor = PathFindNextComponent(pszBlock);
|
||||
ec = (pszCursor == pszBlock || S_OK != StringCchCopyN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock))) ?
|
||||
ERROR_INVALID_NAME : ERROR_SUCCESS;
|
||||
|
||||
pszBlock = pszCursor;
|
||||
|
||||
while (ERROR_SUCCESS == ec && NULL != (pszCursor = PathFindNextComponent(pszBlock)))
|
||||
{
|
||||
if (pszCursor == pszBlock || S_OK != StringCchCatN(szBuffer, ARRAYSIZE(szBuffer), pszBlock, (pszCursor - pszBlock)))
|
||||
ec = ERROR_INVALID_NAME;
|
||||
|
||||
if (ERROR_SUCCESS == ec && !CreateDirectory(szBuffer, NULL))
|
||||
{
|
||||
ec = GetLastError();
|
||||
if (ERROR_ALREADY_EXISTS == ec) ec = ERROR_SUCCESS;
|
||||
}
|
||||
pszBlock = pszCursor;
|
||||
}
|
||||
}
|
||||
|
||||
if (ERROR_ALREADY_EXISTS == ec)
|
||||
ec = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
SetErrorMode(errorMode);
|
||||
SetLastError(ec);
|
||||
return HRESULT_FROM_WIN32(ec);
|
||||
}
|
||||
|
||||
HRESULT LoginBox_GetWindowText(HWND hwnd, LPWSTR *ppszText, UINT *pcchText)
|
||||
{
|
||||
if (NULL == ppszText) return E_POINTER;
|
||||
if (NULL == hwnd) return E_INVALIDARG;
|
||||
|
||||
UINT cchText = (UINT)SNDMSG(hwnd, WM_GETTEXTLENGTH, 0, 0L);
|
||||
|
||||
cchText++;
|
||||
*ppszText = LoginBox_MallocString(cchText);
|
||||
if (NULL == *ppszText)
|
||||
{
|
||||
if (NULL != pcchText) *pcchText = 0;
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
cchText = (UINT)SNDMSG(hwnd, WM_GETTEXT, (WPARAM)cchText, (LPARAM)*ppszText);
|
||||
if (NULL != pcchText)
|
||||
*pcchText = cchText;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BOOL LoginBox_PrintWindow(HWND hwnd, HDC hdc, UINT flags)
|
||||
{
|
||||
typedef BOOL (WINAPI *PRINTWINDOW)(HWND /*hwnd*/, HDC /*hdc*/, UINT /*nFlags*/);
|
||||
static PRINTWINDOW printWindow = NULL;
|
||||
static HMODULE moduleUser32 = NULL;
|
||||
if (NULL == moduleUser32)
|
||||
{
|
||||
moduleUser32 = GetModuleHandle(L"USER32");
|
||||
if (NULL == moduleUser32) return FALSE;
|
||||
|
||||
printWindow = (PRINTWINDOW)GetProcAddress(moduleUser32, "PrintWindow");
|
||||
}
|
||||
|
||||
return (NULL != printWindow && FALSE != printWindow(hwnd, hdc, flags));
|
||||
|
||||
}
|
||||
|
||||
|
||||
BOOL LoginBox_MessageBeep(UINT beepType)
|
||||
{
|
||||
BOOL result = FALSE;
|
||||
ifc_configitem *beepEnabled = AGAVE_API_CONFIG->GetItem(accessibilityConfigGroupGUID, L"modalbeep");
|
||||
if (NULL != beepEnabled)
|
||||
{
|
||||
if (false != beepEnabled->GetBool())
|
||||
{
|
||||
result = MessageBeep(beepType);
|
||||
}
|
||||
beepEnabled->Release();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT LoginBox_IsStringEqualEx(LCID locale, BOOL ignoreCase, LPCWSTR str1, LPCWSTR str2)
|
||||
{
|
||||
if ((NULL == str1) != (NULL == str2))
|
||||
return S_FALSE;
|
||||
|
||||
if (NULL != str1 && CSTR_EQUAL != CompareString(locale, (FALSE != ignoreCase) ? NORM_IGNORECASE : 0, str1, -1, str2, -1))
|
||||
return S_FALSE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
UINT LoginBox_GetCurrentTime()
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
FILETIME ft;
|
||||
|
||||
GetSystemTime(&st);
|
||||
if(FALSE == SystemTimeToFileTime(&st, &ft))
|
||||
return 0;
|
||||
|
||||
ULARGE_INTEGER t1;
|
||||
t1.LowPart = ft.dwLowDateTime;
|
||||
t1.HighPart = ft.dwHighDateTime;
|
||||
|
||||
return (UINT)((t1.QuadPart - 116444736000000000) / 10000000);
|
||||
}
|
||||
|
||||
HRESULT LoginBox_GetCurrentLang(LPSTR *ppLang)
|
||||
{
|
||||
if (NULL == ppLang)
|
||||
return E_POINTER;
|
||||
|
||||
if (NULL == WASABI_API_LNG)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
LPCWSTR lang = WASABI_API_LNG->GetLanguageIdentifier(LANG_LANG_CODE);
|
||||
|
||||
if (NULL != lang && L'\0' != *lang)
|
||||
return LoginBox_WideCharToMultiByte(CP_UTF8, 0, lang, -1, NULL, NULL, ppLang);
|
||||
|
||||
*ppLang = NULL;
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
HDWP LoginBox_LayoutButtonBar(HDWP hdwp, HWND hwnd, const INT *buttonList, UINT buttonCount, const RECT *prcClient, LONG buttonHeight, LONG buttonSpace, BOOL fRedraw, RECT *prcResult)
|
||||
{
|
||||
if (NULL == hdwp && NULL == prcClient)
|
||||
return NULL;
|
||||
|
||||
RECT rect;
|
||||
CopyRect(&rect, prcClient);
|
||||
|
||||
LONG top = rect.bottom - buttonHeight;
|
||||
if (top < rect.top) top = rect.top;
|
||||
LONG height = rect.bottom - top;
|
||||
LONG width;
|
||||
LONG right = rect.right;
|
||||
|
||||
if (NULL == buttonList || 0 == buttonCount)
|
||||
{
|
||||
if (NULL != prcResult)
|
||||
SetRect(prcResult, right, top, rect.right, top + height);
|
||||
|
||||
return (NULL != hdwp) ? hdwp :(HDWP)TRUE;
|
||||
}
|
||||
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
WCHAR szText[256] = {0};
|
||||
INT cchText;
|
||||
HFONT font(NULL), fontOrig;
|
||||
SIZE textSize;
|
||||
|
||||
RECT buttonRect;
|
||||
while(buttonCount--)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, buttonList[buttonCount]);
|
||||
if (NULL == hControl || 0 == (WS_VISIBLE & GetWindowStyle(hControl)) ||
|
||||
FALSE == GetWindowRect(hControl, &buttonRect))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (right != rect.right)
|
||||
right -= buttonSpace;
|
||||
|
||||
width = buttonRect.right - buttonRect.left;
|
||||
|
||||
cchText = (INT)SendMessage(hControl, WM_GETTEXT, (WPARAM)ARRAYSIZE(szText), (LPARAM)szText);
|
||||
if (cchText > 0)
|
||||
{
|
||||
HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
if (NULL == font)
|
||||
font = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L);
|
||||
|
||||
fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
if (FALSE != GetTextExtentPoint32W(hdc, szText, cchText, &textSize))
|
||||
{
|
||||
width = textSize.cx + 4*LoginBox_GetAveCharWidth(hdc);
|
||||
}
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hControl, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
if (width < 75)
|
||||
width = 75;
|
||||
|
||||
if (NULL != hdwp)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, right - width, top, width, height, flags);
|
||||
if (NULL == hdwp) return NULL;
|
||||
}
|
||||
|
||||
right -= width;
|
||||
}
|
||||
|
||||
if (NULL != prcResult)
|
||||
SetRect(prcResult, right, top, rect.right, top + height);
|
||||
|
||||
return (NULL != hdwp) ? hdwp :(HDWP)TRUE;
|
||||
}
|
||||
|
||||
BYTE LoginBox_GetSysFontQuality()
|
||||
{
|
||||
BOOL smoothingEnabled;
|
||||
if (FALSE == SystemParametersInfo(SPI_GETFONTSMOOTHING, 0, &smoothingEnabled, 0) ||
|
||||
FALSE == smoothingEnabled)
|
||||
{
|
||||
return DEFAULT_QUALITY;
|
||||
}
|
||||
|
||||
OSVERSIONINFO vi;
|
||||
vi.dwOSVersionInfoSize = sizeof(vi);
|
||||
if (FALSE == GetVersionEx(&vi))
|
||||
return DEFAULT_QUALITY;
|
||||
|
||||
if (vi.dwMajorVersion > 5 || (vi.dwMajorVersion == 5 && vi.dwMinorVersion >= 1))
|
||||
{
|
||||
UINT smootingType;
|
||||
if (FALSE == SystemParametersInfo(SPI_GETFONTSMOOTHINGTYPE, 0, &smootingType, 0))
|
||||
return DEFAULT_QUALITY;
|
||||
|
||||
if (FE_FONTSMOOTHINGCLEARTYPE == smootingType)
|
||||
return CLEARTYPE_QUALITY;
|
||||
}
|
||||
|
||||
return ANTIALIASED_QUALITY;
|
||||
}
|
||||
|
||||
INT LoginBox_GetAveStrWidth(HDC hdc, INT cchLen)
|
||||
{
|
||||
const char szTest[] =
|
||||
{
|
||||
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z',
|
||||
'a','b','c','d','e','f','g','h','i','j','k','l', 'm','n','o','p','q','r','s','t','u','v','w','x','y','z'
|
||||
};
|
||||
|
||||
SIZE textSize;
|
||||
if (FALSE == GetTextExtentPointA(hdc, szTest, ARRAYSIZE(szTest) -1, &textSize))
|
||||
return 0;
|
||||
|
||||
INT result;
|
||||
if (1 == cchLen)
|
||||
{
|
||||
result = (textSize.cx + ARRAYSIZE(szTest)/2)/ARRAYSIZE(szTest);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = MulDiv(cchLen, textSize.cx + ARRAYSIZE(szTest)/2, ARRAYSIZE(szTest));
|
||||
if (0 != result)
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE != GetTextMetrics(hdc, &tm))
|
||||
result += tm.tmOverhang;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
INT LoginBox_GetAveCharWidth(HDC hdc)
|
||||
{
|
||||
return LoginBox_GetAveStrWidth(hdc, 1);
|
||||
}
|
||||
|
||||
BOOL LoginBox_GetWindowBaseUnits(HWND hwnd, INT *pBaseUnitX, INT *pBaseUnitY)
|
||||
{
|
||||
INT baseunitX(0), baseunitY(0);
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (NULL != hwnd)
|
||||
{
|
||||
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT font = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE != GetTextMetrics(hdc, &tm))
|
||||
{
|
||||
baseunitY = tm.tmHeight;
|
||||
baseunitX = LoginBox_GetAveCharWidth(hdc);
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pBaseUnitX) *pBaseUnitX = baseunitX;
|
||||
if (NULL != pBaseUnitY) *pBaseUnitY = baseunitY;
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
INT LoginBox_GetWindowTextHeight(HWND hwnd, INT paddingDlgUnit)
|
||||
{
|
||||
if (NULL == hwnd) return 0;
|
||||
|
||||
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL == hdc) return 0;
|
||||
|
||||
INT height = 0;
|
||||
|
||||
HFONT font = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE != GetTextMetrics(hdc, &tm))
|
||||
{
|
||||
height = tm.tmHeight;
|
||||
if (0 != paddingDlgUnit)
|
||||
height += MulDiv(2 * paddingDlgUnit, tm.tmHeight, 8);
|
||||
}
|
||||
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
|
||||
return height;
|
||||
|
||||
}
|
||||
BOOL LoginBox_GetWindowTextSize(HWND hwnd, INT idealWidth, INT *pWidth, INT *pHeight)
|
||||
{
|
||||
INT width(0), height(0);
|
||||
BOOL result = FALSE;
|
||||
|
||||
if (NULL != hwnd)
|
||||
{
|
||||
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT font = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
LPWSTR pszText;
|
||||
UINT cchText;
|
||||
if (SUCCEEDED(LoginBox_GetWindowText(hwnd, &pszText, &cchText)))
|
||||
{
|
||||
if (0 == cchText)
|
||||
{
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE != GetTextMetrics(hdc, &tm))
|
||||
{
|
||||
height = tm.tmHeight;
|
||||
width = 0;
|
||||
result = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RECT rect;
|
||||
SetRect(&rect, 0, 0, idealWidth, 0);
|
||||
if (0 != DrawText(hdc, pszText, cchText, &rect, DT_CALCRECT | DT_NOPREFIX | DT_WORDBREAK))
|
||||
{
|
||||
width = rect.right - rect.left;
|
||||
height = rect.bottom - rect.top;
|
||||
result = TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
LoginBox_FreeString(pszText);
|
||||
}
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != pWidth) *pWidth = width;
|
||||
if (NULL != pHeight) *pHeight = height;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL LoginBox_OpenUrl(HWND hOwner, LPCWSTR pszUrl, BOOL forceExternal)
|
||||
{
|
||||
if (NULL == WASABI_API_WINAMP)
|
||||
return FALSE;
|
||||
|
||||
HCURSOR hCursor = LoadCursor(NULL, IDC_APPSTARTING);
|
||||
if (NULL != hCursor)
|
||||
hCursor = SetCursor(hCursor);
|
||||
|
||||
BOOL result;
|
||||
|
||||
if (FALSE != forceExternal)
|
||||
{
|
||||
HINSTANCE hInst = ShellExecute(hOwner, L"open", pszUrl, NULL, NULL, SW_SHOWNORMAL);
|
||||
result = ((INT_PTR)hInst > 32) ? TRUE: FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
HRESULT hr = WASABI_API_WINAMP->OpenUrl(hOwner, pszUrl);
|
||||
result = SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
if (NULL != hCursor)
|
||||
SetCursor(hCursor);
|
||||
|
||||
return result;
|
||||
}
|
||||
96
Src/auth/Loginbox/common.h
Normal file
96
Src/auth/Loginbox/common.h
Normal file
@@ -0,0 +1,96 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_COMMON_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_COMMON_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#ifndef ARRAYSIZE
|
||||
#define ARRAYSIZE(blah) (sizeof(blah)/sizeof(*blah))
|
||||
#endif
|
||||
|
||||
#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
|
||||
|
||||
#ifndef LONGX86
|
||||
#ifdef _WIN64
|
||||
#define LONGX86 LONG_PTR
|
||||
#else /*_WIN64*/
|
||||
#define LONGX86 LONG
|
||||
#endif /*_WIN64*/
|
||||
#endif // LONGX86
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) ::SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
|
||||
#else
|
||||
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
|
||||
#endif // __cplusplus
|
||||
|
||||
#define MSGRESULT(__hwnd, __result) { SetWindowLongPtrW((__hwnd), DWLP_MSGRESULT, ((LONGX86)(LONG_PTR)(__result))); return TRUE; }
|
||||
|
||||
#ifndef GetWindowStyle
|
||||
#define GetWindowStyle(__hwnd) ((UINT)GetWindowLongPtr((__hwnd), GWL_STYLE))
|
||||
#endif //GetWindowStyle
|
||||
|
||||
#ifndef GetWindowStyleEx
|
||||
#define GetWindowStyleEx(__hwnd) ((UINT)GetWindowLongPtr((__hwnd), GWL_EXSTYLE))
|
||||
#endif //GetWindowStyleEx
|
||||
|
||||
|
||||
LPWSTR LoginBox_MallocString(size_t cchLen);
|
||||
void LoginBox_FreeString(LPWSTR pszString);
|
||||
void LoginBox_FreeStringSecure(LPWSTR pszString);
|
||||
|
||||
LPWSTR LoginBox_ReAllocString(LPWSTR pszString, size_t cchLen);
|
||||
LPWSTR LoginBox_CopyString(LPCWSTR pszSource);
|
||||
LPSTR LoginBox_MallocAnsiString(size_t cchLen);
|
||||
LPSTR LoginBox_CopyAnsiString(LPCSTR pszSource);
|
||||
void LoginBox_FreeAnsiString(LPSTR pszString);
|
||||
void LoginBox_FreeAnsiStringSecure(LPSTR pszString);
|
||||
size_t LoginBox_GetAllocSize(void *memory);
|
||||
size_t LoginBox_GetStringMax(LPWSTR pszString);
|
||||
size_t LoginBox_GetAnsiStringMax(LPSTR pszString);
|
||||
|
||||
HRESULT LoginBox_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar, LPSTR *ppResult);
|
||||
HRESULT LoginBox_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte, LPWSTR *ppResult);
|
||||
|
||||
HRESULT LoginBox_GetWindowText(HWND hwnd, LPWSTR *ppszText, UINT *pcchText);
|
||||
|
||||
HRESULT LoginBox_GetConfigPath(LPWSTR pszConfig, BOOL fEnsureExist);
|
||||
HRESULT LoginBox_EnsurePathExist(LPCWSTR pszDirectory);
|
||||
|
||||
BOOL LoginBox_PrintWindow(HWND hwnd, HDC hdc, UINT flags);
|
||||
|
||||
BOOL LoginBox_MessageBeep(UINT beepType);
|
||||
|
||||
HRESULT LoginBox_IsStringEqualEx(LCID locale, BOOL ignoreCase, LPCWSTR str1, LPCWSTR str2);
|
||||
|
||||
#define LoginBox_IsStrEq(str1, str2)\
|
||||
LoginBox_IsStringEqualEx(LOCALE_USER_DEFAULT, FALSE, str1, str2)
|
||||
|
||||
#define LoginBox_IsStrEqI(str1, str2)\
|
||||
LoginBox_IsStringEqualEx(LOCALE_USER_DEFAULT, TRUE, str1, str2)
|
||||
|
||||
#define LoginBox_IsStrEqInv(str1, str2)\
|
||||
LoginBox_IsStringEqualEx(CSTR_INVARIANT, FALSE, str1, str2)
|
||||
|
||||
#define LoginBox_IsStrEqInvI(str1, str2)\
|
||||
LoginBox_IsStringEqualEx(CSTR_INVARIANT, TRUE, str1, str2)
|
||||
|
||||
UINT LoginBox_GetCurrentTime();
|
||||
HRESULT LoginBox_GetCurrentLang(LPSTR *ppLang);
|
||||
|
||||
HDWP LoginBox_LayoutButtonBar(HDWP hdwp, HWND hwnd, const INT *buttonList, UINT buttonCount, const RECT *prcClient, LONG buttonHeight, LONG buttonSpace, BOOL fRedraw, RECT *prcResult);
|
||||
|
||||
BYTE LoginBox_GetSysFontQuality();
|
||||
INT LoginBox_GetAveStrWidth(HDC hdc, INT cchLen);
|
||||
INT LoginBox_GetAveCharWidth(HDC hdc);
|
||||
BOOL LoginBox_GetWindowBaseUnits(HWND hwnd, INT *pBaseUnitX, INT *pBaseUnitY);
|
||||
INT LoginBox_GetWindowTextHeight(HWND hwnd, INT paddingDlgUnit);
|
||||
BOOL LoginBox_GetWindowTextSize(HWND hwnd, INT idealWidth, INT *pWidth, INT *pHeight);
|
||||
|
||||
BOOL LoginBox_OpenUrl(HWND hOwner, LPCWSTR pszUrl, BOOL forceExternal);
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_COMMON_HEADER
|
||||
46
Src/auth/Loginbox/dataAddress.cpp
Normal file
46
Src/auth/Loginbox/dataAddress.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
#include "./dataAddress.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
LoginDataAddress::LoginDataAddress(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszAddress)
|
||||
: LoginData(pRealm, hPage, hLoginbox), address(NULL)
|
||||
{
|
||||
address = LoginBox_CopyString(pszAddress);
|
||||
}
|
||||
|
||||
LoginDataAddress::~LoginDataAddress()
|
||||
{
|
||||
LoginBox_FreeString(address);
|
||||
}
|
||||
|
||||
HRESULT LoginDataAddress::CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszAddress, LoginDataAddress **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hPage || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginDataAddress(pRealm, hPage, hLoginbox, pszAddress);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginDataAddress::QueryInterface(REFIID riid, void** ppObject)
|
||||
{
|
||||
if (NULL == ppObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IID_LoginDataAddress))
|
||||
{
|
||||
*ppObject = static_cast<LoginDataAddress*>(this);
|
||||
if (NULL == *ppObject) return E_UNEXPECTED;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return __super::QueryInterface(riid, ppObject);
|
||||
}
|
||||
|
||||
LPCWSTR LoginDataAddress::GetAddress()
|
||||
{
|
||||
return address;
|
||||
}
|
||||
34
Src/auth/Loginbox/dataAddress.h
Normal file
34
Src/auth/Loginbox/dataAddress.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINDATA_ADDRESS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINDATA_ADDRESS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginData.h"
|
||||
|
||||
// {830B9FCD-3A09-4485-8BA6-1A6B8F10ED39}
|
||||
static const GUID IID_LoginDataAddress =
|
||||
{ 0x830b9fcd, 0x3a09, 0x4485, { 0x8b, 0xa6, 0x1a, 0x6b, 0x8f, 0x10, 0xed, 0x39 } };
|
||||
|
||||
|
||||
class LoginDataAddress : public LoginData
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginDataAddress(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszAddress);
|
||||
~LoginDataAddress();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszAddress, LoginDataAddress **instance);
|
||||
|
||||
public:
|
||||
virtual HRESULT QueryInterface(REFIID riid, void** ppObject);
|
||||
LPCWSTR GetAddress();
|
||||
|
||||
|
||||
protected:
|
||||
LPWSTR address;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINDATA_ADDRESS_HEADER
|
||||
98
Src/auth/Loginbox/dataCredentials.cpp
Normal file
98
Src/auth/Loginbox/dataCredentials.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "./dataCredentials.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
LoginDataCredentials::LoginDataCredentials(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszUsername, LPCWSTR pszPassword)
|
||||
: LoginData(pRealm, hPage, hLoginbox), username(NULL), password(NULL), context(NULL), passcode(NULL)
|
||||
{
|
||||
username = LoginBox_CopyString(pszUsername);
|
||||
password = LoginBox_CopyString(pszPassword);
|
||||
}
|
||||
|
||||
LoginDataCredentials::~LoginDataCredentials()
|
||||
{
|
||||
LoginBox_FreeStringSecure(username);
|
||||
LoginBox_FreeStringSecure(password);
|
||||
LoginBox_FreeStringSecure(passcode);
|
||||
LoginBox_FreeAnsiStringSecure(context);
|
||||
}
|
||||
|
||||
HRESULT LoginDataCredentials::CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszUsername, LPCWSTR pszPassword, LoginDataCredentials **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hPage || NULL == hLoginbox) return E_INVALIDARG;
|
||||
*instance = new LoginDataCredentials(pRealm, hPage, hLoginbox, pszUsername, pszPassword);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginDataCredentials::QueryInterface(REFIID riid, void** ppObject)
|
||||
{
|
||||
if (NULL == ppObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IID_LoginDataCredentials))
|
||||
{
|
||||
*ppObject = static_cast<LoginDataCredentials*>(this);
|
||||
if (NULL == *ppObject) return E_UNEXPECTED;
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return __super::QueryInterface(riid, ppObject);
|
||||
}
|
||||
|
||||
LPCWSTR LoginDataCredentials::GetUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
|
||||
LPCWSTR LoginDataCredentials::GetPassword()
|
||||
{
|
||||
return password;
|
||||
}
|
||||
|
||||
HRESULT LoginDataCredentials::SetContext(LPCSTR pszContext)
|
||||
{
|
||||
LoginBox_FreeAnsiStringSecure(context);
|
||||
if (NULL == pszContext)
|
||||
{
|
||||
context = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
context = LoginBox_CopyAnsiString(pszContext);
|
||||
if (NULL == context)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LPCSTR LoginDataCredentials::GetContext()
|
||||
{
|
||||
return context;
|
||||
}
|
||||
|
||||
HRESULT LoginDataCredentials::SetPasscode(LPCWSTR pszPasscode)
|
||||
{
|
||||
LoginBox_FreeStringSecure(passcode);
|
||||
if (NULL == pszPasscode)
|
||||
{
|
||||
passcode = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
passcode = LoginBox_CopyString(pszPasscode);
|
||||
if (NULL == passcode)
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LPCWSTR LoginDataCredentials::GetPasscode()
|
||||
{
|
||||
return passcode;
|
||||
}
|
||||
43
Src/auth/Loginbox/dataCredentials.h
Normal file
43
Src/auth/Loginbox/dataCredentials.h
Normal file
@@ -0,0 +1,43 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINDATA_CREDENTIALS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINDATA_CREDENTIALS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginData.h"
|
||||
|
||||
// {15D82B0E-A557-4497-808D-CB68F2C9C33A}
|
||||
static const GUID IID_LoginDataCredentials =
|
||||
{ 0x15d82b0e, 0xa557, 0x4497, { 0x80, 0x8d, 0xcb, 0x68, 0xf2, 0xc9, 0xc3, 0x3a } };
|
||||
|
||||
|
||||
class LoginDataCredentials : public LoginData
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginDataCredentials(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszUsername, LPCWSTR pszPassword);
|
||||
~LoginDataCredentials();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LPCWSTR pszUsername, LPCWSTR pszPassword, LoginDataCredentials **instance);
|
||||
|
||||
public:
|
||||
virtual HRESULT QueryInterface(REFIID riid, void** ppObject);
|
||||
LPCWSTR GetUsername();
|
||||
LPCWSTR GetPassword();
|
||||
|
||||
HRESULT SetContext(LPCSTR pszContext);
|
||||
LPCSTR GetContext();
|
||||
|
||||
HRESULT SetPasscode(LPCWSTR pszPasscode);
|
||||
LPCWSTR GetPasscode();
|
||||
|
||||
protected:
|
||||
LPWSTR username;
|
||||
LPWSTR password;
|
||||
LPWSTR passcode;
|
||||
LPSTR context;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINDATA_CREDENTIALS_HEADER
|
||||
268
Src/auth/Loginbox/download.cpp
Normal file
268
Src/auth/Loginbox/download.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
#include "./common.h"
|
||||
#include "./download.h"
|
||||
#include "./downloadResult.h"
|
||||
#include "../api.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
#include "./providerLoader.h"
|
||||
#include "./providerEnumerator.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
LoginDownload::LoginDownload()
|
||||
{
|
||||
}
|
||||
|
||||
LoginDownload::~LoginDownload()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginDownload::Begin(LPCWSTR pszUrl, UINT type, LoginDownloadResult::Callback callback, void *data, LoginStatus *pStatus, LoginDownloadResult **result)
|
||||
{
|
||||
if (NULL == result) return E_POINTER;
|
||||
*result = NULL;
|
||||
|
||||
if (NULL == pszUrl || L'\0' == *pszUrl)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
LPSTR addressAnsi;
|
||||
hr = LoginBox_WideCharToMultiByte(CP_UTF8, 0, pszUrl, -1, NULL, NULL, &addressAnsi);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (NULL != WASABI_API_SVC)
|
||||
{
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(DownloadManagerGUID);
|
||||
api_downloadManager *manager = (NULL != sf) ? (api_downloadManager *)sf->getInterface() : NULL;
|
||||
if (NULL == manager)
|
||||
hr = E_UNEXPECTED;
|
||||
else
|
||||
{
|
||||
hr = LoginDownloadResult::CreateInstance(manager, type, callback, data, pStatus, result);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
if (0 == manager->DownloadEx(addressAnsi, *result, api_downloadManager::DOWNLOADEX_TEMPFILE))
|
||||
{
|
||||
(*result)->Release();
|
||||
*result = NULL;
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sf->releaseInterface(manager);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LoginBox_FreeAnsiString(addressAnsi);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownload::End(LoginDownloadResult *result, BSTR *bstrFileName)
|
||||
{
|
||||
if (NULL != bstrFileName)
|
||||
*bstrFileName = NULL;
|
||||
|
||||
if (NULL == result) return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
UINT state;
|
||||
if (FAILED(result->GetState(&state)) || LoginDownloadResult::stateCompleted != state)
|
||||
{
|
||||
HANDLE completed;
|
||||
hr = result->GetWaitHandle(&completed);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
while(WAIT_OBJECT_0 != WaitForSingleObjectEx(completed, INFINITE, TRUE));
|
||||
CloseHandle(completed);
|
||||
}
|
||||
|
||||
UINT type;
|
||||
hr = result->GetType(&type);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case LoginDownloadResult::typeProviderList:
|
||||
hr = SaveProviderList(result, bstrFileName);
|
||||
break;
|
||||
case LoginDownloadResult::typeImage:
|
||||
hr = SaveImage(result, bstrFileName);
|
||||
break;
|
||||
case LoginDownloadResult::typeUnknown:
|
||||
hr = E_NOTIMPL;
|
||||
break;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownload::SaveProviderList(LoginDownloadResult *result, BSTR *bstrFileName)
|
||||
{
|
||||
if (NULL == result)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
LPCWSTR pszSource;
|
||||
hr = result->GetFile(&pszSource);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
WCHAR szTarget[2048] = {0};
|
||||
hr = LoginBox_GetConfigPath(szTarget, TRUE);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (FALSE == PathAppend(szTarget, L"loginProviders.xml"))
|
||||
return E_FAIL;
|
||||
|
||||
if (S_OK == IsBinaryEqual(pszSource, szTarget))
|
||||
hr = S_FALSE;
|
||||
else
|
||||
{
|
||||
// validate source
|
||||
LoginProviderEnumerator *enumerator;
|
||||
LoginProviderLoader loader;
|
||||
if (FAILED(loader.ReadXml(pszSource, &enumerator, NULL)))
|
||||
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
||||
else
|
||||
{
|
||||
enumerator->Release();
|
||||
|
||||
if (FALSE == CopyFile(pszSource, szTarget, FALSE))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
else
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != bstrFileName)
|
||||
*bstrFileName = (SUCCEEDED(hr)) ? SysAllocString(szTarget) : NULL;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownload::SaveImage(LoginDownloadResult *result, BSTR *bstrFileName)
|
||||
{
|
||||
if (NULL == result)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
LPCWSTR pszSource;
|
||||
hr = result->GetFile(&pszSource);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
WCHAR szTarget[2048] = {0};
|
||||
hr = LoginBox_GetConfigPath(szTarget, TRUE);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
CHAR szFileAnsi[MAX_PATH] = {0}, szUrlAnsi[2096] = {0};
|
||||
hr = result->CreateDownloadFileName(szFileAnsi, ARRAYSIZE(szFileAnsi));
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = result->GetUrl(szUrlAnsi, ARRAYSIZE(szUrlAnsi));
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
LPWSTR pszFile;
|
||||
hr = LoginBox_MultiByteToWideChar(CP_UTF8, 0, szFileAnsi, -1, &pszFile);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (FALSE == PathAppend(szTarget, pszFile))
|
||||
hr = E_FAIL;
|
||||
else if (FALSE == CopyFile(pszSource, szTarget, FALSE))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
if (NULL != bstrFileName)
|
||||
*bstrFileName = SysAllocString(szTarget);
|
||||
|
||||
LoginBox_FreeString(pszFile);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownload::IsBinaryEqual(LPCWSTR pszFile1, LPCWSTR pszFile2)
|
||||
{
|
||||
HRESULT hr;
|
||||
HANDLE hFile1, hFile2;
|
||||
|
||||
hFile1 = CreateFile(pszFile1, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile1)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
else hr = S_OK;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hFile2 = CreateFile(pszFile2, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile2)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
}
|
||||
else
|
||||
hFile2 = INVALID_HANDLE_VALUE;
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// check sizes;
|
||||
LARGE_INTEGER size1, size2;
|
||||
if (FALSE == GetFileSizeEx(hFile1, &size1) || FALSE == GetFileSizeEx(hFile2, &size2))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (size1.QuadPart == size2.QuadPart)
|
||||
{
|
||||
// compare data
|
||||
BYTE szBuffer1[4096] = {0}, szBuffer2[4096] = {0};
|
||||
for(;;)
|
||||
{
|
||||
DWORD read1 = 0, read2 = 0;
|
||||
if (FALSE == ReadFile(hFile1, szBuffer1, ARRAYSIZE(szBuffer1), &read1, NULL) ||
|
||||
FALSE == ReadFile(hFile2, szBuffer2, ARRAYSIZE(szBuffer2), &read2, NULL))
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if (0 == read1 || 0 == read2)
|
||||
{
|
||||
hr = (read1 == read2) ? S_OK : S_FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if(read1 != read2 || 0 != memcmp(szBuffer1, szBuffer2, read1))
|
||||
{
|
||||
hr = S_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
hr = S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (INVALID_HANDLE_VALUE != hFile1)
|
||||
CloseHandle(hFile1);
|
||||
|
||||
if (INVALID_HANDLE_VALUE != hFile2)
|
||||
CloseHandle(hFile2);
|
||||
|
||||
return hr;
|
||||
}
|
||||
30
Src/auth/Loginbox/download.h
Normal file
30
Src/auth/Loginbox/download.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_DOWNLOAD_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_DOWNLOAD_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "./downloadResult.h"
|
||||
|
||||
|
||||
|
||||
class LoginDownload
|
||||
{
|
||||
|
||||
public:
|
||||
LoginDownload();
|
||||
~LoginDownload();
|
||||
|
||||
public:
|
||||
HRESULT Begin(LPCWSTR pszUrl, UINT type, LoginDownloadResult::Callback callback, void *data, LoginStatus *status, LoginDownloadResult **result);
|
||||
HRESULT End(LoginDownloadResult *result, BSTR *bstrFileName); // return S_FALSE if files binary indentical
|
||||
|
||||
private:
|
||||
HRESULT SaveProviderList(LoginDownloadResult *result, BSTR *bstrFileName);
|
||||
HRESULT SaveImage(LoginDownloadResult *result, BSTR *bstrFileName);
|
||||
HRESULT IsBinaryEqual(LPCWSTR pszFile1, LPCWSTR pszFile2);
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_DOWNLOAD_HEADER
|
||||
435
Src/auth/Loginbox/downloadResult.cpp
Normal file
435
Src/auth/Loginbox/downloadResult.cpp
Normal file
@@ -0,0 +1,435 @@
|
||||
#include "./downloadResult.h"
|
||||
#include "./loginStatus.h"
|
||||
#include "../api.h"
|
||||
#include "../resource.h"
|
||||
#include "../jnetlib/api_httpget.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
LoginDownloadResult::LoginDownloadResult(api_downloadManager *pManager, UINT uType, Callback fnCallback, void *pData, LoginStatus *pStatus)
|
||||
: ref(1), manager(pManager), flags(0), callback(fnCallback), data(pData),
|
||||
address(NULL), result(api_downloadManager::TICK_NODATA),
|
||||
cookie(0), completed(NULL), status(pStatus), statusCookie((UINT)-1)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
|
||||
SetType(uType);
|
||||
SetState(stateInitializing);
|
||||
|
||||
if (NULL != status)
|
||||
status->AddRef();
|
||||
|
||||
if (NULL != manager)
|
||||
manager->AddRef();
|
||||
}
|
||||
|
||||
LoginDownloadResult::~LoginDownloadResult()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if(NULL != manager)
|
||||
{
|
||||
if (0 != cookie)
|
||||
{
|
||||
manager->ReleaseDownload(cookie);
|
||||
cookie = 0;
|
||||
}
|
||||
|
||||
manager->Release();
|
||||
}
|
||||
|
||||
if (NULL != completed)
|
||||
CloseHandle(completed);
|
||||
|
||||
if (NULL != address)
|
||||
free(address);
|
||||
|
||||
if (NULL != status)
|
||||
{
|
||||
if (((UINT)-1) != statusCookie)
|
||||
status->Remove(statusCookie);
|
||||
|
||||
status->Release();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::CreateInstance(api_downloadManager *pManager, UINT uType, Callback fnCallback, void *pData, LoginStatus *pStatus, LoginDownloadResult **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
|
||||
if (NULL == pManager)
|
||||
{
|
||||
*instance = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
*instance = new LoginDownloadResult(pManager, uType, fnCallback, pData, pStatus);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
size_t LoginDownloadResult::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t LoginDownloadResult::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LoginDownloadResult::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
if (NULL == object) return E_POINTER;
|
||||
*object = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
void LoginDownloadResult::SetState(UINT uState)
|
||||
{
|
||||
flags = (flags & ~stateMask) | (uState & stateMask);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::SetType(UINT uType)
|
||||
{
|
||||
flags = (flags & ~typeMask) | (uType & typeMask);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::SetFlags(UINT uFlags, UINT uMask)
|
||||
{
|
||||
uMask &= flagsMask;
|
||||
flags = (flags & ~uMask) | (uFlags & uMask);
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginDownloadResult::GetState(UINT *state)
|
||||
{
|
||||
if (NULL == state)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
*state = (flags & stateMask);
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::GetType(UINT *type)
|
||||
{
|
||||
if (NULL == type)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
*type = (flags & typeMask);
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::GetFile(LPCWSTR *ppszPath)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
HRESULT hr;
|
||||
if (NULL == cookie || NULL == manager)
|
||||
{
|
||||
hr = E_UNEXPECTED;
|
||||
}
|
||||
else if (stateCompleted != (stateMask & flags))
|
||||
{
|
||||
hr = E_DWNLD_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(result)
|
||||
{
|
||||
case api_downloadManager::TICK_SUCCESS: hr = E_DWNLD_OK; break;
|
||||
case api_downloadManager::TICK_FAILURE: hr = (0 != (flagUserAbort & flags)) ? E_DWNLD_ABORT : E_DWNLD_FAIL; break;
|
||||
case api_downloadManager::TICK_TIMEOUT: hr = E_DWNLD_TIMEOUT; break;
|
||||
case api_downloadManager::TICK_CANT_CONNECT: hr = E_DWNLD_CANT_CONNECT; break;
|
||||
case api_downloadManager::TICK_WRITE_ERROR: hr = E_DWNLD_WRITE_ERROR; break;
|
||||
default: hr = E_DWNLD_BUSY; break;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != ppszPath)
|
||||
{
|
||||
if (SUCCEEDED(hr))
|
||||
*ppszPath = manager->GetLocation(cookie);
|
||||
else
|
||||
*ppszPath = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::GetWaitHandle(HANDLE *handle)
|
||||
{
|
||||
if (NULL == handle)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL == completed)
|
||||
{
|
||||
completed = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (NULL == completed)
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && FALSE == DuplicateHandle(GetCurrentProcess(), completed,
|
||||
GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::GetData(void **data)
|
||||
{
|
||||
if (NULL == data)
|
||||
return E_POINTER;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
*data = this->data;
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::RequestAbort(BOOL fDrop)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
if (FALSE != fDrop)
|
||||
{
|
||||
data = NULL;
|
||||
callback = NULL;
|
||||
}
|
||||
|
||||
if (0 != cookie && NULL != manager && 0 == (flagUserAbort & flags))
|
||||
{
|
||||
manager->CancelDownload(cookie);
|
||||
SetState(stateAborting);
|
||||
SetFlags(flagUserAbort, flagUserAbort);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::GetUrl(LPSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if(NULL == manager || 0 == cookie)
|
||||
hr = E_UNEXPECTED;
|
||||
else
|
||||
{
|
||||
api_httpreceiver *receiver = manager->GetReceiver(cookie);
|
||||
if (NULL == receiver) hr = E_FAIL;
|
||||
else
|
||||
{
|
||||
LPCSTR url = receiver->get_url();
|
||||
hr = StringCchCopyExA(pszBuffer, cchBufferMax, url, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
void LoginDownloadResult::SetStatus()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL != status && ((UINT)-1 == statusCookie))
|
||||
{
|
||||
LPCWSTR pszStatus;
|
||||
switch(typeMask & flags)
|
||||
{
|
||||
case typeProviderList: pszStatus = MAKEINTRESOURCE(IDS_STATUS_UPDATEBEGIN); break;
|
||||
default: pszStatus = NULL; break;
|
||||
}
|
||||
|
||||
if (NULL != pszStatus)
|
||||
{
|
||||
BSTR bstrText;
|
||||
if (FALSE == IS_INTRESOURCE(pszStatus))
|
||||
bstrText = SysAllocString(pszStatus);
|
||||
else
|
||||
{
|
||||
WCHAR szBuffer[256] = {0};
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszStatus, szBuffer, ARRAYSIZE(szBuffer));
|
||||
bstrText = SysAllocString(szBuffer);
|
||||
}
|
||||
|
||||
statusCookie = status->Add(bstrText);
|
||||
if (((UINT)-1) == statusCookie)
|
||||
SysFreeString(bstrText);
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
|
||||
void LoginDownloadResult::RemoveStatus()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
if (NULL != status)
|
||||
{
|
||||
if (((UINT)-1) != statusCookie)
|
||||
{
|
||||
status->Remove(statusCookie);
|
||||
statusCookie = (UINT)-1;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT LoginDownloadResult::CreateDownloadFileName(LPSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if(NULL == manager || 0 == cookie)
|
||||
hr = E_UNEXPECTED;
|
||||
else
|
||||
{
|
||||
api_httpreceiver *receiver = manager->GetReceiver(cookie);
|
||||
if (NULL == receiver) hr = E_FAIL;
|
||||
else
|
||||
{
|
||||
LPCSTR url = receiver->get_url();
|
||||
LPCSTR contentDisposition = receiver->getheader("content-disposition");
|
||||
LPCSTR contentType = receiver->getheader("content-type");
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
void LoginDownloadResult::DownloadCompleted(int errorCode)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
result = errorCode;
|
||||
SetState(stateCompleted);
|
||||
HANDLE hEvent = completed;
|
||||
Callback cb = callback;
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != hEvent)
|
||||
SetEvent(hEvent);
|
||||
|
||||
if (NULL != cb)
|
||||
cb(this, data);
|
||||
|
||||
RemoveStatus();
|
||||
Release();
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadInit(DownloadToken token)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
AddRef();
|
||||
|
||||
cookie = token;
|
||||
SetState(stateConnecting);
|
||||
|
||||
if (NULL != manager)
|
||||
{
|
||||
manager->RetainDownload(cookie);
|
||||
|
||||
if (typeProviderList == (typeMask & flags))
|
||||
{
|
||||
api_httpreceiver *receiver = manager->GetReceiver(token);
|
||||
if (NULL != receiver)
|
||||
receiver->AllowCompression();
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
SetStatus();
|
||||
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadConnect(DownloadToken token)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
SetState(stateReceiving);
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadTick(DownloadToken token)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
if (stateConnecting == (stateMask & flags))
|
||||
SetState(stateReceiving);
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadFinish(DownloadToken token)
|
||||
{
|
||||
DownloadCompleted(api_downloadManager::TICK_SUCCESS);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadError(DownloadToken token, int errorCode)
|
||||
{
|
||||
DownloadCompleted(errorCode);
|
||||
}
|
||||
|
||||
void LoginDownloadResult::Event_DownloadCancel(DownloadToken token)
|
||||
{
|
||||
DownloadCompleted(api_downloadManager::TICK_NODATA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define CBCLASS LoginDownloadResult
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef)
|
||||
CB(RELEASE, Release)
|
||||
CB(QUERYINTERFACE, QueryInterface)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONINIT, Event_DownloadInit)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, Event_DownloadConnect)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, Event_DownloadFinish)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONERROR, Event_DownloadError)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, Event_DownloadCancel)
|
||||
VCB(IFC_DOWNLOADMANAGERCALLBACK_ONTICK, Event_DownloadTick)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
110
Src/auth/Loginbox/downloadResult.h
Normal file
110
Src/auth/Loginbox/downloadResult.h
Normal file
@@ -0,0 +1,110 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_DOWNLOAD_RESULT_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_DOWNLOAD_RESULT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../dlmgr/api_downloadmanager.h"
|
||||
|
||||
#define E_DWNLD_OK S_OK
|
||||
#define E_DWNLD_BUSY E_PENDING
|
||||
#define E_DWNLD_FAIL E_FAIL
|
||||
#define E_DWNLD_ABORT E_ABORT
|
||||
#define E_DWNLD_TIMEOUT HRESULT_FROM_WIN32(ERROR_TIMEOUT)
|
||||
#define E_DWNLD_CANT_CONNECT HRESULT_FROM_WIN32(ERROR_NOT_CONNECTED)
|
||||
#define E_DWNLD_WRITE_ERROR HRESULT_FROM_WIN32(ERROR_WRITE_FAULT)
|
||||
|
||||
class LoginStatus;
|
||||
|
||||
class LoginDownloadResult : public ifc_downloadManagerCallback
|
||||
{
|
||||
public:
|
||||
typedef void (CALLBACK *Callback)(LoginDownloadResult *result, void *data);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
stateMask = 0x00000FF00,
|
||||
stateReady = 0x00000000,
|
||||
stateInitializing = 0x00000100,
|
||||
stateConnecting = 0x00000200,
|
||||
stateReceiving = 0x00000300,
|
||||
stateCompleted = 0x00000400,
|
||||
stateAborting = 0x00000500,
|
||||
} States;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
typeMask = 0x0000000FF,
|
||||
typeUnknown = 0x00000000,
|
||||
typeImage = 0x00000001,
|
||||
typeProviderList = 0x00000002,
|
||||
} Types;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
flagsMask = 0xFFFF0000,
|
||||
flagUserAbort = 0x00010000,
|
||||
} Flags;
|
||||
|
||||
protected:
|
||||
LoginDownloadResult(api_downloadManager *pManager, UINT uType, Callback fnCallback, void *pData, LoginStatus *pStatus);
|
||||
~LoginDownloadResult();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(api_downloadManager *pManager, UINT uType, Callback fnCallback, void *pData, LoginStatus *pStatus, LoginDownloadResult **instance);
|
||||
|
||||
public:
|
||||
/* Dispatchable */
|
||||
size_t AddRef();
|
||||
size_t Release();
|
||||
int QueryInterface(GUID interface_guid, void **object);
|
||||
|
||||
HRESULT GetWaitHandle(HANDLE *handle);
|
||||
HRESULT GetData(void **data);
|
||||
HRESULT GetType(UINT *type);
|
||||
HRESULT GetState(UINT *state);
|
||||
HRESULT GetFile(LPCWSTR *ppszPath);
|
||||
|
||||
HRESULT CreateDownloadFileName(LPSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetUrl(LPSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT RequestAbort(BOOL fDrop);
|
||||
|
||||
protected:
|
||||
/* ifc_downloadManagerCallback */
|
||||
void Event_DownloadFinish(DownloadToken token);
|
||||
void Event_DownloadTick(DownloadToken token);
|
||||
void Event_DownloadError(DownloadToken token, int errorCode);
|
||||
void Event_DownloadCancel(DownloadToken token);
|
||||
void Event_DownloadConnect(DownloadToken token);
|
||||
void Event_DownloadInit(DownloadToken token);
|
||||
|
||||
void DownloadCompleted(int errorCode);
|
||||
void SetState(UINT uState);
|
||||
void SetType(UINT uType);
|
||||
void SetFlags(UINT uFlags, UINT uMask);
|
||||
void SetStatus();
|
||||
void RemoveStatus();
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
size_t ref;
|
||||
UINT flags;
|
||||
LPWSTR address;
|
||||
INT result;
|
||||
api_downloadManager *manager;
|
||||
DownloadToken cookie;
|
||||
HANDLE completed;
|
||||
Callback callback;
|
||||
void *data;
|
||||
LoginStatus *status;
|
||||
UINT statusCookie;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINDOWNLOADER_HEADER
|
||||
269
Src/auth/Loginbox/editboxExtender.cpp
Normal file
269
Src/auth/Loginbox/editboxExtender.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
#include "./editboxExtender.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
#define NAEF_USERFLAGSMASK 0x00FFFFFF
|
||||
#define NAEF_UNICODE 0x01000000
|
||||
|
||||
typedef struct __EDITBOXEXTENDER
|
||||
{
|
||||
WNDPROC originalProc;
|
||||
UINT flags;
|
||||
DWORD dblclkTime;
|
||||
LPWSTR rollbackText;
|
||||
} EDITBOXEXTENDER;
|
||||
|
||||
#define EDITBOXEXTENDER_PROP L"NullsoftEditboxExtender"
|
||||
|
||||
#define GetEditbox(__hwnd) ((EDITBOXEXTENDER*)GetProp((__hwnd), EDITBOXEXTENDER_PROP))
|
||||
|
||||
static LRESULT CALLBACK EditboxExtender_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
BOOL EditboxExtender_AttachWindow(HWND hEditbox)
|
||||
{
|
||||
if (!IsWindow(hEditbox))
|
||||
return FALSE;
|
||||
|
||||
EDITBOXEXTENDER *editbox = (EDITBOXEXTENDER*)GetProp(hEditbox, EDITBOXEXTENDER_PROP);
|
||||
if (NULL != editbox) return TRUE;
|
||||
|
||||
editbox = (EDITBOXEXTENDER*)calloc(1, sizeof(EDITBOXEXTENDER));
|
||||
if (NULL == editbox) return FALSE;
|
||||
|
||||
if (IsWindowUnicode(hEditbox))
|
||||
editbox->flags |= NAEF_UNICODE;
|
||||
|
||||
editbox->originalProc = (WNDPROC)(LONG_PTR)((0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)EditboxExtender_WindowProc) :
|
||||
SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)EditboxExtender_WindowProc));
|
||||
|
||||
if (NULL == editbox->originalProc || !SetProp(hEditbox, EDITBOXEXTENDER_PROP, editbox))
|
||||
{
|
||||
if (NULL != editbox->originalProc)
|
||||
{
|
||||
if (0 != (NAEF_UNICODE & editbox->flags))
|
||||
SetWindowLongPtrW(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hEditbox, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
}
|
||||
|
||||
free(editbox);
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static void EditboxExtender_Detach(HWND hwnd)
|
||||
{
|
||||
EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
|
||||
RemoveProp(hwnd, EDITBOXEXTENDER_PROP);
|
||||
|
||||
if (NULL == editbox)
|
||||
return;
|
||||
|
||||
if (NULL != editbox->originalProc)
|
||||
{
|
||||
if (0 != (NAEF_UNICODE & editbox->flags))
|
||||
SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
else
|
||||
SetWindowLongPtrA(hwnd, GWLP_WNDPROC, (LONGX86)(LONG_PTR)editbox->originalProc);
|
||||
}
|
||||
free(editbox);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT EditboxExtender_CallOrigWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
|
||||
|
||||
if (NULL == editbox || NULL == editbox->originalProc)
|
||||
{
|
||||
return (0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
DefWindowProcW(hwnd, uMsg, wParam, lParam) :
|
||||
DefWindowProcA(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
return (0 != (NAEF_UNICODE & editbox->flags)) ?
|
||||
CallWindowProcW(editbox->originalProc, hwnd, uMsg, wParam, lParam) :
|
||||
CallWindowProcA(editbox->originalProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnDestroy(HWND hwnd)
|
||||
{
|
||||
EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
|
||||
|
||||
WNDPROC originalProc = editbox->originalProc;
|
||||
BOOL fUnicode = (0 != (NAEF_UNICODE & editbox->flags));
|
||||
|
||||
EditboxExtender_Detach(hwnd);
|
||||
|
||||
if (NULL != originalProc)
|
||||
{
|
||||
if (FALSE != fUnicode)
|
||||
CallWindowProcW(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
else
|
||||
CallWindowProcA(originalProc, hwnd, WM_DESTROY, 0, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT EditboxExtender_OnGetDlgCode(HWND hwnd, INT vKey, MSG* pMsg)
|
||||
{
|
||||
LRESULT result = EditboxExtender_CallOrigWindowProc(hwnd, WM_GETDLGCODE, (WPARAM)vKey, (LPARAM)pMsg);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnLButtonDown(HWND hwnd, UINT vKey, POINTS pts)
|
||||
{
|
||||
EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
|
||||
if (NULL != editbox)
|
||||
{
|
||||
DWORD clickTime = GetTickCount();
|
||||
if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + GetDoubleClickTime()))
|
||||
{
|
||||
SendMessage(hwnd, EM_SETSEL, 0, -1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
EditboxExtender_CallOrigWindowProc(hwnd, WM_LBUTTONDOWN, (WPARAM)vKey, *((LPARAM*)&pts));
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnLButtonDblClk(HWND hwnd, UINT vKey, POINTS pts)
|
||||
{
|
||||
EDITBOXEXTENDER *editbox = GetEditbox(hwnd);
|
||||
if (NULL == editbox) return;
|
||||
|
||||
DWORD clickTime = GetTickCount();
|
||||
if (clickTime >= editbox->dblclkTime && clickTime <= (editbox->dblclkTime + 2*GetDoubleClickTime()))
|
||||
{
|
||||
INT r = (INT)SendMessage(hwnd, EM_CHARFROMPOS, 0, *(LPARAM*)&pts);
|
||||
r = LOWORD(r);
|
||||
SendMessage(hwnd, EM_SETSEL, (WPARAM)r, (LPARAM)r);
|
||||
editbox->dblclkTime = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
editbox->dblclkTime = clickTime;
|
||||
}
|
||||
|
||||
INT f, l;
|
||||
SendMessage(hwnd, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
|
||||
if (f != l) return;
|
||||
|
||||
|
||||
EditboxExtender_CallOrigWindowProc(hwnd, WM_LBUTTONDBLCLK, (WPARAM)vKey, *((LPARAM*)&pts));
|
||||
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnChar(HWND hwnd, UINT vKey, UINT state)
|
||||
{
|
||||
if (0 == (0x8000 & GetAsyncKeyState(VK_CONTROL)) && 0 == (0x8000 & GetAsyncKeyState(VK_MENU)))
|
||||
{
|
||||
HWND hParent = GetAncestor(hwnd, GA_PARENT);
|
||||
if (NULL != hParent)
|
||||
{
|
||||
NMCHAR nmh;
|
||||
nmh.hdr.hwndFrom = hwnd;
|
||||
nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
|
||||
nmh.hdr.code = NM_CHAR;
|
||||
nmh.ch = vKey;
|
||||
nmh.dwItemNext = 0;
|
||||
nmh.dwItemPrev = 0;
|
||||
if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
|
||||
return;
|
||||
}
|
||||
}
|
||||
EditboxExtender_CallOrigWindowProc(hwnd, WM_CHAR, (WPARAM)vKey, (LPARAM)state);
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnKeyDown(HWND hwnd, UINT vKey, UINT state)
|
||||
{
|
||||
HWND hParent = GetAncestor(hwnd, GA_PARENT);
|
||||
if (NULL != hParent)
|
||||
{
|
||||
NMKEY nmh;
|
||||
nmh.hdr.hwndFrom = hwnd;
|
||||
nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
|
||||
nmh.hdr.code = NM_KEYDOWN;
|
||||
nmh.nVKey = vKey;
|
||||
nmh.uFlags = HIWORD(state);
|
||||
if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
|
||||
return;
|
||||
}
|
||||
|
||||
EditboxExtender_CallOrigWindowProc(hwnd, WM_KEYDOWN, (WPARAM)vKey, (LPARAM)state);
|
||||
}
|
||||
|
||||
static void EditboxExtender_PasteText(HWND hwnd, LPCWSTR pszClipboard)
|
||||
{
|
||||
HWND hParent = GetAncestor(hwnd, GA_PARENT);
|
||||
if (NULL != hParent)
|
||||
{
|
||||
EENMPASTE nmh;
|
||||
nmh.hdr.hwndFrom = hwnd;
|
||||
nmh.hdr.idFrom = (INT)(INT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
|
||||
nmh.hdr.code = EENM_PASTE;
|
||||
nmh.text = pszClipboard;
|
||||
if (FALSE != (BOOL)SendMessage(hParent, WM_NOTIFY, nmh.hdr.idFrom, (LPARAM)&nmh))
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessage(hwnd, EM_REPLACESEL, (WPARAM)TRUE, (LPARAM)pszClipboard);
|
||||
}
|
||||
|
||||
static void EditboxExtender_OnPaste(HWND hwnd)
|
||||
{
|
||||
IDataObject *pObject;
|
||||
HRESULT hr = OleGetClipboard(&pObject);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
FORMATETC fmt = {CF_UNICODETEXT, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
|
||||
STGMEDIUM stgm;
|
||||
hr = pObject->GetData(&fmt, &stgm);
|
||||
if(S_OK == hr)
|
||||
{
|
||||
LPCWSTR pClipboard = (LPCWSTR)GlobalLock(stgm.hGlobal);
|
||||
EditboxExtender_PasteText(hwnd, pClipboard);
|
||||
|
||||
GlobalUnlock(stgm.hGlobal);
|
||||
ReleaseStgMedium(&stgm);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.cfFormat = CF_TEXT;
|
||||
hr = pObject->GetData(&fmt, &stgm);
|
||||
if(S_OK == hr)
|
||||
{
|
||||
LPCSTR pClipboardAnsi = (LPCSTR)GlobalLock(stgm.hGlobal);
|
||||
LPWSTR pClipboard;
|
||||
if (FAILED(LoginBox_MultiByteToWideChar(CP_ACP, 0, pClipboardAnsi, -1, &pClipboard)))
|
||||
pClipboard = NULL;
|
||||
|
||||
EditboxExtender_PasteText(hwnd, pClipboard);
|
||||
|
||||
LoginBox_FreeString(pClipboard);
|
||||
GlobalUnlock(stgm.hGlobal);
|
||||
ReleaseStgMedium(&stgm);
|
||||
}
|
||||
}
|
||||
pObject->Release();
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK EditboxExtender_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_DESTROY: EditboxExtender_OnDestroy(hwnd); return 0;
|
||||
case WM_GETDLGCODE: return EditboxExtender_OnGetDlgCode(hwnd, (INT)wParam, (MSG*)lParam);
|
||||
case WM_LBUTTONDOWN: EditboxExtender_OnLButtonDown(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
|
||||
case WM_LBUTTONDBLCLK: EditboxExtender_OnLButtonDblClk(hwnd, (UINT)wParam, MAKEPOINTS(lParam)); return 0;
|
||||
case WM_CHAR: EditboxExtender_OnChar(hwnd, (UINT)wParam, (UINT)lParam); return 0;
|
||||
case WM_KEYDOWN: EditboxExtender_OnKeyDown(hwnd, (UINT)wParam, (UINT)lParam); return 0;
|
||||
case WM_PASTE: EditboxExtender_OnPaste(hwnd); return 1;
|
||||
}
|
||||
|
||||
return EditboxExtender_CallOrigWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
22
Src/auth/Loginbox/editboxExtender.h
Normal file
22
Src/auth/Loginbox/editboxExtender.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_EDITBOX_EXTENDER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_EDITBOX_EXTENDER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
BOOL EditboxExtender_AttachWindow(HWND hEditbox);
|
||||
|
||||
// notification
|
||||
typedef struct __EENMPASTE
|
||||
{
|
||||
NMHDR hdr;
|
||||
LPCWSTR text;
|
||||
}EENMPASTE;
|
||||
|
||||
#define EENM_FIRST 10
|
||||
#define EENM_PASTE (EENM_FIRST + 0L)
|
||||
|
||||
#endif // NULLSOFT_AUTH_LOGINBOX_EDITBOX_EXTENDER_HEADER
|
||||
401
Src/auth/Loginbox/externalMngr.cpp
Normal file
401
Src/auth/Loginbox/externalMngr.cpp
Normal file
@@ -0,0 +1,401 @@
|
||||
#include "./externalMngr.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include "../../winamp/jsapi.h"
|
||||
|
||||
ExternalManager::ExternalManager()
|
||||
: ref(1), lastDispId(0)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
}
|
||||
|
||||
ExternalManager::~ExternalManager()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index= list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
list[index].object->Release();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT ExternalManager::CreateInstance(ExternalManager **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
|
||||
*instance = new ExternalManager();
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) ExternalManager::AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) ExternalManager::Release(void)
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::QueryInterface(REFIID riid, PVOID *ppvObject)
|
||||
{
|
||||
if (NULL == ppvObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IID_IDispatchEx))
|
||||
*ppvObject = static_cast<IDispatchEx*>(this);
|
||||
else if (IsEqualIID(riid, IID_IDispatch))
|
||||
*ppvObject = static_cast<IDispatch*>(this);
|
||||
else if (IsEqualIID(riid, IID_IUnknown))
|
||||
*ppvObject = static_cast<IUnknown*>(this);
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *ppvObject)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
UINT unknowns = 0;
|
||||
size_t count = list.size();
|
||||
for (UINT i = 0; i != cNames ; i++)
|
||||
{
|
||||
rgdispid[i] = DISPID_UNKNOWN;
|
||||
for (size_t j =0; j < count; j++)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(lcid, 0, rgszNames[i], -1, list[j].name, -1))
|
||||
{
|
||||
if (NULL != list[j].object)
|
||||
rgdispid[i] = list[j].id;
|
||||
else
|
||||
unknowns++;
|
||||
break;
|
||||
}
|
||||
if (DISPID_UNKNOWN == rgdispid[i])
|
||||
unknowns++;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return (0 != unknowns) ? DISP_E_UNKNOWNNAME : S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetTypeInfo(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetTypeInfoCount(unsigned int FAR * pctinfo)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::Invoke(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr)
|
||||
{
|
||||
return InvokeEx(dispid, lcid, wFlags, pdispparams, pvarResult, pexecinfo, 0);
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetDispID(BSTR bstrName, DWORD grfdex, DISPID *pid)
|
||||
{
|
||||
if (NULL == pid) return E_POINTER;
|
||||
*pid = DISPID_UNKNOWN;
|
||||
|
||||
HRESULT hr = DISP_E_UNKNOWNNAME;
|
||||
|
||||
if (NULL != bstrName && L'\0' != *bstrName)
|
||||
{
|
||||
UINT compareFlags = 0;
|
||||
if (0 != (fdexNameCaseInsensitive & grfdex))
|
||||
compareFlags |= NORM_IGNORECASE;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, compareFlags, bstrName, -1, list[index].name, -1))
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
*pid = list[index].id;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::InvokeEx(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
|
||||
{
|
||||
if (DISPATCH_METHOD == wFlags || DISPATCH_PROPERTYGET == wFlags || DISPATCH_CONSTRUCT == wFlags)
|
||||
JSAPI_INIT_RESULT(pvarRes, VT_DISPATCH);
|
||||
|
||||
HRESULT hr(DISP_E_MEMBERNOTFOUND);
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (id == list[index].id)
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
if (NULL != pvarRes &&
|
||||
(DISPATCH_METHOD == wFlags || DISPATCH_PROPERTYGET == wFlags || DISPATCH_CONSTRUCT == wFlags))
|
||||
{
|
||||
list[index].object->AddRef();
|
||||
pvarRes->pdispVal = list[index].object;
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::DeleteMemberByName(BSTR bstrName, DWORD grfdex)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
if (NULL != bstrName && L'\0' != *bstrName)
|
||||
{
|
||||
UINT compareFlags = 0;
|
||||
if (0 != (fdexNameCaseInsensitive & grfdex))
|
||||
compareFlags |= NORM_IGNORECASE;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, compareFlags, bstrName, -1, list[index].name, -1))
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
list[index].object->Release();
|
||||
list[index].object = NULL;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::DeleteMemberByDispID(DISPID id)
|
||||
{
|
||||
HRESULT hr = S_FALSE;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (id == list[index].id)
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
list[index].object->Release();
|
||||
list[index].object = NULL;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetMemberProperties(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
|
||||
{
|
||||
HRESULT hr(DISP_E_UNKNOWNNAME);
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (id == list[index].id)
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
if (NULL != pgrfdex)
|
||||
{
|
||||
*pgrfdex = 0;
|
||||
if (0 != (grfdexPropCanAll & grfdexFetch))
|
||||
*pgrfdex |= (fdexPropCanGet | fdexPropCanCall);
|
||||
if (0 != (grfdexPropCannotAll & grfdexFetch))
|
||||
*pgrfdex |= (fdexPropCannotPut | fdexPropCanPutRef | fdexPropCannotConstruct | fdexPropCannotSourceEvents);
|
||||
if (0 != (grfdexPropExtraAll & grfdexFetch))
|
||||
*pgrfdex |= (fdexPropNoSideEffects | fdexPropNoSideEffects);
|
||||
}
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetMemberName(DISPID id, BSTR *pbstrName)
|
||||
{
|
||||
HRESULT hr(DISP_E_UNKNOWNNAME);
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (id == list[index].id)
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
if (NULL != pbstrName)
|
||||
{
|
||||
*pbstrName = SysAllocString(list[index].name);
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetNextDispID(DWORD grfdex, DISPID id, DISPID *pid)
|
||||
{
|
||||
HRESULT hr(S_FALSE);
|
||||
if (NULL == pid) return S_FALSE;
|
||||
*pid = DISPID_UNKNOWN;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t count = list.size();
|
||||
if (DISPID_STARTENUM == id)
|
||||
{
|
||||
if (count > 0)
|
||||
{
|
||||
*pid = list[0].id;
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(size_t i = 0; i < count; i++)
|
||||
{
|
||||
if (id == list[i].id)
|
||||
{
|
||||
i++;
|
||||
if (i < count)
|
||||
{
|
||||
*pid = list[i].id;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP ExternalManager::GetNameSpaceParent(IUnknown **ppunk)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT ExternalManager::AddDispatch(LPCWSTR pszName, IDispatch *pDispatch, DISPID *pid)
|
||||
{
|
||||
if (NULL != pid)
|
||||
*pid = DISPID_UNKNOWN;
|
||||
|
||||
if (NULL == pszName || L'\0' == pszName || NULL == pDispatch)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, pszName, -1, list[index].name, -1))
|
||||
{
|
||||
if (NULL != list[index].object)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
list[index].object = pDispatch;
|
||||
pDispatch->AddRef();
|
||||
*pid = list[index].id;
|
||||
hr = S_OK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((size_t)-1 == index)
|
||||
{
|
||||
DispatchRecord r;
|
||||
r.name = LoginBox_CopyString(pszName);
|
||||
if (NULL == r.name)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
r.id = ++lastDispId;
|
||||
r.object = pDispatch;
|
||||
pDispatch->AddRef();
|
||||
list.push_back(r);
|
||||
*pid = r.id;
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
65
Src/auth/Loginbox/externalMngr.h
Normal file
65
Src/auth/Loginbox/externalMngr.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_EXTERNAL_MANAGER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_EXTERNAL_MANAGER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include <dispex.h>
|
||||
#include "../nu/Vectors.h"
|
||||
|
||||
|
||||
class ExternalManager : public IDispatchEx
|
||||
{
|
||||
protected:
|
||||
ExternalManager();
|
||||
~ExternalManager();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(ExternalManager **instance);
|
||||
|
||||
public:
|
||||
/* IUnknown */
|
||||
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
|
||||
STDMETHOD_(ULONG, AddRef)(void);
|
||||
STDMETHOD_(ULONG, Release)(void);
|
||||
|
||||
/* IDispatch*/
|
||||
STDMETHOD(GetIDsOfNames)(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgdispid);
|
||||
STDMETHOD(GetTypeInfo)(unsigned int itinfo, LCID lcid, ITypeInfo FAR* FAR* pptinfo);
|
||||
STDMETHOD(GetTypeInfoCount)(unsigned int FAR * pctinfo);
|
||||
STDMETHOD(Invoke)(DISPID dispid, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, EXCEPINFO FAR * pexecinfo, unsigned int FAR *puArgErr);
|
||||
|
||||
/* IDispatchEx*/
|
||||
STDMETHOD (GetDispID)(BSTR bstrName, DWORD grfdex, DISPID *pid);
|
||||
STDMETHOD (InvokeEx)(DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp, VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller);
|
||||
STDMETHOD (DeleteMemberByName)(BSTR bstrName, DWORD grfdex);
|
||||
STDMETHOD (DeleteMemberByDispID)(DISPID id);
|
||||
STDMETHOD (GetMemberProperties)(DISPID id, DWORD grfdexFetch, DWORD *pgrfdex);
|
||||
STDMETHOD (GetMemberName)(DISPID id, BSTR *pbstrName);
|
||||
STDMETHOD (GetNextDispID)(DWORD grfdex, DISPID id, DISPID *pid);
|
||||
STDMETHOD (GetNameSpaceParent)(IUnknown **ppunk);
|
||||
|
||||
public:
|
||||
HRESULT AddDispatch(LPCWSTR pszName, IDispatch *pDispatch, DISPID *pid);
|
||||
|
||||
protected:
|
||||
typedef struct __DispatchRecord
|
||||
{
|
||||
DISPID id;
|
||||
LPWSTR name;
|
||||
IDispatch *object;
|
||||
} DispatchRecord;
|
||||
|
||||
typedef Vector<DispatchRecord> DispatchList;
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
DispatchList list;
|
||||
CRITICAL_SECTION lock;
|
||||
DISPID lastDispId;
|
||||
};
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_EXTERNAL_MANAGER_HEADER
|
||||
434
Src/auth/Loginbox/graphics.cpp
Normal file
434
Src/auth/Loginbox/graphics.cpp
Normal file
@@ -0,0 +1,434 @@
|
||||
#include "./graphics.h"
|
||||
#include "./shlwapi.h"
|
||||
|
||||
BOOL Image_ColorOverEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgb)
|
||||
{
|
||||
LONG pitch;
|
||||
UINT a, r, g, b, ma, mr, mg, mb;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (step < 3)
|
||||
return TRUE;
|
||||
|
||||
if (cy < 0) cy -= cy;
|
||||
|
||||
a = (LOBYTE((rgb)>>24)); r = GetRValue(rgb); g = GetGValue(rgb); b = GetBValue(rgb);
|
||||
ma = 255 - a; mr = r * 255; mg = g * 255; mb = b * 255;
|
||||
|
||||
if (0 == a)
|
||||
return TRUE;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
line = pPixels + pitch * ofs + x*step;
|
||||
|
||||
if (0xFF == a)
|
||||
{
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
cursor[0] = (BYTE)b;
|
||||
cursor[1] = (BYTE)g;
|
||||
cursor[2] = (BYTE)r;
|
||||
// cursor[3] = 0xFF;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (premult)
|
||||
{
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
UINT t = (mb + ma * cursor[0] + 127) / 255;
|
||||
cursor[0] = (t > 0xFF) ? 0xFF : t;
|
||||
t = (mg + ma * cursor[1] + 127) / 255;
|
||||
cursor[1] = (t > 0xFF) ? 0xFF : t;
|
||||
t = (mr+ ma * cursor[2] + 127) / 255;
|
||||
cursor[2] = (t > 0xFF) ? 0xFF : t;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WORD k = (((255 - a)*255 + 127)/255);
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
cursor[0] = (b*a + k*cursor[0] + 127)/255;
|
||||
cursor[1] = (g*a + k*cursor[1] + 127)/255;
|
||||
cursor[2] = (r*a + k*cursor[2] + 127)/255;
|
||||
// cursor[3] = (a*a + k*cursor[3] + 127)/255;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL Image_ColorizeEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgbBottom, COLORREF rgbTop)
|
||||
{
|
||||
LONG pitch;
|
||||
UINT rBottom, gBottom, bBottom;
|
||||
UINT rTop, gTop, bTop;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE startLine, line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (cy < 0)
|
||||
cy = -cy;
|
||||
|
||||
rBottom = GetRValue(rgbBottom);
|
||||
gBottom = GetGValue(rgbBottom);
|
||||
bBottom = GetBValue(rgbBottom);
|
||||
|
||||
rTop = GetRValue(rgbTop);
|
||||
gTop = GetGValue(rgbTop);
|
||||
bTop = GetBValue(rgbTop);
|
||||
|
||||
UINT a, k;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
startLine = pPixels + pitch * ofs + x*step;
|
||||
|
||||
line = startLine;
|
||||
|
||||
for (y = cy; y-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
a = (255- cursor[2]);
|
||||
if (a < 0) a = 0;
|
||||
if (a > 254)
|
||||
{
|
||||
cursor[0] = bTop;
|
||||
cursor[1] = gTop;
|
||||
cursor[2] = rTop;
|
||||
}
|
||||
else if (a== 0)
|
||||
{
|
||||
cursor[0] = bBottom;
|
||||
cursor[1] = gBottom;
|
||||
cursor[2] = rBottom;
|
||||
}
|
||||
else
|
||||
{
|
||||
k = (((255 - a)*255 + 127)/255);
|
||||
cursor[0] = (bTop * a + k*bBottom + 127)/255;
|
||||
cursor[1] = (gTop * a + k*gBottom + 127)/255;
|
||||
cursor[2] = (rTop * a + k*rBottom + 127)/255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (32 == bpp && FALSE != premult)
|
||||
{
|
||||
line = startLine;
|
||||
for (y = cy; y-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
a = cursor[3];
|
||||
k = MulDiv(cursor[0], a, 255);
|
||||
cursor[0] = (k < 255) ? k : 255;
|
||||
k = MulDiv(cursor[1], a, 255);
|
||||
cursor[1] = (k < 255) ? k : 255;
|
||||
k = MulDiv(cursor[2], a, 255);
|
||||
cursor[2] = (k < 255) ? k : 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL Image_PremultiplyEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp)
|
||||
{
|
||||
if (32 != bpp)
|
||||
return FALSE;
|
||||
|
||||
LONG pitch;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (cy < 0)
|
||||
cy = -cy;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
line = pPixels + pitch * ofs + x*step;
|
||||
|
||||
UINT a,k;
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
a = cursor[3];
|
||||
if (0 == a)
|
||||
{
|
||||
cursor[0] = 0;
|
||||
cursor[1] = 0;
|
||||
cursor[2] = 0;
|
||||
}
|
||||
else if (255 != a)
|
||||
{
|
||||
k = MulDiv((UINT)cursor[0], a, 255);
|
||||
cursor[0] = (k < 255) ? k : 255;
|
||||
k = MulDiv((UINT)cursor[1], a, 255);
|
||||
cursor[1] = (k < 255) ? k : 255;
|
||||
k = MulDiv((UINT)cursor[2], a, 255);
|
||||
cursor[2] = (k < 255) ? k : 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Image_SaturateEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale)
|
||||
{
|
||||
if (32 != bpp)
|
||||
return FALSE;
|
||||
|
||||
LONG pitch;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (FALSE == fScale)
|
||||
{
|
||||
if (n < 0) n = 0;
|
||||
else if (n > 1000) n = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n < -1000) n = -1000;
|
||||
else if (n > 1000) n = 1000;
|
||||
}
|
||||
|
||||
if (cy < 0)
|
||||
cy = -cy;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
line = pPixels + pitch * ofs + x*step;
|
||||
|
||||
COLORREF rgb;
|
||||
INT k;
|
||||
WORD h, l, s;
|
||||
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
rgb = RGB(cursor[2], cursor[1], cursor[0]);
|
||||
ColorRGBToHLS(rgb, &h, &l, &s);
|
||||
if(FALSE == fScale)
|
||||
s = ((WORD)((240 * n)/1000));
|
||||
else
|
||||
{
|
||||
k = s;
|
||||
s = (WORD)(k + (k * n) /1000);
|
||||
}
|
||||
|
||||
rgb = ColorHLSToRGB(h, l, s);
|
||||
|
||||
cursor[0] = GetBValue(rgb);
|
||||
cursor[1] = GetGValue(rgb);
|
||||
cursor[2] = GetRValue(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL Image_AdjustAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale)
|
||||
{
|
||||
if (32 != bpp)
|
||||
return FALSE;
|
||||
|
||||
LONG pitch;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (FALSE == fScale)
|
||||
{
|
||||
if (n < 0) n = 0;
|
||||
else if (n > 1000) n = 1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (n < -1000) n = -1000;
|
||||
else if (n > 1000) n = 1000;
|
||||
}
|
||||
|
||||
if (cy < 0)
|
||||
cy = -cy;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
line = pPixels + pitch * ofs + x*step;
|
||||
|
||||
INT k;
|
||||
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
if(FALSE == fScale)
|
||||
cursor[3] = ((BYTE)((255 * n)/1000));
|
||||
else
|
||||
{
|
||||
k = cursor[3];
|
||||
k = k + MulDiv(k, n, 1000);
|
||||
if (k > 255) k = 255;
|
||||
cursor[3] = (BYTE)k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL Image_AdjustSaturationAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT nSaturation, INT nAlpha)
|
||||
{
|
||||
if (32 != bpp)
|
||||
return FALSE;
|
||||
|
||||
LONG pitch;
|
||||
INT step = (bpp>>3);
|
||||
LPBYTE line, cursor;
|
||||
pitch = bitmapCX * step;
|
||||
while (pitch%4) pitch++;
|
||||
|
||||
if (nSaturation < -1000) nSaturation = -1000;
|
||||
else if (nSaturation > 1000) nSaturation = 1000;
|
||||
|
||||
if (nAlpha < -1000) nAlpha = -1000;
|
||||
else if (nAlpha > 1000) nAlpha = 1000;
|
||||
|
||||
if (cy < 0)
|
||||
cy = -cy;
|
||||
|
||||
INT ofs = (bitmapCY > 0) ? (bitmapCY - (y + cy)) : y;
|
||||
line = pPixels + pitch * ofs + x*step;
|
||||
|
||||
INT k;
|
||||
COLORREF rgb;
|
||||
WORD h, l, s;
|
||||
|
||||
for (; cy-- != 0; line += pitch)
|
||||
{
|
||||
for (x = cx, cursor = line; x-- != 0; cursor += step)
|
||||
{
|
||||
k = cursor[3];
|
||||
k = k + MulDiv(k, nAlpha, 1000);
|
||||
if (k > 255) k = 255;
|
||||
cursor[3] = (BYTE)k;
|
||||
|
||||
rgb = RGB(cursor[2], cursor[1], cursor[0]);
|
||||
ColorRGBToHLS(rgb, &h, &l, &s);
|
||||
|
||||
k = s;
|
||||
k = k + MulDiv(k, nSaturation, 1000);
|
||||
if (k > 240) k = 240;
|
||||
s = (WORD)k;
|
||||
|
||||
rgb = ColorHLSToRGB(h, l, s);
|
||||
cursor[0] = GetBValue(rgb);
|
||||
cursor[1] = GetGValue(rgb);
|
||||
cursor[2] = GetRValue(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
BOOL Image_ColorOver(HBITMAP hbmp, RECT *prcPart, BOOL premult, COLORREF rgb)
|
||||
{
|
||||
DIBSECTION dibsec;
|
||||
if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
|
||||
BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
|
||||
return FALSE;
|
||||
|
||||
return Image_ColorOverEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
|
||||
prcPart->left, prcPart->top,
|
||||
prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
|
||||
dibsec.dsBm.bmBitsPixel, premult, rgb);
|
||||
}
|
||||
|
||||
BOOL Image_Premultiply(HBITMAP hbmp, RECT *prcPart)
|
||||
{
|
||||
DIBSECTION dibsec;
|
||||
if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
|
||||
BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
|
||||
return FALSE;
|
||||
|
||||
return Image_PremultiplyEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
|
||||
prcPart->left, prcPart->top,
|
||||
prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
|
||||
dibsec.dsBm.bmBitsPixel);
|
||||
}
|
||||
|
||||
BOOL Image_Saturate(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale)
|
||||
{
|
||||
DIBSECTION dibsec;
|
||||
if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
|
||||
BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
|
||||
return FALSE;
|
||||
|
||||
return Image_SaturateEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
|
||||
prcPart->left, prcPart->top,
|
||||
prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
|
||||
dibsec.dsBm.bmBitsPixel, n, fScale);
|
||||
}
|
||||
|
||||
BOOL Image_AdjustAlpha(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale)
|
||||
{
|
||||
DIBSECTION dibsec;
|
||||
if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
|
||||
BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
|
||||
return FALSE;
|
||||
|
||||
return Image_AdjustAlphaEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
|
||||
prcPart->left, prcPart->top,
|
||||
prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
|
||||
dibsec.dsBm.bmBitsPixel, n, fScale);
|
||||
}
|
||||
|
||||
BOOL Image_AdjustSaturationAlpha(HBITMAP hbmp, RECT *prcPart, INT nSaturation, INT nAlpha)
|
||||
{
|
||||
DIBSECTION dibsec;
|
||||
if (!hbmp || sizeof(DIBSECTION) != GetObject(hbmp, sizeof(DIBSECTION), &dibsec) ||
|
||||
BI_RGB != dibsec.dsBmih.biCompression || 1 != dibsec.dsBmih.biPlanes || dibsec.dsBm.bmBitsPixel != 32)
|
||||
return FALSE;
|
||||
|
||||
return Image_AdjustSaturationAlphaEx((BYTE*)dibsec.dsBm.bmBits, dibsec.dsBm.bmWidth, dibsec.dsBm.bmHeight,
|
||||
prcPart->left, prcPart->top,
|
||||
prcPart->right - prcPart->left, prcPart->bottom - prcPart->top,
|
||||
dibsec.dsBm.bmBitsPixel, nSaturation, nAlpha);
|
||||
}
|
||||
|
||||
COLORREF Color_Blend(COLORREF rgbTop, COLORREF rgbBottom, INT alpha)
|
||||
{
|
||||
if (alpha > 254) return rgbTop;
|
||||
if (alpha < 0) return rgbBottom;
|
||||
|
||||
WORD k = (((255 - alpha)*255 + 127)/255);
|
||||
|
||||
return RGB( (GetRValue(rgbTop)*alpha + k*GetRValue(rgbBottom) + 127)/255,
|
||||
(GetGValue(rgbTop)*alpha + k*GetGValue(rgbBottom) + 127)/255,
|
||||
(GetBValue(rgbTop)*alpha + k*GetBValue(rgbBottom) + 127)/255);
|
||||
}
|
||||
29
Src/auth/Loginbox/graphics.h
Normal file
29
Src/auth/Loginbox/graphics.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_GRAPHICS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_GRAPHICS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
BOOL Image_ColorOver(HBITMAP hbmp, RECT *prcPart, BOOL premult, COLORREF rgb);
|
||||
BOOL Image_ColorOverEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgb);
|
||||
|
||||
BOOL Image_ColorizeEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, BOOL premult, COLORREF rgbBottom, COLORREF rgbTop);
|
||||
|
||||
BOOL Image_Premultiply(HBITMAP hbmp, RECT *prcPart);
|
||||
BOOL Image_PremultiplyEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp);
|
||||
|
||||
BOOL Image_Saturate(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale);
|
||||
BOOL Image_SaturateEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale);
|
||||
|
||||
BOOL Image_AdjustAlpha(HBITMAP hbmp, RECT *prcPart, INT n, BOOL fScale);
|
||||
BOOL Image_AdjustAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT n, BOOL fScale);
|
||||
|
||||
BOOL Image_AdjustSaturationAlpha(HBITMAP hbmp, RECT *prcPart, INT nSaturation, INT nAlpha);
|
||||
BOOL Image_AdjustSaturationAlphaEx(BYTE *pPixels, INT bitmapCX, INT bitmapCY, LONG x, LONG y, LONG cx, LONG cy, WORD bpp, INT nSaturation, INT nAlpha);
|
||||
|
||||
COLORREF Color_Blend(COLORREF rgbTop, COLORREF rgbBottom, INT alpha);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_GRAPHICS_HEADER
|
||||
357
Src/auth/Loginbox/imageCache.cpp
Normal file
357
Src/auth/Loginbox/imageCache.cpp
Normal file
@@ -0,0 +1,357 @@
|
||||
#include "./imageCache.h"
|
||||
#include "./imageLoader.h"
|
||||
#include "./graphics.h"
|
||||
#include "./loginBox.h"
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include "../../ombrowser/ifc_omutility.h"
|
||||
#include "../../ombrowser/ifc_omcachemanager.h"
|
||||
#include "../../ombrowser/ifc_omcachegroup.h"
|
||||
#include "../../ombrowser/ifc_omcacherecord.h"
|
||||
|
||||
#include "../api.h"
|
||||
|
||||
LoginImageCache::LoginImageCache(HWND hLoginbox)
|
||||
: ref(1), hwnd(hLoginbox), group(NULL)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
}
|
||||
|
||||
LoginImageCache::~LoginImageCache()
|
||||
{
|
||||
if (NULL != group)
|
||||
{
|
||||
group->Release();
|
||||
}
|
||||
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT LoginImageCache::CreateInstance(HWND hLoginbox, LoginImageCache **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
*instance = NULL;
|
||||
if (NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginImageCache(hLoginbox);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t LoginImageCache::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t LoginImageCache::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int LoginImageCache::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
if (NULL == object) return E_POINTER;
|
||||
|
||||
if (IsEqualIID(interface_guid, IFC_OmCacheCallback))
|
||||
*object = static_cast<ifc_omcachecallback*>(this);
|
||||
else
|
||||
{
|
||||
*object = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *object)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void LoginImageCache::PathChanged(ifc_omcacherecord *record)
|
||||
{
|
||||
HWND hLoginbox;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
hLoginbox = hwnd;
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != hLoginbox && FALSE != IsWindow(hLoginbox))
|
||||
{
|
||||
IMAGECACHERESULT result;
|
||||
result.imageCache = this;
|
||||
result.cacheRecord = record;
|
||||
SendMessage(hLoginbox, NLBM_IMAGECACHED, 0, (LPARAM)&result);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LoginImageCache::Finish()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
ifc_omcachegroup *groupCopy = group;
|
||||
if (NULL != groupCopy)
|
||||
groupCopy->AddRef();
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != groupCopy)
|
||||
{
|
||||
groupCopy->Clear();
|
||||
|
||||
WCHAR szGroup[64] = {0};
|
||||
if (SUCCEEDED(groupCopy->GetName(szGroup, ARRAYSIZE(szGroup))))
|
||||
{
|
||||
waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
|
||||
if (NULL != serviceFactory)
|
||||
{
|
||||
ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
|
||||
if (NULL != omUtility)
|
||||
{
|
||||
ifc_omcachemanager *cacheManager;
|
||||
if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
|
||||
{
|
||||
cacheManager->Delete(szGroup);
|
||||
cacheManager->Release();
|
||||
}
|
||||
omUtility->Release();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
groupCopy->Release();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT LoginImageCache::InitGroup()
|
||||
{
|
||||
HRESULT hr;
|
||||
EnterCriticalSection(&lock);
|
||||
if (NULL != group)
|
||||
{
|
||||
hr = S_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = S_OK;
|
||||
waServiceFactory *serviceFactory = WASABI_API_SVC->service_getServiceByGuid(IFC_OmUtility);
|
||||
if (NULL != serviceFactory)
|
||||
{
|
||||
ifc_omutility *omUtility = (ifc_omutility*)serviceFactory->getInterface();
|
||||
if (NULL != omUtility)
|
||||
{
|
||||
ifc_omcachemanager *cacheManager;
|
||||
if (SUCCEEDED(omUtility->GetCacheManager(&cacheManager)))
|
||||
{
|
||||
if (FAILED(cacheManager->Find(L"loginBox", TRUE, &group, NULL)))
|
||||
group = NULL;
|
||||
cacheManager->Release();
|
||||
}
|
||||
omUtility->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == group)
|
||||
hr = E_NOINTERFACE;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginImageCache::GetImageListIndex(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
|
||||
{
|
||||
if (NULL == pszPath || L'\0' == *pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
WCHAR szBuffer[2048] = {0};
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
BOOL fCreated = FALSE;
|
||||
|
||||
hr = InitGroup();
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
||||
ifc_omcacherecord *record;
|
||||
hr = group->Find(pszPath, TRUE, &record, &fCreated);
|
||||
if (S_OK != hr)
|
||||
{
|
||||
if (S_FALSE == hr)
|
||||
hr = E_PENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
record->RegisterCallback(this);
|
||||
|
||||
hr = record->GetPath(szBuffer, ARRAYSIZE(szBuffer));
|
||||
record->Release();
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
return GetImageListIndexLocal(szBuffer, himl, index, indexActive, indexDisabled);
|
||||
}
|
||||
|
||||
HRESULT LoginImageCache::GetImageListIndexLocal(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled)
|
||||
{
|
||||
if (NULL == himl || NULL == pszPath || L'\0' == *pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (NULL == index && NULL == indexActive && NULL == indexDisabled)
|
||||
return E_INVALIDARG;
|
||||
|
||||
INT destWidth, destHeight;
|
||||
if (0 == ImageList_GetIconSize(himl, &destWidth, &destHeight))
|
||||
return E_FAIL;
|
||||
|
||||
INT imageWidth, imageHeight;
|
||||
HBITMAP hbmp = ImageLoader_LoadBitmap(NULL, pszPath, FALSE, &imageWidth, &imageHeight);
|
||||
if (NULL == hbmp)
|
||||
return E_FAIL;
|
||||
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
RECT imageRect;
|
||||
SetRect(&imageRect, 0, 0, imageWidth, imageHeight);
|
||||
|
||||
if (NULL != indexActive)
|
||||
{
|
||||
*indexActive = ImageList_Add(himl, hbmp, NULL);
|
||||
if (((UINT)-1) == *indexActive) hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (NULL != index)
|
||||
{
|
||||
Image_AdjustSaturationAlpha(hbmp, &imageRect, -150, -100);
|
||||
|
||||
*index = ImageList_Add(himl, hbmp, NULL);
|
||||
if (((UINT)-1) == *index) hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (NULL != indexDisabled)
|
||||
{
|
||||
Image_AdjustSaturationAlpha(hbmp, &imageRect, -600, -600);
|
||||
|
||||
*indexDisabled = ImageList_Add(himl, hbmp, NULL);
|
||||
if (((UINT)-1) == *indexDisabled) hr = E_FAIL;
|
||||
}
|
||||
|
||||
if (NULL != hbmp)
|
||||
DeleteObject(hbmp);
|
||||
|
||||
return hr;
|
||||
|
||||
}
|
||||
|
||||
HBITMAP LoginImageCache::AdjustBitmapSize(HBITMAP hBitmap, INT forceWidth, INT forceHeight)
|
||||
{
|
||||
BITMAP bm;
|
||||
if (sizeof(BITMAP) != GetObject(hBitmap, sizeof(bm), &bm))
|
||||
return NULL;
|
||||
if (bm.bmHeight < 0) bm.bmHeight = -bm.bmHeight;
|
||||
|
||||
if (bm.bmWidth == forceWidth && bm.bmHeight == forceHeight)
|
||||
return hBitmap;
|
||||
|
||||
HDC hdc, hdcSrc, hdcDst;
|
||||
hdc = GetDCEx(NULL, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
|
||||
if (NULL == hdc) return NULL;
|
||||
|
||||
hdcSrc = CreateCompatibleDC(hdc);
|
||||
hdcDst = CreateCompatibleDC(hdc);
|
||||
|
||||
BITMAPINFOHEADER bhi;
|
||||
ZeroMemory(&bhi, sizeof(bhi));
|
||||
bhi.biSize = sizeof(bhi);
|
||||
bhi.biCompression = BI_RGB;
|
||||
bhi.biBitCount = 32;
|
||||
bhi.biPlanes = 1;
|
||||
bhi.biWidth = forceWidth;
|
||||
bhi.biHeight = -forceHeight;
|
||||
|
||||
UINT *pixelData;
|
||||
HBITMAP hbmpDst = CreateDIBSection(NULL, (LPBITMAPINFO)&bhi, DIB_RGB_COLORS, (void**)&pixelData, NULL, 0);
|
||||
if (NULL != hbmpDst)
|
||||
{
|
||||
for (INT i = 0; i < forceWidth * forceHeight; i++)
|
||||
pixelData[i] = 0x00FFFFFF;
|
||||
}
|
||||
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
if (NULL != hdcSrc && NULL != hdcDst && NULL != hbmpDst)
|
||||
{
|
||||
HBITMAP hbmpSrcOrig = (HBITMAP)SelectObject(hdcSrc, hBitmap);
|
||||
HBITMAP hbmpDstOrig = (HBITMAP)SelectObject(hdcDst, hbmpDst);
|
||||
|
||||
BOOL result;
|
||||
if (bm.bmWidth <= forceWidth && bm.bmHeight <= forceHeight)
|
||||
{
|
||||
BLENDFUNCTION bf;
|
||||
bf.BlendOp = AC_SRC_OVER;
|
||||
bf.BlendFlags = 0;
|
||||
bf.SourceConstantAlpha = 255;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
result = GdiAlphaBlend(hdcDst, (forceWidth - bm.bmWidth)/2, (forceHeight - bm.bmHeight)/2,
|
||||
bm.bmWidth, bm.bmHeight, hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, bf);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetStretchBltMode(hdcDst, HALFTONE);
|
||||
result = StretchBlt(hdcDst, 0, 0, forceWidth, forceHeight,
|
||||
hdcSrc, 0, 0, bm.bmWidth, bm.bmHeight, SRCCOPY);
|
||||
}
|
||||
|
||||
|
||||
if(FALSE != result)
|
||||
{
|
||||
hBitmap = hbmpDst;
|
||||
hbmpDst = NULL;
|
||||
}
|
||||
else
|
||||
hBitmap = NULL;
|
||||
|
||||
SelectObject(hdcSrc, hbmpSrcOrig);
|
||||
SelectObject(hdcDst, hbmpDstOrig);
|
||||
}
|
||||
else
|
||||
{
|
||||
hBitmap = NULL;
|
||||
}
|
||||
|
||||
if (NULL != hdcDst) DeleteDC(hdcDst);
|
||||
if (NULL != hdcSrc) DeleteDC(hdcSrc);
|
||||
if (NULL != hbmpDst) DeleteObject(hbmpDst);
|
||||
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
#define CBCLASS LoginImageCache
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef)
|
||||
CB(RELEASE, Release)
|
||||
CB(QUERYINTERFACE, QueryInterface)
|
||||
VCB(API_PATHCHANGED, PathChanged)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
53
Src/auth/Loginbox/imageCache.h
Normal file
53
Src/auth/Loginbox/imageCache.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_IMAGECACHE_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_IMAGECACHE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../ombrowser/ifc_omcachecallback.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
class ifc_omcachegroup;
|
||||
class ifc_omcacherecord;
|
||||
|
||||
class LoginImageCache : public ifc_omcachecallback
|
||||
{
|
||||
protected:
|
||||
LoginImageCache(HWND hLoginbox);
|
||||
~LoginImageCache();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(HWND hLoginbox, LoginImageCache **instance);
|
||||
|
||||
public:
|
||||
/* Dispatchable */
|
||||
size_t AddRef();
|
||||
size_t Release();
|
||||
int QueryInterface(GUID interface_guid, void **object);
|
||||
|
||||
/* ifc_omcachecallback */
|
||||
void PathChanged(ifc_omcacherecord *record);
|
||||
|
||||
void Finish();
|
||||
|
||||
HRESULT GetImageListIndex(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled);
|
||||
HRESULT GetImageListIndexLocal(LPCWSTR pszPath, HIMAGELIST himl, UINT *index, UINT *indexActive, UINT *indexDisabled);
|
||||
|
||||
private:
|
||||
HRESULT InitGroup();
|
||||
HBITMAP AdjustBitmapSize(HBITMAP hBitmap, INT forceWidth, INT forceHeight);
|
||||
protected:
|
||||
size_t ref;
|
||||
HWND hwnd;
|
||||
ifc_omcachegroup *group;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
private:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
#endif // NULLSOFT_AUTH_LOGINBOX_IMAGECACHE_HEADER
|
||||
331
Src/auth/Loginbox/imageLoader.cpp
Normal file
331
Src/auth/Loginbox/imageLoader.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
#include "./imageLoader.h"
|
||||
#include "./common.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
#include <shlwapi.h>
|
||||
|
||||
template <class api_T>
|
||||
void ImageLoader_ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
|
||||
{
|
||||
if (WASABI_API_SVC)
|
||||
{
|
||||
waServiceFactory *factory = WASABI_API_SVC->service_getServiceByGuid(factoryGUID_t);
|
||||
if (factory)
|
||||
api_t = (api_T *)factory->getInterface();
|
||||
}
|
||||
}
|
||||
|
||||
typedef BOOL (CALLBACK *IMAGEDATAPROCESSOR)(const void * /*data*/, size_t /*dataSize*/, ULONG_PTR /*param*/);
|
||||
|
||||
|
||||
typedef struct __LOADDATAPARAM
|
||||
{
|
||||
BOOL premultiply;
|
||||
INT cx;
|
||||
INT cy;
|
||||
void *pixels;
|
||||
} LOADDATAPARAM;
|
||||
|
||||
typedef struct __GETDIMENSIONPARAM
|
||||
{
|
||||
INT cx;
|
||||
INT cy;
|
||||
} GETDIMENSIONPARAM;
|
||||
|
||||
static BOOL CALLBACK ImageLoader_LoadDataCallback(const void *data, size_t size, ULONG_PTR param)
|
||||
{
|
||||
LOADDATAPARAM *loadParam = (LOADDATAPARAM*)param;
|
||||
if (NULL == loadParam) return FALSE;
|
||||
|
||||
if (NULL == WASABI_API_PNGLOADER)
|
||||
{
|
||||
ImageLoader_ServiceBuild(WASABI_API_PNGLOADER, pngLoaderGUID);
|
||||
if (NULL == WASABI_API_PNGLOADER)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
loadParam->pixels = (FALSE == loadParam->premultiply) ?
|
||||
WASABI_API_PNGLOADER->loadImageData(data, (INT)size, &loadParam->cx, &loadParam->cy) :
|
||||
WASABI_API_PNGLOADER->loadImage(data, (INT)size, &loadParam->cx, &loadParam->cy);
|
||||
|
||||
return (NULL != loadParam->pixels);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK ImageLoader_GetDimensionsCallback(const void *data, size_t size, ULONG_PTR param)
|
||||
{
|
||||
GETDIMENSIONPARAM *dimensionParam = (GETDIMENSIONPARAM*)param;
|
||||
if (NULL == dimensionParam) return FALSE;
|
||||
|
||||
if (NULL == WASABI_API_PNGLOADER)
|
||||
{
|
||||
ImageLoader_ServiceBuild(WASABI_API_PNGLOADER, pngLoaderGUID);
|
||||
if (NULL == WASABI_API_PNGLOADER)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return WASABI_API_PNGLOADER->getDimensions(data, (INT)size, &dimensionParam->cx, &dimensionParam->cy);
|
||||
}
|
||||
|
||||
static BOOL ImageLoader_ProcessResource(HINSTANCE hInstance, LPCWSTR pszName, LPCWSTR pszType, IMAGEDATAPROCESSOR processor, ULONG_PTR param)
|
||||
{
|
||||
HRSRC res = FindResourceW(hInstance, pszName, pszType);
|
||||
if (NULL == res) return FALSE;
|
||||
|
||||
BOOL fSucceeded = FALSE;
|
||||
HANDLE handle = LoadResource(hInstance, res);
|
||||
if (NULL != handle)
|
||||
{
|
||||
UINT resourceSize = SizeofResource(hInstance, res);
|
||||
if (0 != resourceSize)
|
||||
{
|
||||
void *resourceData = LockResource(handle);
|
||||
if (NULL != resourceData)
|
||||
fSucceeded = processor(resourceData, resourceSize, param);
|
||||
}
|
||||
FreeResource(handle);
|
||||
}
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
static HRESULT ImageLoader_ParseResProtocol(LPWSTR pszAddress, LPCWSTR defaultType, HINSTANCE *module, LPCWSTR *resourceName, LPCWSTR *resourceType)
|
||||
{
|
||||
if (NULL == module || NULL == resourceName || NULL == resourceType)
|
||||
return E_POINTER;
|
||||
|
||||
if (NULL == pszAddress || L'\0' == *pszAddress)
|
||||
return E_INVALIDARG;
|
||||
|
||||
INT cchAddress = lstrlenW(pszAddress);
|
||||
const WCHAR szPrefix[] = L"res://";
|
||||
INT cchPrefix = ARRAYSIZE(szPrefix) - 1;
|
||||
if (cchAddress <= cchPrefix)
|
||||
return S_FALSE;
|
||||
|
||||
if (CSTR_EQUAL != CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, pszAddress, cchPrefix, szPrefix, cchPrefix))
|
||||
return S_FALSE;
|
||||
|
||||
pszAddress += cchPrefix;
|
||||
cchAddress -= cchPrefix;
|
||||
|
||||
LPWSTR resType = NULL;
|
||||
LPWSTR resName = NULL;
|
||||
|
||||
LPWSTR p = pszAddress + cchAddress;
|
||||
while (p != pszAddress && L'/' != *p) p--;
|
||||
if (p != pszAddress && p < (pszAddress + cchAddress))
|
||||
{
|
||||
resName = p + 1;
|
||||
*p = L'\0';
|
||||
p--;
|
||||
}
|
||||
|
||||
if (NULL == resName || L'\0' == *resName)
|
||||
return E_FAIL;
|
||||
|
||||
|
||||
while (p != pszAddress && L'/' != *p) p--;
|
||||
if (p != pszAddress && p < resName)
|
||||
{
|
||||
resType = p + 1;
|
||||
if (L'\0' == *resType)
|
||||
{
|
||||
resType = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
resType = p + 1;
|
||||
*p = L'\0';
|
||||
p--;
|
||||
}
|
||||
}
|
||||
|
||||
HINSTANCE hModule;
|
||||
hModule = LoadLibraryExW(pszAddress, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
|
||||
if (NULL == hModule)
|
||||
{
|
||||
UINT errorCode = GetLastError();
|
||||
if (NULL != resType)
|
||||
{
|
||||
*(resType - 1) = L'/';
|
||||
resType = NULL;
|
||||
hModule = LoadLibraryExW(pszAddress, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
|
||||
if (NULL == hModule) errorCode = GetLastError();
|
||||
}
|
||||
|
||||
if (ERROR_SUCCESS != errorCode)
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
if (NULL == resType)
|
||||
resType = (LPWSTR)defaultType;
|
||||
|
||||
if (NULL != resType && FALSE == IS_INTRESOURCE(resType) && L'#' == *resType)
|
||||
{
|
||||
INT typeId;
|
||||
if (FALSE != StrToIntExW(resType + 1, STIF_DEFAULT, &typeId))
|
||||
resType = MAKEINTRESOURCEW(typeId);
|
||||
}
|
||||
|
||||
if (NULL != resName && FALSE == IS_INTRESOURCE(resName) && L'#' == *resName)
|
||||
{
|
||||
INT nameId;
|
||||
if (FALSE != StrToIntExW(resName + 1, STIF_DEFAULT, &nameId))
|
||||
resName = MAKEINTRESOURCEW(nameId);
|
||||
}
|
||||
|
||||
*module = hModule;
|
||||
*resourceName = resName;
|
||||
*resourceType = resType;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static BOOL ImageLoader_ProcessFile(LPCWSTR pszPath, IMAGEDATAPROCESSOR processor, ULONG_PTR param)
|
||||
{
|
||||
HINSTANCE resModule;
|
||||
LPCWSTR resName, resType;
|
||||
|
||||
BOOL fSucceeded = FALSE;
|
||||
|
||||
LPWSTR name = LoginBox_CopyString(pszPath);
|
||||
HRESULT hr = ImageLoader_ParseResProtocol(name, RT_RCDATA, &resModule, &resName, &resType);
|
||||
if (S_OK == hr)
|
||||
{
|
||||
fSucceeded = ImageLoader_ProcessResource(resModule, resName, resType, processor, param);
|
||||
LoginBox_FreeString(name);
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
LoginBox_FreeString(name);
|
||||
|
||||
if (FAILED(hr))
|
||||
return FALSE;
|
||||
|
||||
HANDLE hFile = CreateFileW(pszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
return FALSE;
|
||||
|
||||
UINT resourceSize = GetFileSize(hFile, NULL);
|
||||
if (INVALID_FILE_SIZE != resourceSize)
|
||||
{
|
||||
void *resourceData = malloc(resourceSize);
|
||||
if (NULL != resourceData)
|
||||
{
|
||||
DWORD readed = 0;
|
||||
if (0 != ReadFile(hFile, resourceData, resourceSize, &readed, NULL) || resourceSize != readed)
|
||||
fSucceeded = processor(resourceData, resourceSize, param);
|
||||
free(resourceData);
|
||||
}
|
||||
}
|
||||
CloseHandle(hFile);
|
||||
|
||||
return fSucceeded;
|
||||
}
|
||||
|
||||
void *ImageLoader_LoadData(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, INT *widthOut, INT *heightOut)
|
||||
{
|
||||
BOOL fSucceeded;
|
||||
LOADDATAPARAM param;
|
||||
param.premultiply = fPremultiply;
|
||||
if (NULL == hInstance && !IS_INTRESOURCE(pszName))
|
||||
fSucceeded = ImageLoader_ProcessFile(pszName, ImageLoader_LoadDataCallback, (ULONG_PTR)¶m);
|
||||
else
|
||||
fSucceeded = ImageLoader_ProcessResource(hInstance, pszName, RT_RCDATA, ImageLoader_LoadDataCallback, (ULONG_PTR)¶m);
|
||||
|
||||
if (FALSE == fSucceeded)
|
||||
{
|
||||
if (NULL != widthOut) *widthOut = 0;
|
||||
if (NULL != heightOut) *heightOut = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (NULL != widthOut) *widthOut = param.cx;
|
||||
if (NULL != heightOut) *heightOut = param.cy;
|
||||
|
||||
return param.pixels;
|
||||
}
|
||||
|
||||
void ImageLoader_FreeData(void *data)
|
||||
{
|
||||
if (NULL == data)
|
||||
return;
|
||||
|
||||
if (NULL == WASABI_API_MEMMNGR)
|
||||
{
|
||||
ImageLoader_ServiceBuild(WASABI_API_MEMMNGR, memMgrApiServiceGuid);
|
||||
if (NULL == WASABI_API_MEMMNGR) return;
|
||||
}
|
||||
|
||||
WASABI_API_MEMMNGR->sysFree(data);
|
||||
}
|
||||
|
||||
HBITMAP ImageLoader_LoadBitmapEx(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, BITMAPINFOHEADER *headerInfo, void **dataOut)
|
||||
{
|
||||
INT imageCX, imageCY;
|
||||
|
||||
void *data = ImageLoader_LoadData(hInstance, pszName, fPremultiply, &imageCX, &imageCY);
|
||||
if (NULL == data) return NULL;
|
||||
|
||||
ZeroMemory(headerInfo, sizeof(BITMAPINFOHEADER));
|
||||
headerInfo->biSize = sizeof(BITMAPINFOHEADER);
|
||||
headerInfo->biCompression = BI_RGB;
|
||||
headerInfo->biBitCount = 32;
|
||||
headerInfo->biPlanes = 1;
|
||||
headerInfo->biWidth = imageCX;
|
||||
headerInfo->biHeight = -imageCY;
|
||||
|
||||
void *pixelData;
|
||||
HBITMAP bitmap = CreateDIBSection(NULL, (LPBITMAPINFO)headerInfo, DIB_RGB_COLORS, &pixelData, NULL, 0);
|
||||
if (NULL != bitmap)
|
||||
{
|
||||
if (NULL != dataOut) *dataOut = pixelData;
|
||||
CopyMemory(pixelData, data, headerInfo->biWidth * abs(headerInfo->biHeight) * sizeof(DWORD));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != dataOut) *dataOut = NULL;
|
||||
}
|
||||
|
||||
ImageLoader_FreeData(data);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
HBITMAP ImageLoader_LoadBitmap(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, INT *widthOut, INT *heightOut)
|
||||
{
|
||||
BITMAPINFOHEADER header;
|
||||
HBITMAP bitmap = ImageLoader_LoadBitmapEx(hInstance, pszName, fPremultiply, &header, NULL);
|
||||
if (NULL != bitmap)
|
||||
{
|
||||
if (NULL != widthOut) *widthOut = header.biWidth;
|
||||
if (NULL != heightOut) *heightOut = header.biHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != widthOut) *widthOut = 0;
|
||||
if (NULL != heightOut) *heightOut = 0;
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
BOOL ImageLoader_GetDimensions(HINSTANCE hInstance, LPCWSTR pszName, INT *widthOut, INT *heightOut)
|
||||
{
|
||||
BOOL fSucceeded;
|
||||
GETDIMENSIONPARAM param;
|
||||
if (NULL == hInstance && !IS_INTRESOURCE(pszName))
|
||||
fSucceeded = ImageLoader_ProcessFile(pszName, ImageLoader_GetDimensionsCallback, (ULONG_PTR)¶m);
|
||||
else
|
||||
fSucceeded = ImageLoader_ProcessResource(hInstance, pszName, RT_RCDATA, ImageLoader_GetDimensionsCallback, (ULONG_PTR)¶m);
|
||||
|
||||
if (FALSE == fSucceeded)
|
||||
{
|
||||
if (NULL != widthOut) *widthOut = 0;
|
||||
if (NULL != heightOut) *heightOut = 0;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NULL != widthOut) *widthOut = param.cx;
|
||||
if (NULL != heightOut) *heightOut = param.cy;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
16
Src/auth/Loginbox/imageLoader.h
Normal file
16
Src/auth/Loginbox/imageLoader.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_IMAGELOADER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_IMAGELOADER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
void *ImageLoader_LoadData(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, INT *widthOut, INT *heightOut);
|
||||
void ImageLoader_FreeData(void *data);
|
||||
HBITMAP ImageLoader_LoadBitmapEx(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, BITMAPINFOHEADER *headerInfo, void **dataOut);
|
||||
HBITMAP ImageLoader_LoadBitmap(HINSTANCE hInstance, LPCWSTR pszName, BOOL fPremultiply, INT *widthOut, INT *heightOut);
|
||||
BOOL ImageLoader_GetDimensions(HINSTANCE hInstance, LPCWSTR pszName, INT *widthOut, INT *heightOut);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_IMAGELOADER_HEADER
|
||||
36
Src/auth/Loginbox/loginCommand.h
Normal file
36
Src/auth/Loginbox/loginCommand.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINCOMMAND_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINCOMMAND_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "./loginResult.h"
|
||||
|
||||
class LoginData;
|
||||
class LoginCredentials;
|
||||
|
||||
class __declspec(novtable) LoginCommand
|
||||
{
|
||||
protected:
|
||||
LoginCommand() {}
|
||||
~LoginCommand() {}
|
||||
|
||||
public:
|
||||
virtual ULONG AddRef() = 0;
|
||||
virtual ULONG Release() = 0;
|
||||
|
||||
virtual HRESULT GetType(GUID *commandUid) = 0;
|
||||
|
||||
virtual HRESULT SetParameter(LPCWSTR pszKey, LPCWSTR pszValue) = 0;
|
||||
virtual HRESULT IsValid() = 0;
|
||||
virtual HRESULT IsIdentical(LoginCommand *test) = 0;
|
||||
|
||||
virtual HRESULT BeginLogin(LoginData *data, LoginResult::Callback callback, void *user, LoginResult **result) = 0;
|
||||
virtual HRESULT EndLogin(LoginResult *result, INT *authCode, LoginCredentials **credentials) = 0;
|
||||
virtual HRESULT RequestAbort(LoginResult *result, BOOL drop) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINCOMMAND_HEADER
|
||||
124
Src/auth/Loginbox/loginConfig.cpp
Normal file
124
Src/auth/Loginbox/loginConfig.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
#include "./loginConfig.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define BOOL2HRESULT(__result) ((FALSE != (__result)) ? S_OK : S_FALSE)
|
||||
|
||||
|
||||
LoginConfig::LoginConfig()
|
||||
: ref(1), configPath(NULL), pathValidated(FALSE), buffer(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LoginConfig::~LoginConfig()
|
||||
{
|
||||
LoginBox_FreeAnsiString(configPath);
|
||||
LoginBox_FreeString((LPWSTR)buffer);
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginConfig::CreateInstance(LoginConfig **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
WCHAR szFile[MAX_PATH] = {0};
|
||||
HRESULT hr;
|
||||
|
||||
hr = LoginBox_GetConfigPath(szFile, FALSE);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
if (FALSE == PathAppend(szFile, L"loginBox.ini"))
|
||||
return E_UNEXPECTED;
|
||||
|
||||
LPSTR configPath;
|
||||
hr = LoginBox_WideCharToMultiByte(CP_UTF8, 0, szFile, -1, NULL, NULL, &configPath);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
*instance = new LoginConfig();
|
||||
if (NULL == *instance)
|
||||
{
|
||||
LoginBox_FreeAnsiString(configPath);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*instance)->configPath = configPath;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginConfig::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginConfig::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginConfig::GetPath(LPCSTR *ppPath)
|
||||
{
|
||||
if (NULL == ppPath)
|
||||
return E_POINTER;
|
||||
|
||||
*ppPath = configPath;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
DWORD LoginConfig::ReadAnsiStr(LPCSTR lpSectionName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize)
|
||||
{
|
||||
return GetPrivateProfileStringA(lpSectionName, lpKeyName, lpDefault, lpReturnedString, nSize, configPath);
|
||||
}
|
||||
|
||||
UINT LoginConfig::ReadInt(LPCSTR lpSectionName, LPCSTR lpKeyName, INT nDefault)
|
||||
{
|
||||
return GetPrivateProfileIntA(lpSectionName, lpKeyName, nDefault, configPath);
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginConfig::WriteAnsiStr(LPCSTR lpSectionName, LPCSTR lpKeyName, LPCSTR lpString)
|
||||
{
|
||||
if (NULL == configPath || L'\0' == *configPath)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (FALSE == pathValidated)
|
||||
{
|
||||
LPWSTR pszTest;
|
||||
if (SUCCEEDED(LoginBox_MultiByteToWideChar(CP_UTF8, 0, configPath, -1, &pszTest)))
|
||||
{
|
||||
PathRemoveFileSpec(pszTest);
|
||||
LoginBox_EnsurePathExist(pszTest);
|
||||
pathValidated = TRUE;
|
||||
|
||||
LoginBox_FreeString(pszTest);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != WritePrivateProfileStringA(lpSectionName, lpKeyName, lpString, configPath))
|
||||
return S_OK;
|
||||
|
||||
DWORD errorCode = GetLastError();
|
||||
return HRESULT_FROM_WIN32(errorCode);
|
||||
}
|
||||
|
||||
HRESULT LoginConfig::WriteInt(LPCSTR lpSectionName, LPCSTR lpKeyName, INT nValue)
|
||||
{
|
||||
CHAR szBuffer[32] = {0};
|
||||
HRESULT hr = StringCchPrintfA(szBuffer, ARRAYSIZE(szBuffer), "%d", nValue);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
return WriteAnsiStr(lpSectionName, lpKeyName, szBuffer);
|
||||
}
|
||||
40
Src/auth/Loginbox/loginConfig.h
Normal file
40
Src/auth/Loginbox/loginConfig.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_CONFIG_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_CONFIG_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginConfig
|
||||
{
|
||||
protected:
|
||||
LoginConfig();
|
||||
~LoginConfig();
|
||||
public:
|
||||
static HRESULT CreateInstance(LoginConfig **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
public:
|
||||
HRESULT GetPath(LPCSTR *ppPath);
|
||||
DWORD ReadAnsiStr(LPCSTR lpSectionName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, DWORD nSize);
|
||||
UINT ReadInt(LPCSTR lpSectionName, LPCSTR lpKeyName, INT nDefault);
|
||||
HRESULT WriteAnsiStr(LPCSTR lpSectionName, LPCSTR lpKeyName, LPCSTR lpString);
|
||||
HRESULT WriteInt(LPCSTR lpSectionName, LPCSTR lpKeyName, INT nValue);
|
||||
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
LPSTR configPath;
|
||||
BOOL pathValidated;
|
||||
void *buffer;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_CONFIG_HEADER
|
||||
108
Src/auth/Loginbox/loginCredentials.cpp
Normal file
108
Src/auth/Loginbox/loginCredentials.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "./loginCredentials.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include "../api_auth.h"
|
||||
|
||||
|
||||
LoginCredentials::LoginCredentials(const GUID *pRealm, LPCWSTR pszName, LPCSTR pszSession, LPCSTR pszToken, __time64_t tExpire)
|
||||
: ref(1), username(NULL), sessionKey(NULL), token(NULL)
|
||||
{
|
||||
realm = (NULL == pRealm) ? GUID_NULL : *pRealm;
|
||||
username = LoginBox_CopyString(pszName);
|
||||
sessionKey = LoginBox_CopyAnsiString(pszSession);
|
||||
token = LoginBox_CopyAnsiString(pszToken);
|
||||
expire = tExpire;
|
||||
}
|
||||
|
||||
LoginCredentials::~LoginCredentials()
|
||||
{
|
||||
LoginBox_FreeStringSecure(username);
|
||||
LoginBox_FreeAnsiStringSecure(sessionKey);
|
||||
LoginBox_FreeAnsiStringSecure(token);
|
||||
}
|
||||
|
||||
HRESULT LoginCredentials::CreateInstance(const GUID *pRealm, LPCWSTR pszName, LPCSTR pszSession, LPCSTR pszToken, __time64_t tExpire, LoginCredentials **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = new LoginCredentials(pRealm, pszName, pszSession, pszToken, tExpire);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginCredentials::CreateFromAuth(api_auth *authApi, const GUID *pRealm, LoginCredentials **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
if (NULL == authApi) return E_INVALIDARG;
|
||||
|
||||
const size_t sessionKeyMax(8192), tokenMax(8192), usernameMax(8192);
|
||||
LPSTR sessionKey = LoginBox_MallocAnsiString(sessionKeyMax);
|
||||
LPSTR token = LoginBox_MallocAnsiString(tokenMax);
|
||||
LPWSTR username = LoginBox_MallocString(usernameMax);
|
||||
__time64_t expire;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL == sessionKey || NULL == token || NULL == username)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
INT result = authApi->GetCredentials((NULL != pRealm) ? *pRealm : GUID_NULL, sessionKey, sessionKeyMax, token, tokenMax, username, usernameMax, &expire);
|
||||
if (AUTH_SUCCESS == result)
|
||||
{
|
||||
hr = CreateInstance(pRealm, username, sessionKey, token, expire, instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
LoginBox_FreeAnsiStringSecure(sessionKey);
|
||||
LoginBox_FreeAnsiStringSecure(token);
|
||||
LoginBox_FreeStringSecure(username);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
UINT LoginCredentials::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
UINT LoginCredentials::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
GUID LoginCredentials::GetRealm()
|
||||
{
|
||||
return realm;
|
||||
}
|
||||
|
||||
__time64_t LoginCredentials::GetExpiration()
|
||||
{
|
||||
return expire;
|
||||
}
|
||||
|
||||
LPCWSTR LoginCredentials::GetUsername()
|
||||
{
|
||||
return username;
|
||||
}
|
||||
LPCSTR LoginCredentials::GetSessionKey()
|
||||
{
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
LPCSTR LoginCredentials::GetToken()
|
||||
{
|
||||
return token;
|
||||
}
|
||||
42
Src/auth/Loginbox/loginCredentials.h
Normal file
42
Src/auth/Loginbox/loginCredentials.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_CREDENTIALS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_CREDENTIALS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class api_auth;
|
||||
|
||||
class LoginCredentials
|
||||
{
|
||||
protected:
|
||||
LoginCredentials(const GUID *pRealm, LPCWSTR pszName, LPCSTR pszSession, LPCSTR pszToken, __time64_t tExpire);
|
||||
~LoginCredentials();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(const GUID *pRealm, LPCWSTR pszName, LPCSTR pszSession, LPCSTR pszToken, __time64_t tExpire, LoginCredentials **instance);
|
||||
static HRESULT CreateFromAuth(api_auth *authApi, const GUID *pRealm, LoginCredentials **instance);
|
||||
|
||||
public:
|
||||
UINT AddRef();
|
||||
UINT Release();
|
||||
|
||||
GUID GetRealm();
|
||||
LPCWSTR GetUsername();
|
||||
LPCSTR GetSessionKey();
|
||||
LPCSTR GetToken();
|
||||
__time64_t GetExpiration();
|
||||
|
||||
private:
|
||||
ULONG ref;
|
||||
GUID realm;
|
||||
LPWSTR username;
|
||||
LPSTR sessionKey;
|
||||
LPSTR token;
|
||||
__time64_t expire;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_CREDENTIALS_HEADER
|
||||
544
Src/auth/Loginbox/loginCurtain.cpp
Normal file
544
Src/auth/Loginbox/loginCurtain.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
#include "./loginCurtain.h"
|
||||
#include "./loginPopup.h"
|
||||
#include "./common.h"
|
||||
#include "./graphics.h"
|
||||
#include "./imageLoader.h"
|
||||
#include "../resource.h"
|
||||
#include "../api.h"
|
||||
|
||||
|
||||
#define NWC_LOGINCURTAIN L"NullsoftLoginCurtain"
|
||||
|
||||
typedef struct __LOGINCURTAINCREATEPARAM
|
||||
{
|
||||
HWND owner;
|
||||
} LOGINCURTAINCREATEPARAM;
|
||||
|
||||
#define NLPF_IMAGEINVALID 0x00000001
|
||||
|
||||
typedef struct __LOGINCURTAIN
|
||||
{
|
||||
HWND owner;
|
||||
HBITMAP bkImage;
|
||||
UINT flags;
|
||||
UINT childCount;
|
||||
} LOGINCURTAIN;
|
||||
|
||||
typedef struct __DRAWBORDERPARAM
|
||||
{
|
||||
HWND hParent;
|
||||
RECT rect;
|
||||
HDC hdc;
|
||||
HDC hdcSrc;
|
||||
HBITMAP bitmapFrame;
|
||||
HBITMAP bitmapOrig;
|
||||
BLENDFUNCTION blendFunc;
|
||||
} DRAWBORDERPARAM;
|
||||
|
||||
|
||||
typedef struct __UPDATEPOSPARAM
|
||||
{
|
||||
HWND hParent;
|
||||
RECT clientRect;
|
||||
RECT childRect;
|
||||
HDWP hdwp;
|
||||
UINT childCount;
|
||||
} UPDATEPOSPARAM;
|
||||
|
||||
typedef struct __EXCLUDERGNPARAM
|
||||
{
|
||||
HWND hParent;
|
||||
HRGN exclude;
|
||||
HRGN tmp;
|
||||
RECT rect;
|
||||
} EXCLUDERGNPARAM;
|
||||
|
||||
#define BACKGROUND_ALPHA 200
|
||||
|
||||
#define GetCurtain(__hwnd) ((LOGINCURTAIN*)(LONG_PTR)(LONGX86)GetWindowLongPtr((__hwnd), 0))
|
||||
|
||||
static LRESULT WINAPI LoginCurtain_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
|
||||
static BOOL LoginCurtain_RegisterClass(HINSTANCE hInstance)
|
||||
{
|
||||
|
||||
WNDCLASSW wc;
|
||||
if (FALSE != GetClassInfo(hInstance, NWC_LOGINCURTAIN, &wc))
|
||||
return TRUE;
|
||||
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
|
||||
wc.lpszClassName = NWC_LOGINCURTAIN;
|
||||
wc.lpfnWndProc = LoginCurtain_WindowProc;
|
||||
wc.style = CS_PARENTDC;
|
||||
wc.cbWndExtra = sizeof(LOGINCURTAIN*);
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
|
||||
return ( 0 != RegisterClassW(&wc));
|
||||
}
|
||||
|
||||
HWND LoginCurtain_CreateWindow(HWND hParent, HWND hOwner)
|
||||
{
|
||||
if (FALSE == LoginCurtain_RegisterClass(WASABI_API_ORIG_HINST))
|
||||
return NULL;
|
||||
|
||||
RECT rect;
|
||||
if (FALSE == GetClientRect(hOwner, &rect))
|
||||
SetRectEmpty(&rect);
|
||||
else
|
||||
MapWindowPoints(hOwner, hParent, (POINT*)&rect, 2);
|
||||
|
||||
LOGINCURTAINCREATEPARAM createParam;
|
||||
createParam.owner = hOwner;
|
||||
|
||||
return CreateWindowEx(WS_EX_CONTROLPARENT, NWC_LOGINCURTAIN, NULL,
|
||||
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | DS_CONTROL,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top,
|
||||
hParent, NULL, WASABI_API_ORIG_HINST, &createParam);
|
||||
|
||||
}
|
||||
|
||||
static BOOL CALLBACK LoginCurtain_ExcludeChildRgnCallback(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
EXCLUDERGNPARAM *param = (EXCLUDERGNPARAM*)lParam;
|
||||
if (NULL == param) return FALSE;
|
||||
|
||||
RECT *r = ¶m->rect;
|
||||
|
||||
if (0 == (WS_VISIBLE & GetWindowStyle(hwnd)) ||
|
||||
param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) ||
|
||||
FALSE == GetWindowRect(hwnd, r))
|
||||
return TRUE;
|
||||
|
||||
MapWindowPoints(HWND_DESKTOP, param->hParent, (POINT*)r, 2);
|
||||
|
||||
if (NULL == param->tmp)
|
||||
{
|
||||
param->tmp = CreateRectRgn(0, 0, 0, 0);
|
||||
if (NULL == param->tmp) return FALSE;
|
||||
}
|
||||
|
||||
if (NULL == param->exclude)
|
||||
{
|
||||
param->exclude = CreateRectRgn(0, 0, 0, 0);
|
||||
if (NULL == param->exclude) return FALSE;
|
||||
}
|
||||
|
||||
INT regionType = GetWindowRgn(hwnd, param->tmp);
|
||||
switch(regionType)
|
||||
{
|
||||
case NULLREGION:
|
||||
SetRectRgn(param->tmp, r->left, r->top, r->right, r->bottom);
|
||||
CombineRgn(param->exclude, param->exclude, param->tmp, RGN_OR);
|
||||
break;
|
||||
case SIMPLEREGION:
|
||||
case COMPLEXREGION:
|
||||
OffsetRgn(param->tmp, r->left, r->top);
|
||||
CombineRgn(param->exclude, param->exclude, param->tmp, RGN_OR);
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void LoginCurtain_ExcludeChildren(HWND hwnd, HDC hdc)
|
||||
{
|
||||
EXCLUDERGNPARAM param;
|
||||
param.hParent = hwnd;
|
||||
param.exclude = NULL;
|
||||
param.tmp = NULL;
|
||||
EnumChildWindows(hwnd, LoginCurtain_ExcludeChildRgnCallback, (LPARAM)¶m);
|
||||
if (NULL != param.exclude)
|
||||
{
|
||||
ExtSelectClipRgn(hdc, param.exclude, RGN_DIFF);
|
||||
DeleteObject(param.exclude);
|
||||
}
|
||||
|
||||
if (NULL != param.tmp)
|
||||
DeleteObject(param.tmp);
|
||||
}
|
||||
|
||||
static BOOL CALLBACK LoginCurtain_DrawWindowBorderCallback(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
DRAWBORDERPARAM *param = (DRAWBORDERPARAM*)lParam;
|
||||
if (NULL == param) return FALSE;
|
||||
|
||||
RECT *r = ¶m->rect;
|
||||
|
||||
if (0 == (WS_VISIBLE & GetWindowStyle(hwnd)) ||
|
||||
param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT) ||
|
||||
FALSE == GetWindowRect(hwnd, r))
|
||||
return TRUE;
|
||||
|
||||
MapWindowPoints(HWND_DESKTOP, param->hParent, (POINT*)r, 2);
|
||||
|
||||
if (NULL == param->bitmapFrame)
|
||||
{
|
||||
INT frameHeight, frameWidth;
|
||||
param->bitmapFrame = ImageLoader_LoadBitmap(WASABI_API_ORIG_HINST, MAKEINTRESOURCE(IDR_POPUPBORDER_IMAGE),
|
||||
TRUE, &frameWidth, &frameHeight);
|
||||
if (NULL == param->bitmapFrame)
|
||||
return FALSE;
|
||||
|
||||
param->hdcSrc = CreateCompatibleDC(param->hdc);
|
||||
if (NULL == param->hdcSrc) return FALSE;
|
||||
|
||||
param->bitmapOrig = (HBITMAP)SelectObject(param->hdcSrc, param->bitmapFrame);
|
||||
|
||||
param->blendFunc.AlphaFormat = AC_SRC_ALPHA;
|
||||
param->blendFunc.BlendFlags = 0;
|
||||
param->blendFunc.BlendOp = AC_SRC_OVER;
|
||||
param->blendFunc.SourceConstantAlpha = 255;
|
||||
}
|
||||
|
||||
r->left -= 14;
|
||||
r->top -= 13;
|
||||
r->right += 17;
|
||||
r->bottom += 19;
|
||||
|
||||
GdiAlphaBlend(param->hdc, r->left, r->top, 26, 26, param->hdcSrc, 0, 0, 26, 26, param->blendFunc);
|
||||
GdiAlphaBlend(param->hdc, r->right - 28, r->top, 28, 26, param->hdcSrc, 27, 0, 28, 26, param->blendFunc);
|
||||
GdiAlphaBlend(param->hdc, r->left, r->bottom - 31, 26, 31, param->hdcSrc, 0, 27, 26, 31, param->blendFunc);
|
||||
GdiAlphaBlend(param->hdc, r->right - 28, r->bottom - 31, 28, 31, param->hdcSrc, 27, 27, 28, 31, param->blendFunc);
|
||||
|
||||
LONG l = (r->right - r->left - (26 + 28));
|
||||
GdiAlphaBlend(param->hdc, r->left + 26, r->top, l, 26, param->hdcSrc, 25, 0, 1, 26, param->blendFunc);
|
||||
GdiAlphaBlend(param->hdc, r->left + 26, r->bottom - 31, l, 31, param->hdcSrc, 25, 27, 1, 31, param->blendFunc);
|
||||
|
||||
l = (r->bottom - r->top - (26 + 31));
|
||||
GdiAlphaBlend(param->hdc, r->left, r->top + 26, 26, l, param->hdcSrc, 0, 28, 26, 1, param->blendFunc);
|
||||
GdiAlphaBlend(param->hdc, r->right - 28, r->top + 26, 28, l, param->hdcSrc, 27, 28, 28, 1, param->blendFunc);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void LoginCurtain_DrawChildBorders(HWND hwnd, HDC hdc)
|
||||
{
|
||||
DRAWBORDERPARAM param;
|
||||
ZeroMemory(¶m, sizeof(param));
|
||||
param.hdc = hdc;
|
||||
param.hParent = hwnd;
|
||||
|
||||
EnumChildWindows(hwnd, LoginCurtain_DrawWindowBorderCallback, (LPARAM)¶m);
|
||||
|
||||
if (NULL != param.hdcSrc)
|
||||
{
|
||||
SelectObject(param.hdcSrc, param.bitmapOrig);
|
||||
DeleteDC(param.hdcSrc);
|
||||
}
|
||||
|
||||
if (NULL != param.bitmapFrame)
|
||||
DeleteObject(param.bitmapFrame);
|
||||
}
|
||||
|
||||
static HBITMAP LoginCurtain_CreateBkImage(HWND hwnd, HDC hdc, HBITMAP hBitmap, HWND hOwner)
|
||||
{
|
||||
RECT rect;
|
||||
if (FALSE == GetClientRect(hwnd, &rect))
|
||||
return NULL;
|
||||
|
||||
LONG width = rect.right - rect.left;
|
||||
LONG height = rect.bottom - rect.top;
|
||||
|
||||
BITMAP bi;
|
||||
|
||||
if (NULL == hBitmap ||
|
||||
sizeof(BITMAP) != GetObject(hBitmap, sizeof(BITMAP), &bi) ||
|
||||
bi.bmWidth < width || bi.bmHeight < height)
|
||||
{
|
||||
if (NULL != hBitmap)
|
||||
DeleteObject(hBitmap);
|
||||
|
||||
BITMAPINFOHEADER header;
|
||||
ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
|
||||
|
||||
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||
header.biCompression = BI_RGB;
|
||||
header.biBitCount = 32;
|
||||
header.biPlanes = 1;
|
||||
header.biWidth = (width + 32);
|
||||
header.biHeight = -(height + 32);
|
||||
|
||||
bi.bmBitsPixel = header.biBitCount;
|
||||
bi.bmWidth = header.biWidth;
|
||||
bi.bmHeight = header.biHeight;
|
||||
bi.bmPlanes = header.biPlanes;
|
||||
|
||||
hBitmap = CreateDIBSection(NULL, (LPBITMAPINFO)&header, DIB_RGB_COLORS, (void**)&bi.bmBits, NULL, 0);
|
||||
if (NULL == hBitmap) return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
bi.bmHeight = -bi.bmHeight;
|
||||
}
|
||||
|
||||
HBRUSH bkBrush = (HBRUSH)SendMessage(hOwner, WM_CTLCOLORDLG, (WPARAM)hdc, (LPARAM)hwnd);
|
||||
|
||||
HBITMAP hbo = (HBITMAP)SelectObject(hdc, hBitmap);
|
||||
|
||||
if (NULL == hOwner)
|
||||
{
|
||||
if (NULL != bkBrush)
|
||||
FillRect(hdc, &rect, bkBrush);
|
||||
else
|
||||
ExtTextOut(hdc, 0, 0, OPAQUE, &rect, NULL, 0, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FALSE == LoginBox_PrintWindow(hOwner, hdc, 0))
|
||||
SendMessage(hOwner, WM_PRINT, (WPARAM)hdc, (LPARAM) (PRF_NONCLIENT | PRF_CLIENT | PRF_CHILDREN | PRF_ERASEBKGND));
|
||||
|
||||
COLORREF rgbBlend = GetDCBrushColor(hdc);
|
||||
if (CLR_INVALID == rgbBlend)
|
||||
rgbBlend = GetBkColor(hdc);
|
||||
rgbBlend |= (BACKGROUND_ALPHA << 24);
|
||||
Image_ColorOverEx((BYTE*)bi.bmBits, bi.bmWidth, bi.bmHeight, 0, 0, width, height, bi.bmBitsPixel, FALSE, rgbBlend);
|
||||
}
|
||||
|
||||
LoginCurtain_DrawChildBorders(hwnd, hdc);
|
||||
|
||||
SelectObject(hdc, hbo);
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
static void LoginCurtain_EraseBkGround(HWND hwnd, HDC hdc, const RECT *prcPaint)
|
||||
{
|
||||
LOGINCURTAIN *curtain = GetCurtain(hwnd);
|
||||
if (NULL == curtain) return;
|
||||
|
||||
HDC hdcSrc = CreateCompatibleDC(hdc);
|
||||
if (NULL == hdcSrc) return;
|
||||
|
||||
|
||||
if (NULL == curtain->bkImage || 0 != (NLPF_IMAGEINVALID & curtain->flags))
|
||||
{
|
||||
HRGN clipRegion = CreateRectRgn(0,0,0,0);
|
||||
if (NULL != clipRegion)
|
||||
{
|
||||
INT regionType = GetClipRgn(hdc, clipRegion);
|
||||
if (1 == regionType)
|
||||
SelectClipRgn(hdcSrc, clipRegion);
|
||||
DeleteObject(clipRegion);
|
||||
}
|
||||
curtain->bkImage = LoginCurtain_CreateBkImage(hwnd, hdcSrc, curtain->bkImage, curtain->owner);
|
||||
curtain->flags &= ~NLPF_IMAGEINVALID;
|
||||
}
|
||||
|
||||
if (NULL != curtain->bkImage)
|
||||
{
|
||||
HBITMAP hbmpOld = (HBITMAP)SelectObject(hdcSrc, curtain->bkImage);
|
||||
BitBlt(hdc, prcPaint->left, prcPaint->top,
|
||||
prcPaint->right - prcPaint->left, prcPaint->bottom - prcPaint->top,
|
||||
hdcSrc, prcPaint->left, prcPaint->top, SRCCOPY);
|
||||
|
||||
SelectObject(hdcSrc, hbmpOld);
|
||||
}
|
||||
|
||||
DeleteDC(hdcSrc);
|
||||
|
||||
}
|
||||
|
||||
static void LoginCurtain_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase)
|
||||
{
|
||||
if (FALSE != fErase)
|
||||
{
|
||||
LoginCurtain_ExcludeChildren(hwnd, hdc);
|
||||
LoginCurtain_EraseBkGround(hwnd, hdc, prcPaint);
|
||||
}
|
||||
}
|
||||
|
||||
static BOOL CALLBACK LoginCurtain_UpdateChildPosCallback(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
UPDATEPOSPARAM *param = (UPDATEPOSPARAM*)lParam;
|
||||
if (NULL == param) return FALSE;
|
||||
|
||||
if (param->hParent != (HWND)(LONG_PTR)GetWindowLongPtr(hwnd, GWLP_HWNDPARENT))
|
||||
return TRUE;
|
||||
|
||||
if (NULL == param->hdwp)
|
||||
{
|
||||
param->hdwp = BeginDeferWindowPos(param->childCount);
|
||||
param->childCount = 0;
|
||||
|
||||
if (NULL == param->hdwp) return FALSE;
|
||||
}
|
||||
|
||||
LONG prevWidth(0), prevHeight(0);
|
||||
if (FALSE != GetWindowRect(hwnd, ¶m->childRect))
|
||||
{
|
||||
prevWidth = param->childRect.right - param->childRect.left;
|
||||
prevHeight = param->childRect.bottom - param->childRect.top;
|
||||
}
|
||||
|
||||
|
||||
if (FALSE != LoginPopup_UpdateWindowPos(hwnd, ¶m->clientRect, ¶m->childRect))
|
||||
{
|
||||
param->hdwp = DeferWindowPos(param->hdwp, hwnd, NULL, param->childRect.left, param->childRect.top,
|
||||
param->childRect.right - param->childRect.left, param->childRect.bottom - param->childRect.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW);
|
||||
|
||||
if (NULL == param->hdwp) return FALSE;
|
||||
|
||||
LONG width = param->childRect.right - param->childRect.left;
|
||||
LONG height = param->childRect.bottom - param->childRect.top;
|
||||
if (width != prevWidth || height != prevHeight)
|
||||
{
|
||||
HRGN clipRgn = CreateRoundRectRgn(0, 0, width, height, 9, 9);
|
||||
SetWindowRgn(hwnd, clipRgn, FALSE);
|
||||
}
|
||||
}
|
||||
param->childCount++;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void LoginCurtain_UpdateLayout(HWND hwnd, BOOL fRedraw)
|
||||
{
|
||||
LOGINCURTAIN *curtain = GetCurtain(hwnd);
|
||||
if (NULL == curtain) return;
|
||||
|
||||
curtain->flags |= NLPF_IMAGEINVALID;
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
|
||||
UPDATEPOSPARAM param;
|
||||
param.hParent = hwnd;
|
||||
param.hdwp = 0;
|
||||
param.childCount = curtain->childCount;
|
||||
|
||||
CopyRect(¶m.clientRect, &clientRect);
|
||||
param.clientRect.left += 15;
|
||||
param.clientRect.top += 14;
|
||||
param.clientRect.right -= 18;
|
||||
param.clientRect.bottom -= 20;
|
||||
|
||||
EnumChildWindows(hwnd, LoginCurtain_UpdateChildPosCallback, (LPARAM)¶m);
|
||||
curtain->childCount = param.childCount;
|
||||
if (NULL != param.hdwp)
|
||||
EndDeferWindowPos(param.hdwp);
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
RedrawWindow(hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN);
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT LoginCurtain_OnCreate(HWND hwnd, CREATESTRUCT* pcs)
|
||||
{
|
||||
LOGINCURTAIN *curtain = (LOGINCURTAIN*)calloc(1, sizeof(LOGINCURTAIN));
|
||||
if (NULL != curtain)
|
||||
{
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
if (!SetWindowLongPtr(hwnd, 0, (LONGX86)(LONG_PTR)curtain) && ERROR_SUCCESS != GetLastError())
|
||||
{
|
||||
free(curtain);
|
||||
curtain = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == curtain)
|
||||
return -1;
|
||||
|
||||
LOGINCURTAINCREATEPARAM *createParam = (LOGINCURTAINCREATEPARAM*)pcs->lpCreateParams;
|
||||
if (NULL != createParam)
|
||||
{
|
||||
curtain->owner = createParam->owner;
|
||||
}
|
||||
|
||||
SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED | SWP_NOREDRAW);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LoginCurtain_OnDestroy(HWND hwnd)
|
||||
{
|
||||
LOGINCURTAIN *curtain = GetCurtain(hwnd);
|
||||
SetWindowLongPtr(hwnd, 0, 0L);
|
||||
if (NULL == curtain) return;
|
||||
|
||||
if (NULL != curtain->bkImage)
|
||||
DeleteObject(curtain->bkImage);
|
||||
|
||||
free(curtain);
|
||||
}
|
||||
|
||||
static void LoginCurtain_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
|
||||
{
|
||||
if (SWP_NOSIZE == ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
||||
return;
|
||||
|
||||
LoginCurtain_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
|
||||
}
|
||||
|
||||
|
||||
static void LoginCurtain_OnPaint(HWND hwnd)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
if (BeginPaint(hwnd, &ps))
|
||||
{
|
||||
if (ps.rcPaint.left != ps.rcPaint.right)
|
||||
LoginCurtain_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoginCurtain_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
|
||||
{
|
||||
RECT clientRect;
|
||||
if (GetClientRect(hwnd, &clientRect))
|
||||
LoginCurtain_Paint(hwnd, hdc, &clientRect, 0 != (PRF_ERASEBKGND & options));
|
||||
}
|
||||
|
||||
static void LoginCurtain_OnParentNotify(HWND hwnd, INT eventId, INT childId, LPARAM eventParam)
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case WM_CREATE:
|
||||
{
|
||||
HWND hChild = (HWND)eventParam;
|
||||
RECT rect;
|
||||
GetWindowRect(hChild, &rect);
|
||||
HRGN clipRgn = CreateRoundRectRgn(0, 0, rect.right - rect.left, rect.bottom - rect.top, 9, 9);
|
||||
SetWindowRgn(hChild, clipRgn, FALSE);
|
||||
}
|
||||
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED );
|
||||
break;
|
||||
|
||||
case WM_DESTROY:
|
||||
{
|
||||
HWND hChild = (HWND)eventParam;
|
||||
SetWindowLongPtr(hChild, GWLP_ID, 0);
|
||||
}
|
||||
SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT LoginCurtain_OnNotify(HWND hwnd, INT controlId, NMHDR *pnmh)
|
||||
{
|
||||
HWND hAncestor = GetAncestor(hwnd, GA_PARENT);
|
||||
if (NULL != hAncestor)
|
||||
return SendMessage(hAncestor, WM_NOTIFY, (WPARAM)controlId, (LPARAM)pnmh);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI LoginCurtain_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_CREATE: return LoginCurtain_OnCreate(hwnd, (CREATESTRUCT*)lParam);
|
||||
case WM_DESTROY: LoginCurtain_OnDestroy(hwnd); return 0;
|
||||
case WM_ERASEBKGND: return 0;
|
||||
case WM_PAINT: LoginCurtain_OnPaint(hwnd); return 0;
|
||||
case WM_PRINTCLIENT: LoginCurtain_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return 0;
|
||||
case WM_WINDOWPOSCHANGED: LoginCurtain_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return 0;
|
||||
case WM_SIZE: return 0;
|
||||
case WM_PARENTNOTIFY: LoginCurtain_OnParentNotify(hwnd, LOWORD(wParam), HIWORD(wParam), lParam); return 0;
|
||||
case WM_NOTIFY: return LoginCurtain_OnNotify(hwnd, (INT)wParam, (NMHDR*)lParam);
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
12
Src/auth/Loginbox/loginCurtain.h
Normal file
12
Src/auth/Loginbox/loginCurtain.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINCURTAIN_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINCURTAIN_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
HWND LoginCurtain_CreateWindow(HWND hParent, HWND hOwner);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINCURTAIN_HEADER
|
||||
149
Src/auth/Loginbox/loginData.cpp
Normal file
149
Src/auth/Loginbox/loginData.cpp
Normal file
@@ -0,0 +1,149 @@
|
||||
#include "./loginData.h"
|
||||
#include "./loginBox.h"
|
||||
#include "./loginProvider.h"
|
||||
#include "./loginStatus.h"
|
||||
|
||||
#include "../api.h"
|
||||
|
||||
LoginData::LoginData(const GUID *pRealm, HWND hPage, HWND hLoginbox)
|
||||
: ref(1), hPage(hPage), hLoginbox(hLoginbox), provider(NULL), status(NULL), statusCookie(-1)
|
||||
{
|
||||
if (NULL != pRealm)
|
||||
{
|
||||
realm = *pRealm;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL == hLoginbox || FALSE == LoginBox_GetRealm(hLoginbox, &realm))
|
||||
realm = GUID_NULL;
|
||||
}
|
||||
|
||||
if (FALSE == LoginBox_GetActiveProvider(hLoginbox, &provider))
|
||||
provider = NULL;
|
||||
|
||||
LoginBox_GetStatus(hLoginbox, &status);
|
||||
}
|
||||
|
||||
LoginData::~LoginData()
|
||||
{
|
||||
if (NULL != provider)
|
||||
provider->Release();
|
||||
|
||||
if (NULL != status)
|
||||
{
|
||||
if (-1 != statusCookie)
|
||||
status->Remove(statusCookie);
|
||||
|
||||
status->Release();
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT LoginData::CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LoginData **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hPage || NULL == hLoginbox) return E_INVALIDARG;
|
||||
*instance = new LoginData(pRealm, hPage, hLoginbox);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginData::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginData::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginData::QueryInterface(REFIID riid, void** ppObject)
|
||||
{
|
||||
if (NULL == ppObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IID_LoginData))
|
||||
*ppObject = static_cast<LoginData*>(this);
|
||||
else
|
||||
{
|
||||
*ppObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *ppObject)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HWND LoginData::GetLoginbox()
|
||||
{
|
||||
return hLoginbox;
|
||||
}
|
||||
|
||||
HWND LoginData::GetPage()
|
||||
{
|
||||
return hPage;
|
||||
}
|
||||
|
||||
HRESULT LoginData::GetRealm(GUID *pRealm)
|
||||
{
|
||||
if (NULL == pRealm) return E_POINTER;
|
||||
*pRealm = realm;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginData::GetProvider(LoginProvider **ppProvider)
|
||||
{
|
||||
if (NULL == ppProvider) return E_POINTER;
|
||||
*ppProvider = provider;
|
||||
if (NULL != provider)
|
||||
provider->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginData::GetStatus(LoginStatus **ppStatus)
|
||||
{
|
||||
if (NULL == ppStatus) return E_POINTER;
|
||||
*ppStatus = status;
|
||||
if (NULL != status)
|
||||
status->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT LoginData::SetStatus(LPCWSTR pszStatus)
|
||||
{
|
||||
if (NULL == status)
|
||||
return E_FAIL;
|
||||
|
||||
BSTR bstrText;
|
||||
if (NULL == pszStatus || FALSE == IS_INTRESOURCE(pszStatus))
|
||||
bstrText = SysAllocString(pszStatus);
|
||||
else
|
||||
{
|
||||
WCHAR szBuffer[256] = {0};
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)pszStatus, szBuffer, ARRAYSIZE(szBuffer));
|
||||
bstrText = SysAllocString(szBuffer);
|
||||
}
|
||||
|
||||
if (-1 == statusCookie)
|
||||
{
|
||||
statusCookie = status->Add(bstrText);
|
||||
if (-1 == statusCookie)
|
||||
return E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FALSE == status->Set(statusCookie, bstrText))
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
50
Src/auth/Loginbox/loginData.h
Normal file
50
Src/auth/Loginbox/loginData.h
Normal file
@@ -0,0 +1,50 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINDATA_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINDATA_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
// {69346B92-168E-452e-AA88-986AB3883920}
|
||||
static const GUID IID_LoginData =
|
||||
{ 0x69346b92, 0x168e, 0x452e, { 0xaa, 0x88, 0x98, 0x6a, 0xb3, 0x88, 0x39, 0x20 } };
|
||||
|
||||
|
||||
class LoginProvider;
|
||||
class LoginStatus;
|
||||
|
||||
class LoginData
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginData(const GUID *pRealm, HWND hPage, HWND hLoginbox);
|
||||
virtual ~LoginData();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(const GUID *pRealm, HWND hPage, HWND hLoginbox, LoginData **instance);
|
||||
|
||||
public:
|
||||
virtual ULONG AddRef();
|
||||
virtual ULONG Release();
|
||||
virtual HRESULT QueryInterface(REFIID riid, void** ppObject);
|
||||
|
||||
virtual HWND GetLoginbox();
|
||||
virtual HWND GetPage();
|
||||
virtual HRESULT GetRealm(GUID *pRealm);
|
||||
virtual HRESULT GetProvider(LoginProvider **ppProvider);
|
||||
virtual HRESULT GetStatus(LoginStatus **ppStatus);
|
||||
virtual HRESULT SetStatus(LPCWSTR pszStatus);
|
||||
|
||||
protected:
|
||||
UINT ref;
|
||||
GUID realm;
|
||||
HWND hPage;
|
||||
HWND hLoginbox;
|
||||
LoginProvider *provider;
|
||||
LoginStatus *status;
|
||||
UINT statusCookie;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINDATA_HEADER
|
||||
277
Src/auth/Loginbox/loginGui.cpp
Normal file
277
Src/auth/Loginbox/loginGui.cpp
Normal file
@@ -0,0 +1,277 @@
|
||||
#include "./loginGui.h"
|
||||
#include "./common.h"
|
||||
#include "./imageLoader.h"
|
||||
|
||||
#include "../resource.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
static size_t threadStorage = TLS_OUT_OF_INDEXES;
|
||||
|
||||
LoginGuiObject::LoginGuiObject()
|
||||
: ref(1), bitmapIcons(NULL), fontTitle(NULL), fontEditor(NULL), fontText(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LoginGuiObject::~LoginGuiObject()
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
|
||||
HRESULT LoginGuiObject::InitializeThread()
|
||||
{
|
||||
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
{
|
||||
if (NULL == WASABI_API_APP)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
threadStorage = WASABI_API_APP->AllocateThreadStorage();
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
LoginGuiObject *cache = (LoginGuiObject*)WASABI_API_APP->GetThreadStorage(threadStorage);
|
||||
if (NULL != cache)
|
||||
{
|
||||
cache->AddRef();
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if (NULL == cache)
|
||||
{
|
||||
cache = new LoginGuiObject();
|
||||
if (NULL == cache) return E_OUTOFMEMORY;
|
||||
WASABI_API_APP->SetThreadStorage(threadStorage, cache);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginGuiObject::UninitializeThread()
|
||||
{
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
return E_FAIL;
|
||||
|
||||
if (NULL == WASABI_API_APP)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
LoginGuiObject *cache = (LoginGuiObject*)WASABI_API_APP->GetThreadStorage(threadStorage);
|
||||
if (NULL != cache && 0 == cache->Release())
|
||||
WASABI_API_APP->SetThreadStorage(threadStorage, NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginGuiObject::QueryInstance(LoginGuiObject **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
*instance = (LoginGuiObject*)WASABI_API_APP->GetThreadStorage(threadStorage);
|
||||
if (NULL == *instance) return E_FAIL;
|
||||
(*instance)->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginGuiObject::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginGuiObject::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginGuiObject::Reset()
|
||||
{
|
||||
if (NULL != bitmapIcons)
|
||||
{
|
||||
DeleteObject(bitmapIcons);
|
||||
bitmapIcons = NULL;
|
||||
}
|
||||
|
||||
if (NULL != fontTitle)
|
||||
{
|
||||
DeleteObject(fontTitle);
|
||||
fontTitle = NULL;
|
||||
}
|
||||
|
||||
if (NULL != fontEditor)
|
||||
{
|
||||
DeleteObject(fontEditor);
|
||||
fontEditor = NULL;
|
||||
}
|
||||
|
||||
if (NULL != fontText)
|
||||
{
|
||||
DeleteObject(fontText);
|
||||
fontText = NULL;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginGuiObject::GetIconDimensions(INT *pWidth, INT *pHeight)
|
||||
{
|
||||
if (NULL == bitmapIcons)
|
||||
{
|
||||
INT width, height;
|
||||
bitmapIcons = ImageLoader_LoadBitmap(WASABI_API_ORIG_HINST, MAKEINTRESOURCE(IDR_NOTIFIERICONS_IMAGE),
|
||||
TRUE, &width, &height);
|
||||
|
||||
if (NULL == bitmapIcons)
|
||||
return E_FAIL;
|
||||
|
||||
if (height < 0) height = -height;
|
||||
|
||||
if (NULL != pWidth) *pWidth = width;
|
||||
if (NULL != pHeight) *pHeight = width;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
BITMAP bm;
|
||||
if (sizeof(bm) != GetObject(bitmapIcons, sizeof(bm), &bm))
|
||||
return E_FAIL;
|
||||
|
||||
if (NULL != pWidth) *pWidth = bm.bmWidth;
|
||||
if (NULL != pHeight) *pHeight = bm.bmWidth;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HBITMAP LoginGuiObject::GetIcon(INT iconId, RECT *prcIcon)
|
||||
{
|
||||
if (NULL == prcIcon || iconId < 0)
|
||||
return NULL;
|
||||
|
||||
INT width, height;
|
||||
|
||||
if (NULL != bitmapIcons)
|
||||
{
|
||||
BITMAP bm;
|
||||
if (sizeof(bm) != GetObject(bitmapIcons, sizeof(bm), &bm))
|
||||
bitmapIcons = NULL;
|
||||
else
|
||||
{
|
||||
width = bm.bmWidth;
|
||||
height = bm.bmHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == bitmapIcons)
|
||||
{
|
||||
bitmapIcons = ImageLoader_LoadBitmap(WASABI_API_ORIG_HINST, MAKEINTRESOURCE(IDR_NOTIFIERICONS_IMAGE),
|
||||
TRUE, &width, &height);
|
||||
|
||||
if (NULL == bitmapIcons)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (height < 0) height = -height;
|
||||
|
||||
if (width * (iconId + 1) > height)
|
||||
return NULL;
|
||||
|
||||
prcIcon->left = 0;
|
||||
prcIcon->right = width;
|
||||
prcIcon->top = width * iconId;
|
||||
prcIcon->bottom = prcIcon->top + width;
|
||||
|
||||
return bitmapIcons;
|
||||
}
|
||||
|
||||
|
||||
static HFONT LoginGuiObject_DuplicateFont(HFONT fontBase, INT heightDeltaPt)
|
||||
{
|
||||
if (NULL == fontBase) return NULL;
|
||||
|
||||
LOGFONT lf;
|
||||
if (sizeof(lf) != GetObject(fontBase, sizeof(lf), &lf))
|
||||
return NULL;
|
||||
|
||||
if (0 != heightDeltaPt)
|
||||
{
|
||||
HDC hdc = GetDCEx(NULL, NULL, DCX_WINDOW | DCX_CACHE | DCX_NORESETATTRS);
|
||||
HDC hdcTmp = NULL;
|
||||
|
||||
if (NULL != hdc)
|
||||
{
|
||||
hdcTmp = CreateCompatibleDC(hdc);
|
||||
ReleaseDC(NULL, hdc);
|
||||
}
|
||||
|
||||
if (NULL == hdcTmp)
|
||||
return NULL;
|
||||
|
||||
LONG pixelsY = GetDeviceCaps (hdcTmp, LOGPIXELSY);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdcTmp, fontBase);
|
||||
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE != GetTextMetrics(hdcTmp, &tm))
|
||||
{
|
||||
INT basePt = MulDiv(tm.tmHeight - tm.tmInternalLeading, 72, pixelsY);
|
||||
lf.lfHeight = -MulDiv((basePt + heightDeltaPt), pixelsY, 72);
|
||||
|
||||
}
|
||||
|
||||
SelectObject(hdcTmp, fontOrig);
|
||||
DeleteDC(hdcTmp);
|
||||
}
|
||||
|
||||
return CreateFontIndirect(&lf);
|
||||
}
|
||||
|
||||
HFONT LoginGuiObject::GetTitleFont()
|
||||
{
|
||||
if (NULL == fontTitle)
|
||||
{
|
||||
HFONT fontBase = GetTextFont();
|
||||
if (NULL != fontBase)
|
||||
{
|
||||
fontTitle = LoginGuiObject_DuplicateFont(fontBase, 3);
|
||||
}
|
||||
}
|
||||
return fontTitle;
|
||||
}
|
||||
|
||||
HFONT LoginGuiObject::GetEditorFont()
|
||||
{
|
||||
if (NULL == fontEditor)
|
||||
{
|
||||
HFONT fontBase = GetTextFont();
|
||||
if (NULL != fontBase)
|
||||
{
|
||||
fontEditor = LoginGuiObject_DuplicateFont(fontBase, 0);
|
||||
}
|
||||
}
|
||||
return fontEditor;
|
||||
}
|
||||
|
||||
HFONT LoginGuiObject::GetTextFont()
|
||||
{
|
||||
if (NULL == fontText)
|
||||
{
|
||||
LOGFONT lf;
|
||||
if (FALSE != SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0))
|
||||
{
|
||||
lf.lfQuality = LoginBox_GetSysFontQuality();
|
||||
fontText = CreateFontIndirect(&lf);
|
||||
}
|
||||
}
|
||||
return fontText;
|
||||
}
|
||||
53
Src/auth/Loginbox/loginGui.h
Normal file
53
Src/auth/Loginbox/loginGui.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_GUI_OBJECT_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_GUI_OBJECT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginGuiObject
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
iconNone = -1,
|
||||
iconInfo = 0,
|
||||
iconWarning = 1,
|
||||
iconError = 2,
|
||||
iconQuestion = 3,
|
||||
} IconType;
|
||||
|
||||
protected:
|
||||
LoginGuiObject();
|
||||
~LoginGuiObject();
|
||||
|
||||
public:
|
||||
static HRESULT InitializeThread();
|
||||
static HRESULT UninitializeThread();
|
||||
|
||||
static HRESULT QueryInstance(LoginGuiObject **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
|
||||
HRESULT Reset();
|
||||
|
||||
HRESULT GetIconDimensions(INT *pWidth, INT *pHeight);
|
||||
HBITMAP GetIcon(INT iconId, RECT *prcIcon);
|
||||
HFONT GetTitleFont();
|
||||
HFONT GetEditorFont();
|
||||
HFONT GetTextFont();
|
||||
|
||||
private:
|
||||
ULONG ref;
|
||||
HBITMAP bitmapIcons;
|
||||
HFONT fontTitle;
|
||||
HFONT fontEditor;
|
||||
HFONT fontText;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_GUI_OBJECT_HEADER
|
||||
663
Src/auth/Loginbox/loginNotifier.cpp
Normal file
663
Src/auth/Loginbox/loginNotifier.cpp
Normal file
@@ -0,0 +1,663 @@
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include "./loginNotifier.h"
|
||||
#include "./common.h"
|
||||
#include "./loginGui.h"
|
||||
|
||||
#include "../api.h"
|
||||
#include "../resource.h"
|
||||
#include "../api_auth.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
#define NWC_LOGINNOTIFIER L"NullsoftLoginNotifier"
|
||||
|
||||
#define GRADIENT_LEFT 30
|
||||
#define GRADIENT_RIGHT 10
|
||||
|
||||
#define SPACING_TOP 2
|
||||
#define SPACING_BOTTOM 2
|
||||
|
||||
typedef struct __LOGINNOTIFIER
|
||||
{
|
||||
UINT flags;
|
||||
HBITMAP image;
|
||||
INT type;
|
||||
LPWSTR text;
|
||||
HFONT font;
|
||||
INT textHeight;
|
||||
INT aveCharWidth;
|
||||
COLORREF rgbBack;
|
||||
COLORREF rgbText;
|
||||
} LOGINNOTIFIER;
|
||||
|
||||
#define GetNotifier(__hwnd) ((LOGINNOTIFIER*)(LONG_PTR)(LONGX86)GetWindowLongPtr((__hwnd), 0))
|
||||
|
||||
static LRESULT WINAPI LoginNotifier_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static BOOL LoginNotifier_RegisterClass(HINSTANCE hInstance)
|
||||
{
|
||||
|
||||
WNDCLASSW wc;
|
||||
if (FALSE != GetClassInfo(hInstance, NWC_LOGINNOTIFIER, &wc))
|
||||
return TRUE;
|
||||
|
||||
ZeroMemory(&wc, sizeof(wc));
|
||||
|
||||
wc.lpszClassName = NWC_LOGINNOTIFIER;
|
||||
wc.lpfnWndProc = LoginNotifier_WindowProc;
|
||||
wc.style = CS_PARENTDC;
|
||||
wc.cbWndExtra = sizeof(LOGINNOTIFIER*);
|
||||
wc.hInstance = hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
return ( 0 != RegisterClassW(&wc));
|
||||
}
|
||||
|
||||
HWND LoginNotifier_CreateWindow(UINT styleEx, UINT style, INT x, INT y, INT cx, INT cy, HWND hParent, INT controlId)
|
||||
{
|
||||
if (FALSE == LoginNotifier_RegisterClass(WASABI_API_ORIG_HINST))
|
||||
return NULL;
|
||||
|
||||
return CreateWindowEx(styleEx, NWC_LOGINNOTIFIER, NULL, WS_CHILD | style, x, y, cx, cy,
|
||||
hParent, (HMENU)(INT_PTR)controlId, WASABI_API_ORIG_HINST, NULL);
|
||||
|
||||
}
|
||||
|
||||
static HBITMAP LoginNotifier_CreateTypeImage(HDC hdc, INT type, INT height)
|
||||
{
|
||||
INT iconIndex;
|
||||
COLORREF rgbBack = RGB(255, 255, 255);
|
||||
COLORREF rgbAlert;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case NLNTYPE_INFORMATION:
|
||||
iconIndex = LoginGuiObject::iconInfo;
|
||||
rgbAlert = RGB(209, 222, 254);
|
||||
break;
|
||||
case NLNTYPE_WARNING:
|
||||
iconIndex = LoginGuiObject::iconWarning;
|
||||
rgbAlert = RGB(254, 241, 148);
|
||||
break;
|
||||
case NLNTYPE_ERROR:
|
||||
iconIndex = LoginGuiObject::iconError;
|
||||
rgbAlert = RGB(225, 105, 105);
|
||||
break;
|
||||
case NLNTYPE_QUESTION:
|
||||
iconIndex = LoginGuiObject::iconQuestion;
|
||||
rgbAlert = RGB(209, 222, 254);
|
||||
break;
|
||||
default:
|
||||
iconIndex = LoginGuiObject::iconNone;
|
||||
rgbAlert = GetSysColor(COLOR_3DLIGHT);
|
||||
break;
|
||||
}
|
||||
|
||||
RECT iconRect;
|
||||
HBITMAP bitmapIcons = NULL;
|
||||
if (LoginGuiObject::iconNone != iconIndex)
|
||||
{
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
bitmapIcons = loginGui->GetIcon(iconIndex, &iconRect);
|
||||
loginGui->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == bitmapIcons)
|
||||
SetRectEmpty(&iconRect);
|
||||
|
||||
INT iconWidth = iconRect.right - iconRect.left;
|
||||
INT iconHeight = iconRect.bottom - iconRect.top;
|
||||
|
||||
INT width = GRADIENT_LEFT + GRADIENT_RIGHT;
|
||||
width += iconWidth;
|
||||
|
||||
HBITMAP bitmapDst = NULL;
|
||||
HDC contextDst = CreateCompatibleDC(hdc);
|
||||
if (NULL != contextDst)
|
||||
{
|
||||
bitmapDst = CreateCompatibleBitmap(hdc, width, height);
|
||||
if (NULL != bitmapDst)
|
||||
{
|
||||
HBITMAP bitmapDstOrig = (HBITMAP)SelectObject(contextDst, bitmapDst);
|
||||
|
||||
TRIVERTEX vertex[] =
|
||||
{
|
||||
{ 0, 0, GetRValue(rgbBack) << 8, GetGValue(rgbBack) << 8, GetBValue(rgbBack) << 8, 0x0000 },
|
||||
{ GRADIENT_LEFT, height, GetRValue(rgbAlert) << 8, GetGValue(rgbAlert) << 8, GetBValue(rgbAlert) << 8, 0x0000 },
|
||||
};
|
||||
|
||||
GRADIENT_RECT gradientRect;
|
||||
gradientRect.UpperLeft = 0;
|
||||
gradientRect.LowerRight = 1;
|
||||
|
||||
RECT fillRect;
|
||||
SetRect(&fillRect, 0, 0, width, height);
|
||||
if (FALSE != GdiGradientFill(contextDst, vertex, ARRAYSIZE(vertex), &gradientRect, 1, GRADIENT_FILL_RECT_H))
|
||||
fillRect.left = GRADIENT_LEFT;
|
||||
|
||||
if (fillRect.left < fillRect.right)
|
||||
{
|
||||
COLORREF rgbBackOrig = SetBkColor(contextDst, rgbAlert);
|
||||
ExtTextOut(contextDst, 0, 0, ETO_OPAQUE, &fillRect, NULL, 0, NULL);
|
||||
if (rgbBackOrig != rgbAlert)
|
||||
SetBkColor(contextDst, rgbBackOrig);
|
||||
}
|
||||
|
||||
if (NULL != bitmapIcons)
|
||||
{
|
||||
HDC contextSrc = CreateCompatibleDC(hdc);
|
||||
if (NULL != contextSrc)
|
||||
{
|
||||
HBITMAP bitmapSrcOrig = (HBITMAP)SelectObject(contextSrc, bitmapIcons);
|
||||
|
||||
BLENDFUNCTION blendFunc;
|
||||
blendFunc.AlphaFormat = AC_SRC_ALPHA;
|
||||
blendFunc.BlendFlags = 0;
|
||||
blendFunc.BlendOp = AC_SRC_OVER;
|
||||
blendFunc.SourceConstantAlpha = 255;
|
||||
|
||||
INT iconTop = (height - iconHeight)/2 + (height - iconHeight)%2;
|
||||
if (iconTop >= 1 && (iconTop + iconHeight) < height)
|
||||
{
|
||||
GdiAlphaBlend(contextDst, GRADIENT_LEFT, iconTop, iconWidth, iconHeight,
|
||||
contextSrc, iconRect.left, iconRect.top, iconWidth, iconHeight, blendFunc);
|
||||
}
|
||||
|
||||
SelectObject(contextSrc, bitmapSrcOrig);
|
||||
DeleteDC(contextSrc);
|
||||
}
|
||||
}
|
||||
SelectObject(contextDst, bitmapDstOrig);
|
||||
}
|
||||
DeleteDC(contextDst);
|
||||
}
|
||||
|
||||
return bitmapDst;
|
||||
}
|
||||
|
||||
static INT LoginNotifier_CalcTextHeight(HWND hwnd, HDC hdc, INT *aveCharWidth)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return 0;
|
||||
|
||||
HDC contextMine(NULL);
|
||||
HFONT fontOrig;
|
||||
if (NULL == hdc)
|
||||
{
|
||||
contextMine = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL == contextMine) return 0;
|
||||
|
||||
if (NULL != notifier->font)
|
||||
fontOrig = (HFONT)SelectObject(contextMine, notifier->font);
|
||||
|
||||
hdc = contextMine;
|
||||
}
|
||||
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE == GetTextMetrics(hdc, &tm))
|
||||
{
|
||||
tm.tmHeight = 0;
|
||||
tm.tmAveCharWidth = 0;
|
||||
}
|
||||
|
||||
if (NULL != aveCharWidth)
|
||||
{
|
||||
*aveCharWidth = LoginBox_GetAveCharWidth(hdc);
|
||||
}
|
||||
|
||||
|
||||
if (NULL != contextMine)
|
||||
{
|
||||
if (NULL != notifier->font)
|
||||
SelectObject(contextMine, fontOrig);
|
||||
|
||||
ReleaseDC(hwnd, contextMine);
|
||||
}
|
||||
|
||||
|
||||
|
||||
return tm.tmHeight;
|
||||
}
|
||||
|
||||
static void LoginNotifier_Paint(HWND hwnd, HDC hdc, const RECT *prcPaint, BOOL fErase)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
|
||||
if (NULL == notifier->image)
|
||||
notifier->image = LoginNotifier_CreateTypeImage(hdc, notifier->type, rect.bottom - rect.top);
|
||||
|
||||
INT imageWidth = 0;
|
||||
if (NULL != notifier->image)
|
||||
{
|
||||
BITMAP bm;
|
||||
if (sizeof(BITMAP) == GetObject(notifier->image, sizeof(BITMAP), &bm))
|
||||
{
|
||||
HDC contextSrc = CreateCompatibleDC(hdc);
|
||||
if (NULL != contextSrc)
|
||||
{
|
||||
HBITMAP bitmapSrcOrig = (HBITMAP)SelectObject(contextSrc, notifier->image);
|
||||
if (FALSE != BitBlt(hdc, rect.left, rect.top, bm.bmWidth, bm.bmHeight, contextSrc, 0, 0, SRCCOPY))
|
||||
imageWidth = bm.bmWidth;
|
||||
SelectObject(contextSrc, bitmapSrcOrig);
|
||||
DeleteDC(contextSrc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetBkColor(hdc, notifier->rgbBack);
|
||||
SetTextColor(hdc, notifier->rgbText);
|
||||
|
||||
HFONT fontOrig;
|
||||
if (NULL != notifier->font)
|
||||
fontOrig = (HFONT)SelectObject(hdc, notifier->font);
|
||||
|
||||
LPCWSTR text = notifier->text;
|
||||
INT cchText = (NULL != text) ? lstrlenW(text) : 0;
|
||||
|
||||
if (-1 == notifier->textHeight)
|
||||
notifier->textHeight = LoginNotifier_CalcTextHeight(hwnd, hdc, ¬ifier->aveCharWidth);
|
||||
|
||||
RECT textRect;
|
||||
CopyRect(&textRect, &rect);
|
||||
textRect.left += imageWidth;
|
||||
|
||||
INT textOffsetY = (textRect.bottom - textRect.top) - notifier->textHeight;
|
||||
textOffsetY = textOffsetY/2 + textOffsetY%2;
|
||||
|
||||
if (textOffsetY < SPACING_TOP) textOffsetY = SPACING_TOP;
|
||||
|
||||
INT textAlignOrig = SetTextAlign(hdc, TA_TOP | TA_LEFT);
|
||||
ExtTextOut(hdc, textRect.left + notifier->aveCharWidth+2, textRect.top + textOffsetY, ETO_CLIPPED | ETO_OPAQUE, &textRect, text, cchText, NULL);
|
||||
|
||||
if (textAlignOrig != (TA_TOP | TA_LEFT))
|
||||
SetTextAlign(hdc, textAlignOrig);
|
||||
|
||||
if (NULL != notifier->font)
|
||||
SelectObject(hdc, fontOrig);
|
||||
}
|
||||
|
||||
static void LoginNotifier_UpdateLayout(HWND hwnd, BOOL fRedraw)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
|
||||
if (NULL != notifier->image)
|
||||
{
|
||||
BITMAP bm;
|
||||
if (sizeof(BITMAP) != GetObject(notifier->image, sizeof(BITMAP), &bm) ||
|
||||
bm.bmHeight != rect.bottom - rect.top)
|
||||
{
|
||||
DeleteObject(notifier->image);
|
||||
notifier->image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
||||
}
|
||||
|
||||
static BOOL LoginNotifier_SetNotification(HWND hwnd, INT type, LPCWSTR pszText, BOOL fInvalidate)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return FALSE;
|
||||
|
||||
if (type != notifier->type)
|
||||
{
|
||||
notifier->type = type;
|
||||
if (NULL != notifier->image)
|
||||
{
|
||||
DeleteObject(notifier->image);
|
||||
notifier->image = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LoginBox_FreeString(notifier->text);
|
||||
|
||||
BOOL resultCode = TRUE;
|
||||
|
||||
if (NULL == pszText)
|
||||
{
|
||||
notifier->text = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IS_INTRESOURCE(pszText))
|
||||
{
|
||||
INT stringId;
|
||||
switch((INT_PTR)pszText)
|
||||
{
|
||||
case AUTH_SUCCESS: stringId = IDS_ERR_SUCCESS; break;
|
||||
case AUTH_404: stringId = IDS_ERR_404; break;
|
||||
case AUTH_TIMEOUT: stringId = IDS_ERR_TIMEOUT; break;
|
||||
case AUTH_NOHTTP: stringId = IDS_ERR_NOHTTP; break;
|
||||
case AUTH_NOPARSER: stringId = IDS_ERR_NOPARSER; break;
|
||||
case AUTH_CONNECTIONRESET: stringId = IDS_ERR_CONNECTIONRESET; break;
|
||||
case AUTH_ERROR_PARSING_XML: stringId = IDS_ERR_PARSING_XML; break;
|
||||
case AUTH_NOT_AUTHORIZED: stringId = IDS_ERR_NOT_AUTHORIZED; break;
|
||||
case AUTH_SECURID: stringId = IDS_ERR_SECURID; break;
|
||||
case AUTH_ABORT: stringId = IDS_ERR_ABORT; break;
|
||||
case AUTH_INVALIDCRED: stringId = IDS_ERR_INVALIDCRED; break;
|
||||
case AUTH_UNCONFIRMED: stringId = IDS_ERR_UNCONFIRMED; break;
|
||||
case AUTH_UNEXPECTED: stringId = IDS_ERR_UNEXPECTED; break;
|
||||
case AUTH_INVALIDPASSCODE: stringId = IDS_ERR_PASSCODE_INVALID; break;
|
||||
case AUTH_USERNAME_EMPTY: stringId = IDS_ERR_USERNAME_EMPTY; break;
|
||||
case AUTH_USERNAME_TOOSHORT: stringId = IDS_ERR_USERNAME_TOOSHORT; break;
|
||||
case AUTH_USERNAME_TOOLONG: stringId = IDS_ERR_USERNAME_TOOLONG; break;
|
||||
case AUTH_USERNAME_BADFORMAT: stringId = IDS_ERR_USERNAME_BADFORMAT; break;
|
||||
case AUTH_PASSWORD_EMPTY: stringId = IDS_ERR_PASSWORD_EMPTY; break;
|
||||
case AUTH_PASSWORD_TOOSHORT: stringId = IDS_ERR_PASSWORD_TOOSHORT; break;
|
||||
case AUTH_PASSWORD_TOOLONG: stringId = IDS_ERR_PASSWORD_TOOLONG; break;
|
||||
case AUTH_PASSWORD_BADFORMAT: stringId = IDS_ERR_PASSWORD_BADFORMAT; break;
|
||||
case AUTH_PASSCODE_EMPTY: stringId = IDS_ERR_PASSCODE_EMPTY; break;
|
||||
case AUTH_PASSCODE_TOOSHORT: stringId = IDS_ERR_PASSCODE_TOOSHORT; break;
|
||||
case AUTH_PASSCODE_TOOLONG: stringId = IDS_ERR_PASSCODE_TOOLONG; break;
|
||||
case AUTH_PASSCODE_BADFORMAT: stringId = IDS_ERR_PASSCODE_BADFORMAT; break;
|
||||
default: stringId = IDS_ERR_UNKNOWN; break;
|
||||
}
|
||||
|
||||
WCHAR szBuffer[2048] = {0};
|
||||
LPWSTR cursor = szBuffer;
|
||||
size_t remaining = ARRAYSIZE(szBuffer);
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_LOGIN_FAILURE, cursor, remaining);
|
||||
size_t len = lstrlen(cursor);
|
||||
cursor += len;
|
||||
remaining -= len;
|
||||
if (cursor != szBuffer)
|
||||
StringCchCopyEx(cursor, remaining, L": ", &cursor, &remaining, 0);
|
||||
WASABI_API_LNGSTRINGW_BUF(stringId, cursor, remaining);
|
||||
|
||||
notifier->text = LoginBox_CopyString(szBuffer);
|
||||
if (NULL == notifier->text)
|
||||
resultCode = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
notifier->text = LoginBox_CopyString(pszText);
|
||||
if (NULL == notifier->text)
|
||||
resultCode = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE != fInvalidate)
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
|
||||
return resultCode;
|
||||
}
|
||||
static LRESULT LoginNotifier_OnCreate(HWND hwnd, CREATESTRUCT* pcs)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = (LOGINNOTIFIER*)calloc(1, sizeof(LOGINNOTIFIER));
|
||||
if (NULL != notifier)
|
||||
{
|
||||
SetLastError(ERROR_SUCCESS);
|
||||
if (!SetWindowLongPtr(hwnd, 0, (LONGX86)(LONG_PTR)notifier) && ERROR_SUCCESS != GetLastError())
|
||||
{
|
||||
free(notifier);
|
||||
notifier = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == notifier)
|
||||
return -1;
|
||||
|
||||
notifier->textHeight = -1;
|
||||
notifier->rgbBack = RGB(247, 247, 247);
|
||||
notifier->rgbText = RGB(0, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnDestroy(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
SetWindowLongPtr(hwnd, 0, 0L);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
if (NULL != notifier->image)
|
||||
DeleteObject(notifier->image);
|
||||
|
||||
free(notifier);
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
|
||||
{
|
||||
if (SWP_NOSIZE == ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
||||
return;
|
||||
|
||||
LoginNotifier_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
|
||||
}
|
||||
|
||||
|
||||
static void LoginNotifier_OnPaint(HWND hwnd)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
if (BeginPaint(hwnd, &ps))
|
||||
{
|
||||
if (ps.rcPaint.left != ps.rcPaint.right)
|
||||
LoginNotifier_Paint(hwnd, ps.hdc, &ps.rcPaint, ps.fErase);
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnPrintClient(HWND hwnd, HDC hdc, UINT options)
|
||||
{
|
||||
RECT clientRect;
|
||||
if (GetClientRect(hwnd, &clientRect))
|
||||
LoginNotifier_Paint(hwnd, hdc, &clientRect, 0 != (PRF_ERASEBKGND & options));
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnSetFont(HWND hwnd, HFONT hFont, BOOL fRedraw)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
notifier->font = hFont;
|
||||
|
||||
notifier->textHeight = -1;
|
||||
|
||||
if (NULL != fRedraw)
|
||||
InvalidateRect(hwnd, NULL, FALSE);
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetFont(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
return (NULL != notifier) ? (LRESULT)notifier->font : NULL;
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnSetText(HWND hwnd, LPCWSTR pszText)
|
||||
{
|
||||
return LoginNotifier_SetNotification(hwnd, NLNTYPE_INFORMATION, pszText, TRUE);
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetText(HWND hwnd, LPWSTR pszBuffer, size_t cchBufferMax)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
LPCWSTR pszText = (NULL != notifier) ? notifier->text : NULL;
|
||||
|
||||
if (NULL == pszBuffer)
|
||||
return 0;
|
||||
|
||||
size_t remaining;
|
||||
StringCchCopyEx(pszBuffer, cchBufferMax, pszText, NULL, &remaining, STRSAFE_IGNORE_NULLS);
|
||||
return (cchBufferMax - remaining);
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetTextLength(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
return (NULL != notifier && NULL != notifier->text) ? lstrlen(notifier->text) : 0;
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnNotify(HWND hwnd, INT type, LPCWSTR pszText)
|
||||
{
|
||||
return LoginNotifier_SetNotification(hwnd, type, pszText, TRUE);
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetIdealHeight(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return 0;
|
||||
|
||||
if (-1 == notifier->textHeight)
|
||||
notifier->textHeight = LoginNotifier_CalcTextHeight(hwnd, NULL, ¬ifier->aveCharWidth);
|
||||
|
||||
|
||||
INT iconHeight(0);
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
loginGui->GetIconDimensions(NULL, &iconHeight);
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
INT height = (notifier->textHeight > iconHeight) ?
|
||||
notifier->textHeight : iconHeight;
|
||||
|
||||
height += SPACING_TOP + SPACING_BOTTOM;
|
||||
return height;
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetIdealSize(HWND hwnd, SIZE *sizeOut)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier || NULL == sizeOut) return FALSE;
|
||||
|
||||
if (-1 == notifier->textHeight)
|
||||
notifier->textHeight = LoginNotifier_CalcTextHeight(hwnd, NULL, ¬ifier->aveCharWidth);
|
||||
|
||||
INT iconWidth(0), iconHeight(0);
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
loginGui->GetIconDimensions(&iconWidth, &iconHeight);
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
sizeOut->cy = (notifier->textHeight > iconHeight) ?
|
||||
notifier->textHeight :
|
||||
iconHeight;
|
||||
|
||||
sizeOut->cy += SPACING_TOP + SPACING_BOTTOM;
|
||||
|
||||
sizeOut->cx = (0 != iconWidth) ?
|
||||
(GRADIENT_LEFT + GRADIENT_RIGHT + iconWidth) :
|
||||
0;
|
||||
|
||||
INT cchText = (NULL != notifier->text) ? lstrlen(notifier->text) : 0;
|
||||
|
||||
BOOL resultOk = TRUE;
|
||||
|
||||
if (0 != cchText)
|
||||
{
|
||||
sizeOut->cx += notifier->aveCharWidth+2;
|
||||
|
||||
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, notifier->font);
|
||||
|
||||
SIZE textSize;
|
||||
if (FALSE != GetTextExtentPoint32W(hdc, notifier->text, cchText, &textSize))
|
||||
sizeOut->cx += textSize.cx;
|
||||
else
|
||||
resultOk = FALSE;
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
else
|
||||
resultOk = FALSE;
|
||||
}
|
||||
return resultOk;
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnSetBkColor(HWND hwnd, COLORREF rgbColor)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
notifier->rgbBack = rgbColor;
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetBkColor(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return RGB(255, 0, 255);
|
||||
|
||||
return notifier->rgbBack;
|
||||
}
|
||||
|
||||
static void LoginNotifier_OnSetTextColor(HWND hwnd, COLORREF rgbColor)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
notifier->rgbText = rgbColor;
|
||||
}
|
||||
|
||||
static LRESULT LoginNotifier_OnGetTextColor(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return RGB(255, 0, 255);
|
||||
|
||||
return notifier->rgbText;
|
||||
}
|
||||
static void LoginNotifier_OnPlayBeep(HWND hwnd)
|
||||
{
|
||||
LOGINNOTIFIER *notifier = GetNotifier(hwnd);
|
||||
if (NULL == notifier) return;
|
||||
|
||||
UINT beepType;
|
||||
switch(notifier->type)
|
||||
{
|
||||
case NLNTYPE_INFORMATION: beepType = MB_ICONASTERISK; break;
|
||||
case NLNTYPE_WARNING: beepType = MB_ICONEXCLAMATION; break;
|
||||
case NLNTYPE_ERROR: beepType = MB_ICONHAND; break;
|
||||
case NLNTYPE_QUESTION: beepType = MB_ICONQUESTION; break;
|
||||
default: return;
|
||||
}
|
||||
LoginBox_MessageBeep(beepType);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI LoginNotifier_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_CREATE: return LoginNotifier_OnCreate(hwnd, (CREATESTRUCT*)lParam);
|
||||
case WM_DESTROY: LoginNotifier_OnDestroy(hwnd); return 0;
|
||||
case WM_ERASEBKGND: return 0;
|
||||
case WM_PAINT: LoginNotifier_OnPaint(hwnd); return 0;
|
||||
case WM_PRINTCLIENT: LoginNotifier_OnPrintClient(hwnd, (HDC)wParam, (UINT)lParam); return 0;
|
||||
case WM_PRINT: return 0;
|
||||
|
||||
case WM_WINDOWPOSCHANGED: LoginNotifier_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return 0;
|
||||
case WM_SIZE: return 0;
|
||||
case WM_SETFONT: LoginNotifier_OnSetFont(hwnd, (HFONT)wParam, (BOOL)LOWORD(lParam)); return 0;
|
||||
case WM_GETFONT: return LoginNotifier_OnGetFont(hwnd);
|
||||
case WM_SETTEXT: return LoginNotifier_OnSetText(hwnd, (LPCWSTR)lParam);
|
||||
case WM_GETTEXT: return LoginNotifier_OnGetText(hwnd, (LPWSTR)lParam, (INT)wParam);
|
||||
case WM_GETTEXTLENGTH: return LoginNotifier_OnGetTextLength(hwnd);
|
||||
|
||||
case NLNM_NOTIFY: return LoginNotifier_OnNotify(hwnd, (INT)wParam, (LPCWSTR)lParam);
|
||||
case NLNM_GETIDEALHEIGHT: return LoginNotifier_OnGetIdealHeight(hwnd);
|
||||
case NLNM_SETBKCOLOR: LoginNotifier_OnSetBkColor(hwnd, (COLORREF)lParam); return 0;
|
||||
case NLNM_GETBKCOLOR: return LoginNotifier_OnGetBkColor(hwnd);
|
||||
case NLNM_SETTEXTCOLOR: LoginNotifier_OnSetTextColor(hwnd, (COLORREF)lParam); return 0;
|
||||
case NLNM_GETTEXTCOLOR: return LoginNotifier_OnGetTextColor(hwnd);
|
||||
case NLNM_PLAYBEEP: LoginNotifier_OnPlayBeep(hwnd); return 0;
|
||||
case NLNM_GETIDEALSIZE: return LoginNotifier_OnGetIdealSize(hwnd, (SIZE*)lParam);
|
||||
}
|
||||
return DefWindowProc(hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
54
Src/auth/Loginbox/loginNotifier.h
Normal file
54
Src/auth/Loginbox/loginNotifier.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_NOTIFIER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_NOTIFIER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginGuiObject;
|
||||
|
||||
HWND LoginNotifier_CreateWindow(UINT styleEx, UINT style, INT x, INT y, INT cx, INT cy, HWND hParent, INT controlId);
|
||||
|
||||
|
||||
#define NLNTYPE_INFORMATION 0
|
||||
#define NLNTYPE_WARNING 1
|
||||
#define NLNTYPE_ERROR 2
|
||||
#define NLNTYPE_QUESTION 3
|
||||
|
||||
#define NLNM_FIRST (WM_USER + 10)
|
||||
|
||||
#define NLNM_NOTIFY (NLNM_FIRST + 0) // wParam = (WPARAM)(INT)notificationType, lParam = (LPARAM)(LPCWSTR)notificationText; Return - TRUE on success; notificationText can be MAKEINTRESOURCE(authError)
|
||||
#define LoginNotifier_Notify(/*HWND*/ __hwnd, /*INT*/ __notificationType, /*LPCWSTR*/ __notificationText)\
|
||||
(SNDMSG((__hwnd), NLNM_NOTIFY, (WPARAM)(__notificationType), (LPARAM)(__notificationText)))
|
||||
|
||||
#define NLNM_GETIDEALHEIGHT (NLNM_FIRST + 1) // wParam - not used, lParam - not used; Return - ideal height
|
||||
#define LoginNotifier_GetIdealHeight(/*HWND*/ __hwnd)\
|
||||
((INT)SNDMSG((__hwnd), NLNM_GETIDEALHEIGHT, 0, 0L))
|
||||
|
||||
#define NLNM_SETBKCOLOR (NLNM_FIRST + 2) // wParam - not used, lParam = (LPARAM)(COLORREF)rgb; Return ignored
|
||||
#define LoginNotifier_SetBkColor(/*HWND*/ __hwnd, /*COLORREF*/ __rgb)\
|
||||
(SNDMSG((__hwnd), NLNM_SETBKCOLOR, 0, (LPARAM)(__rgb)))
|
||||
|
||||
#define NLNM_GETBKCOLOR (NLNM_FIRST + 3) // wParam - not used, lParam - not used; Return back color
|
||||
#define LoginNotifier_GetBkColor(/*HWND*/ __hwnd)\
|
||||
((COLORREF)SNDMSG((__hwnd), NLNM_GETBKCOLOR, 0, 0L))
|
||||
|
||||
#define NLNM_SETTEXTCOLOR (NLNM_FIRST + 4) // wParam - not used, lParam = (LPARAM)(COLORREF)rgb; Return ignored
|
||||
#define LoginNotifier_SetTextColor(/*HWND*/ __hwnd, /*COLORREF*/ __rgb)\
|
||||
(SNDMSG((__hwnd), NLNM_SETTEXTCOLOR, 0, (LPARAM)(__rgb)))
|
||||
|
||||
#define NLNM_GETTEXTCOLOR (NLNM_FIRST + 5) // wParam - not used, lParam - not used; Return back color
|
||||
#define LoginNotifier_GetTextColor(/*HWND*/ __hwnd)\
|
||||
((COLORREF)SNDMSG((__hwnd), NLNM_GETTEXTCOLOR, 0, 0L))
|
||||
|
||||
#define NLNM_PLAYBEEP (NLNM_FIRST + 6) // wParam - not used, lParam - not used; Return ignored
|
||||
#define LoginNotifier_PlayBeep(/*HWND*/ __hwnd)\
|
||||
(SNDMSG((__hwnd), NLNM_PLAYBEEP, 0, 0L))
|
||||
|
||||
#define NLNM_GETIDEALSIZE (NLNM_FIRST + 7) // wParam - not used, lParam - (LPARAM)(SIZE*)sizeOut; Return TRUE on success
|
||||
#define LoginNotifier_GetIdealSize(/*HWND*/ __hwnd, /*SIZE* */ __sizeOut)\
|
||||
((BOOL)SNDMSG((__hwnd), NLNM_GETIDEALSIZE, 0, (LPARAM)(__sizeOut)))
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_NOTIFIER_HEADER
|
||||
624
Src/auth/Loginbox/loginPage.cpp
Normal file
624
Src/auth/Loginbox/loginPage.cpp
Normal file
@@ -0,0 +1,624 @@
|
||||
#define OEMRESOURCE
|
||||
|
||||
#include "./loginPage.h"
|
||||
#include "./loginData.h"
|
||||
#include "./loginBox.h"
|
||||
#include "./loginProvider.h"
|
||||
#include "./loginGui.h"
|
||||
#include "./common.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include "../../nu/windowsTheme.h"
|
||||
|
||||
#include <vssym32.h>
|
||||
#include <vsstyle.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define IDC_TITLE 9999
|
||||
#define IDC_HELPLINK 9998
|
||||
|
||||
typedef struct __LOGINPAGECREATEPARAM
|
||||
{
|
||||
LOGINPAGECREATOR fnCreator;
|
||||
LPARAM lParam;
|
||||
HWND hLoginbox;
|
||||
} LOGINPAGECREATEPARAM;
|
||||
|
||||
LoginPage::LoginPage(HWND hwnd, HWND hLoginbox)
|
||||
{
|
||||
this->hwnd = hwnd;
|
||||
this->hLoginbox = hLoginbox;
|
||||
}
|
||||
|
||||
LoginPage::~LoginPage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HWND LoginPage::CreatePage(HWND hLoginbox, LPCWSTR pszTemplate, HWND hParent, LPARAM param, LOGINPAGECREATOR fnCreator)
|
||||
{
|
||||
if (NULL == hLoginbox || NULL == hParent)
|
||||
return NULL;
|
||||
|
||||
if (NULL == pszTemplate || NULL == fnCreator)
|
||||
return NULL;
|
||||
|
||||
LOGINPAGECREATEPARAM createParam;
|
||||
createParam.fnCreator = fnCreator;
|
||||
createParam.lParam = param;
|
||||
createParam.hLoginbox = hLoginbox;
|
||||
|
||||
return WASABI_API_CREATEDIALOGPARAMW((INT)(INT_PTR)pszTemplate, hParent, LoginPage_DialogProc, (LPARAM)&createParam);
|
||||
}
|
||||
|
||||
void LoginPage::UpdateColors()
|
||||
{
|
||||
rgbTitle = RGB(0, 51, 153);
|
||||
rgbSecondaryText = GetSysColor(COLOR_WINDOWTEXT);
|
||||
rgbText = GetSysColor(COLOR_WINDOWTEXT);
|
||||
rgbBack = GetSysColor(COLOR_WINDOW);
|
||||
hbrBack = GetSysColorBrush(COLOR_WINDOW);
|
||||
|
||||
if (SUCCEEDED(UxTheme_LoadLibrary()) && FALSE != UxIsAppThemed())
|
||||
{
|
||||
UXTHEME hTheme = UxOpenThemeData(hwnd, L"TEXTSTYLE");
|
||||
if (NULL != hTheme)
|
||||
{
|
||||
UxGetThemeColor(hTheme, TEXT_MAININSTRUCTION, 0, TMT_TEXTCOLOR, &rgbTitle);
|
||||
UxGetThemeColor(hTheme, TEXT_BODYTEXT, 0, TMT_TEXTCOLOR, &rgbText);
|
||||
UxGetThemeColor(hTheme, TEXT_SECONDARYTEXT, 0, TMT_TEXTCOLOR, &rgbSecondaryText);
|
||||
UxCloseThemeData(hTheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPage::UpdateMargins()
|
||||
{
|
||||
SetRect(&margins, 14, 7, 7, 7);
|
||||
MapDialogRect(hwnd, &margins);
|
||||
|
||||
RECT controlRect;
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
|
||||
if (NULL != hControl && GetWindowRect(hControl, &controlRect))
|
||||
{
|
||||
|
||||
INT t = (controlRect.right - controlRect.left) + 1;
|
||||
if (margins.right < t) margins.right = t;
|
||||
|
||||
t = (controlRect.bottom - controlRect.top) + 1;
|
||||
if (margins.top < t) margins.top = t;
|
||||
}
|
||||
}
|
||||
|
||||
static HBITMAP LoginPage_GetHelpBitmap(HWND hwnd, HBRUSH hbrBack, INT *pWidth, INT *pHeight)
|
||||
{
|
||||
LoginGuiObject *loginGui;
|
||||
if (FAILED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
return NULL;
|
||||
|
||||
|
||||
RECT rectSrc;
|
||||
HBITMAP hbmpSrc = loginGui->GetIcon(LoginGuiObject::iconQuestion, &rectSrc);
|
||||
HBITMAP hbmpDst = NULL;
|
||||
if (NULL != hbmpSrc)
|
||||
{
|
||||
HDC hdc = GetDCEx(hwnd, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if( NULL != hdc)
|
||||
{
|
||||
HDC hdcDst = CreateCompatibleDC(hdc);
|
||||
HDC hdcSrc = CreateCompatibleDC(hdc);
|
||||
if (NULL != hdcDst && NULL != hdcSrc)
|
||||
{
|
||||
INT imageWidth = rectSrc.right - rectSrc.left;
|
||||
INT imageHeight = rectSrc.bottom - rectSrc.top;
|
||||
|
||||
BITMAPINFOHEADER header;
|
||||
ZeroMemory(&header, sizeof(BITMAPINFOHEADER));
|
||||
|
||||
header.biSize = sizeof(BITMAPINFOHEADER);
|
||||
header.biCompression = BI_RGB;
|
||||
header.biBitCount = 24;
|
||||
header.biPlanes = 1;
|
||||
header.biWidth = imageWidth;
|
||||
header.biHeight = -imageHeight;
|
||||
void *pixelData;
|
||||
|
||||
hbmpDst = CreateDIBSection(hdc, (LPBITMAPINFO)&header, DIB_RGB_COLORS, (void**)&pixelData, NULL, 0);
|
||||
if (NULL != hbmpDst)
|
||||
{
|
||||
HBITMAP hbmpDstOrig = (HBITMAP)SelectObject(hdcDst, hbmpDst);
|
||||
HBITMAP hbmpSrcOrig = (HBITMAP)SelectObject(hdcSrc, hbmpSrc);
|
||||
|
||||
RECT fillRect;
|
||||
SetRect(&fillRect, 0, 0, imageWidth, imageHeight);
|
||||
FillRect(hdcDst, &fillRect, hbrBack);
|
||||
|
||||
BLENDFUNCTION bf;
|
||||
bf.BlendOp = AC_SRC_OVER;
|
||||
bf.BlendFlags = 0;
|
||||
bf.SourceConstantAlpha = 255;
|
||||
bf.AlphaFormat = AC_SRC_ALPHA;
|
||||
|
||||
GdiAlphaBlend(hdcDst, 0, 0, imageWidth, imageHeight,
|
||||
hdcSrc, rectSrc.left, rectSrc.top, imageWidth, imageHeight, bf);
|
||||
|
||||
SelectObject(hdcDst, hbmpDstOrig);
|
||||
SelectObject(hdcSrc, hbmpSrcOrig);
|
||||
|
||||
if (NULL != pWidth) *pWidth = imageWidth;
|
||||
if (NULL != pHeight) *pHeight = imageHeight;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != hdcDst) DeleteDC(hdcDst);
|
||||
if (NULL != hdcSrc) DeleteDC(hdcSrc);
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
}
|
||||
loginGui->Release();
|
||||
return hbmpDst;
|
||||
}
|
||||
|
||||
void LoginPage::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
RECT clientRect;
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
const INT szControls[] = { IDC_HELPLINK, IDC_TITLE};
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
|
||||
|
||||
RECT rect;
|
||||
INT cx, cy, x, y;
|
||||
|
||||
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);
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_HELPLINK:
|
||||
x = clientRect.right - cx - 1;
|
||||
if (x < clientRect.left + 1) x = clientRect.left + 1;
|
||||
y = clientRect.top + 1;
|
||||
break;
|
||||
case IDC_TITLE:
|
||||
x = clientRect.left + margins.left;
|
||||
y = clientRect.top + margins.top;
|
||||
cx = clientRect.right - margins.right - x;
|
||||
cy = 0;
|
||||
|
||||
LoginBox_GetWindowTextSize(hControl, cx, &cx, &cy);
|
||||
|
||||
if ((cx + x) > (clientRect.right - margins.right))
|
||||
cx = clientRect.right - margins.right - x;
|
||||
if ((cy + y) > (clientRect.bottom - margins.bottom))
|
||||
cy = clientRect.bottom - margins.bottom - y;
|
||||
break;
|
||||
}
|
||||
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, flags);
|
||||
if (NULL == hdwp) break;
|
||||
}
|
||||
|
||||
if (NULL != hdwp)
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
|
||||
BOOL LoginPage::GetPageRect(RECT *prc)
|
||||
{
|
||||
if (NULL == prc || FALSE == GetClientRect(hwnd, prc))
|
||||
return FALSE;
|
||||
|
||||
prc->left += margins.left;
|
||||
prc->top += margins.top;
|
||||
prc->right -= margins.right;
|
||||
prc->bottom -= margins.bottom;
|
||||
|
||||
HWND hTitle = GetDlgItem(hwnd, IDC_TITLE);
|
||||
if (NULL != hTitle)
|
||||
{
|
||||
UINT titleStyle = GetWindowStyle(hTitle);
|
||||
if (0 != (WS_VISIBLE & titleStyle))
|
||||
{
|
||||
RECT titleRect;
|
||||
if (FALSE != GetWindowRect(hTitle, &titleRect))
|
||||
{
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&titleRect, 2);
|
||||
|
||||
titleRect.bottom += GetTitleSpacing();
|
||||
|
||||
if (titleRect.bottom > prc->top)
|
||||
{
|
||||
prc->top = titleRect.bottom;
|
||||
if (prc->top > prc->bottom)
|
||||
prc->top = prc->bottom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INT LoginPage::GetTitleSpacing()
|
||||
{
|
||||
HWND hTitle = GetDlgItem(hwnd, IDC_TITLE);
|
||||
if (NULL == hTitle) return 0;
|
||||
|
||||
HFONT fontTitle = (HFONT)SendMessage(hTitle, WM_GETFONT, 0, 0L);
|
||||
|
||||
HDC hdc = GetDCEx(hTitle, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL == hdc) return 0;
|
||||
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, fontTitle);
|
||||
|
||||
TEXTMETRIC tm;
|
||||
if (FALSE == GetTextMetrics(hdc, &tm))
|
||||
tm.tmHeight = 0;
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hTitle, hdc);
|
||||
|
||||
return tm.tmHeight;
|
||||
}
|
||||
|
||||
|
||||
BOOL LoginPage::IsHelpAvailable()
|
||||
{
|
||||
LoginProvider *provider;
|
||||
if (NULL == hLoginbox ||
|
||||
FALSE == LoginBox_GetActiveProvider(hLoginbox, &provider) ||
|
||||
NULL == provider)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WCHAR szBuffer[8192] = {0};
|
||||
|
||||
HRESULT hr = provider->GetHelpLink(szBuffer, ARRAYSIZE(szBuffer));
|
||||
provider->Release();
|
||||
|
||||
if (FAILED(hr) || L'\0' == szBuffer[0])
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoginPage::ShowHelp()
|
||||
{
|
||||
LoginProvider *provider;
|
||||
if (NULL == hLoginbox ||
|
||||
FALSE == LoginBox_GetActiveProvider(hLoginbox, &provider) ||
|
||||
NULL == provider)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
WCHAR szBuffer[8192] = {0};
|
||||
|
||||
HRESULT hr = provider->GetHelpLink(szBuffer, ARRAYSIZE(szBuffer));
|
||||
provider->Release();
|
||||
|
||||
if (FAILED(hr) || L'\0' == szBuffer[0])
|
||||
return FALSE;
|
||||
|
||||
return LoginBox_OpenUrl(hwnd, szBuffer, TRUE);
|
||||
}
|
||||
|
||||
BOOL LoginPage::SetLabelText(INT controlId, LPCWSTR pszText)
|
||||
{
|
||||
HWND hLabel = GetDlgItem(hwnd, controlId);
|
||||
if (NULL == hLabel) return FALSE;
|
||||
|
||||
LPWSTR pszTemp = NULL;
|
||||
if (NULL != pszText && L'\0' != *pszText)
|
||||
{
|
||||
INT cchLabel = lstrlenW(pszText);
|
||||
if (cchLabel > 0 && L':' != pszText[cchLabel-1])
|
||||
{
|
||||
pszTemp = LoginBox_MallocString(cchLabel + 2);
|
||||
if (NULL != pszTemp)
|
||||
{
|
||||
CopyMemory(pszTemp, pszText, sizeof(WCHAR) * cchLabel);
|
||||
pszTemp[cchLabel] = L':';
|
||||
pszTemp[cchLabel + 1] = L'\0';
|
||||
pszText = pszTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL result = SetWindowText(hLabel, pszText);
|
||||
|
||||
if (NULL != pszTemp)
|
||||
LoginBox_FreeString(pszTemp);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
HWND hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", NULL,
|
||||
WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
|
||||
0, 0, 100, 24, hwnd, (HMENU)IDC_TITLE, NULL, 0L);
|
||||
|
||||
if (NULL != hControl)
|
||||
{
|
||||
HFONT fontTitle = NULL;
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
fontTitle = loginGui->GetTitleFont();
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
if (NULL == fontTitle)
|
||||
fontTitle = (HFONT)SNDMSG(hwnd, WM_GETFONT, 0, 0L);
|
||||
|
||||
if (NULL != fontTitle)
|
||||
SNDMSG(hControl, WM_SETFONT, (WPARAM)fontTitle, 0L);
|
||||
}
|
||||
|
||||
INT imageWidth, imageHeight;
|
||||
HBITMAP bitmapHelp = LoginPage_GetHelpBitmap(hwnd, hbrBack, &imageWidth, &imageHeight);
|
||||
if (NULL != bitmapHelp)
|
||||
{
|
||||
UINT controlStyle = WS_CHILD | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
|
||||
SS_BITMAP | SS_NOTIFY;
|
||||
|
||||
if (FALSE != IsHelpAvailable())
|
||||
controlStyle |= WS_VISIBLE;
|
||||
|
||||
hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", NULL, controlStyle,
|
||||
0, 0, 0, 0, hwnd, (HMENU)IDC_HELPLINK, NULL, 0L);
|
||||
|
||||
HBITMAP bitmapSelected = NULL;
|
||||
|
||||
if (NULL != hControl)
|
||||
{
|
||||
bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)bitmapHelp);
|
||||
if (NULL != bitmapSelected)
|
||||
DeleteObject(bitmapSelected);
|
||||
bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_GETIMAGE, (WPARAM)IMAGE_BITMAP, 0L);
|
||||
}
|
||||
|
||||
if (bitmapSelected != bitmapHelp)
|
||||
DeleteObject(bitmapHelp);
|
||||
}
|
||||
|
||||
|
||||
UpdateMargins();
|
||||
UpdateColors();
|
||||
UpdateLayout(FALSE);
|
||||
PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPage::OnDestroy()
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
HBITMAP bitmapSelected = (HBITMAP)SNDMSG(hControl, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, 0L);
|
||||
if (NULL != bitmapSelected)
|
||||
DeleteObject(bitmapSelected);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPage::OnWindowPosChanged(const WINDOWPOS *pwp)
|
||||
{
|
||||
if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
||||
UpdateLayout(0 == (SWP_NOREDRAW & pwp->flags));
|
||||
}
|
||||
|
||||
void LoginPage::OnCommand(UINT commandId, UINT eventType, HWND hControl)
|
||||
{
|
||||
switch(commandId)
|
||||
{
|
||||
case IDC_HELPLINK:
|
||||
switch(eventType)
|
||||
{
|
||||
case STN_CLICKED:
|
||||
ShowHelp();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnNotify(UINT controlId, const NMHDR *pnmh)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnGetLoginData(LoginData **ppLoginData)
|
||||
{
|
||||
if (FAILED(LoginData::CreateInstance(NULL, hwnd, hLoginbox, ppLoginData)))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LoginPage::OnUpdateStateChange(BOOL updateActive)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnSetUsername(LPCWSTR pszUsername)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnSetPassword(LPCWSTR pszPassword)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HWND LoginPage::OnGetFirstItem()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnSetTitle(LPCWSTR pszTitle)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_TITLE);
|
||||
if (NULL == hControl) return FALSE;
|
||||
|
||||
BOOL result = (BOOL)SNDMSG(hControl, WM_SETTEXT, 0, (LPARAM)pszTitle);
|
||||
if (FALSE != result)
|
||||
UpdateLayout(TRUE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HBRUSH LoginPage::OnGetStaticColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
INT controlId = (INT)GetWindowLongPtr(hControl, GWLP_ID);
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_TITLE:
|
||||
SetTextColor(hdc, rgbTitle);
|
||||
break;
|
||||
default:
|
||||
SetTextColor(hdc, rgbText);
|
||||
break;
|
||||
}
|
||||
|
||||
SetBkColor(hdc, rgbBack);
|
||||
return hbrBack;
|
||||
}
|
||||
|
||||
HBRUSH LoginPage::OnGetDialogColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
SetTextColor(hdc, rgbText);
|
||||
SetBkColor(hdc, rgbBack);
|
||||
return hbrBack;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnSetCursor(HWND hTarget, INT hitCode, INT uMsg)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_HELPLINK);
|
||||
if (hControl == hTarget && NULL != hControl)
|
||||
{
|
||||
UINT controlStyle = GetWindowStyle(hControl);
|
||||
if (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & controlStyle))
|
||||
{
|
||||
HCURSOR hCursor = LoadCursor(NULL, IDC_HAND);
|
||||
if (NULL != hCursor)
|
||||
{
|
||||
SetCursor(hCursor);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LoginPage::OnHelp(HELPINFO *phi)
|
||||
{
|
||||
return ShowHelp();
|
||||
}
|
||||
|
||||
void LoginPage::OnThemeChanged()
|
||||
{
|
||||
UpdateColors();
|
||||
}
|
||||
|
||||
void LoginPage::OnSysColorChanged()
|
||||
{
|
||||
UpdateColors();
|
||||
}
|
||||
|
||||
INT_PTR LoginPage::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
|
||||
case WM_DESTROY: OnDestroy(); return TRUE;
|
||||
case WM_NOTIFY: MSGRESULT(hwnd, OnNotify((INT)wParam, (NMHDR*)lParam));
|
||||
case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
|
||||
case WM_WINDOWPOSCHANGED: OnWindowPosChanged((WINDOWPOS*)lParam); return TRUE;
|
||||
case WM_SIZE: return TRUE;
|
||||
case WM_CTLCOLORSTATIC: return (INT_PTR)OnGetStaticColor((HDC)wParam, (HWND)lParam);
|
||||
case WM_CTLCOLORDLG: return (INT_PTR)OnGetDialogColor((HDC)wParam, (HWND)lParam);
|
||||
case WM_SETCURSOR:
|
||||
if (FALSE != OnSetCursor((HWND)wParam, LOWORD(lParam), HIWORD(lParam)))
|
||||
MSGRESULT(hwnd, TRUE);
|
||||
break;
|
||||
case WM_HELP:
|
||||
if (FALSE != OnHelp((HELPINFO*)lParam))
|
||||
MSGRESULT(hwnd, TRUE);
|
||||
break;
|
||||
|
||||
case WM_THEMECHANGED: OnThemeChanged(); return TRUE;
|
||||
case WM_SYSCOLORCHANGE: OnSysColorChanged(); return TRUE;
|
||||
|
||||
case NLPM_GETLOGINDATA: MSGRESULT(hwnd, OnGetLoginData((LoginData**)lParam));
|
||||
case NLPM_UPDATESTATECHANGE: OnUpdateStateChange((BOOL)lParam); return TRUE;
|
||||
case NLPM_SETUSERNAME: MSGRESULT(hwnd, OnSetUsername((LPCWSTR)lParam));
|
||||
case NLPM_SETPASSWORD: MSGRESULT(hwnd, OnSetPassword((LPCWSTR)lParam));
|
||||
case NLPM_GETFIRSTITEM: MSGRESULT(hwnd, OnGetFirstItem());
|
||||
case NLPM_SETTITLE: MSGRESULT(hwnd, OnSetTitle((LPCWSTR)lParam));
|
||||
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK LoginPage_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static ATOM LOGINPAGE_PROP = 0;
|
||||
LoginPage *page = (LoginPage*)GetProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP));
|
||||
|
||||
if (NULL == page)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
if (0 == LOGINPAGE_PROP)
|
||||
{
|
||||
LOGINPAGE_PROP = GlobalAddAtomW(L"NullsoftLoginPageProp");
|
||||
if (0 == LOGINPAGE_PROP)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL != lParam)
|
||||
{
|
||||
LOGINPAGECREATEPARAM *create = (LOGINPAGECREATEPARAM*)lParam;
|
||||
lParam = create->lParam;
|
||||
if (SUCCEEDED(create->fnCreator(hwnd, create->hLoginbox, &page)))
|
||||
{
|
||||
if (FALSE == SetProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP), (HANDLE)page))
|
||||
{
|
||||
delete(page);
|
||||
page = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != page)
|
||||
return page->DialogProc(uMsg, wParam, lParam);
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR result = page->DialogProc(uMsg, wParam, lParam);
|
||||
|
||||
if (WM_DESTROY == uMsg)
|
||||
{
|
||||
RemoveProp(hwnd, MAKEINTATOM(LOGINPAGE_PROP));
|
||||
delete(page);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
733
Src/auth/Loginbox/loginPopup.cpp
Normal file
733
Src/auth/Loginbox/loginPopup.cpp
Normal file
@@ -0,0 +1,733 @@
|
||||
#include "./loginPopup.h"
|
||||
#include "../api.h"
|
||||
#include "../../nu/Vectors.h"
|
||||
#include "./loginNotifier.h"
|
||||
#include "./common.h"
|
||||
|
||||
typedef Vector<HWND> WindowList;
|
||||
|
||||
typedef struct __THREADPOPUPDATA
|
||||
{
|
||||
HHOOK hHook;
|
||||
WindowList windowList;
|
||||
} THREADPOPUPDATA;
|
||||
|
||||
static size_t threadStorage = TLS_OUT_OF_INDEXES;
|
||||
|
||||
typedef struct __LOGINPOPUPCREATEPARAM
|
||||
{
|
||||
LoginPopup::Creator fnCreator;
|
||||
LPARAM lParam;
|
||||
} LOGINPOPUPCREATEPARAM;
|
||||
|
||||
#define IDC_NOTIFIER 10001
|
||||
|
||||
//#define COLOR_TITLE COLOR_3DLIGHT
|
||||
//#define COLOR_TITLETEXT COLOR_WINDOWTEXT
|
||||
#define COLOR_CLIENT COLOR_3DFACE
|
||||
#define COLOR_CLIENTTEXT COLOR_WINDOWTEXT
|
||||
|
||||
LoginPopup::LoginPopup(HWND hwnd, UINT popupType, LPCWSTR pszTitle)
|
||||
: alertType(-1), alertMessage(NULL)
|
||||
{
|
||||
buttonHeight = buttonSpace = 0;
|
||||
this->hwnd = hwnd;
|
||||
|
||||
if (NULL != pszTitle)
|
||||
SetTitle(popupType, pszTitle);
|
||||
}
|
||||
|
||||
LoginPopup::~LoginPopup()
|
||||
{
|
||||
RegisterPopup(hwnd, FALSE);
|
||||
|
||||
if (FALSE == IS_INTRESOURCE(alertMessage))
|
||||
LoginBox_FreeString(alertMessage);
|
||||
}
|
||||
|
||||
HWND LoginPopup::CreatePopup(LPCWSTR pszTemplate, HWND hParent, LPARAM param, Creator fnCreator)
|
||||
{
|
||||
if (NULL == hParent || NULL == pszTemplate || NULL == fnCreator)
|
||||
return NULL;
|
||||
|
||||
LOGINPOPUPCREATEPARAM createParam;
|
||||
createParam.fnCreator = fnCreator;
|
||||
createParam.lParam = param;
|
||||
|
||||
return WASABI_API_CREATEDIALOGPARAMW((INT)(INT_PTR)pszTemplate, hParent, LoginPopup_DialogProc, (LPARAM)&createParam);
|
||||
}
|
||||
|
||||
BOOL LoginPopup::RegisterPopup(HWND hwnd, BOOL fRegister)
|
||||
{
|
||||
if (NULL == hwnd || GetWindowThreadProcessId(hwnd, NULL) != GetCurrentThreadId())
|
||||
return FALSE;
|
||||
|
||||
THREADPOPUPDATA *data = NULL;
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
{
|
||||
if (NULL == WASABI_API_APP)
|
||||
return FALSE;
|
||||
|
||||
threadStorage = WASABI_API_APP->AllocateThreadStorage();
|
||||
if (TLS_OUT_OF_INDEXES == threadStorage)
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = (THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage);
|
||||
}
|
||||
|
||||
if (NULL == data)
|
||||
{
|
||||
data = new THREADPOPUPDATA();
|
||||
if (NULL == data) return FALSE;
|
||||
data->hHook = SetWindowsHookEx(WH_MSGFILTER, LoginPopup_MessageFilter, NULL, GetCurrentThreadId());
|
||||
if (NULL == data->hHook)
|
||||
{
|
||||
delete data;
|
||||
return FALSE;
|
||||
}
|
||||
WASABI_API_APP->SetThreadStorage(threadStorage, data);
|
||||
}
|
||||
|
||||
size_t index = data->windowList.size();
|
||||
while(index--)
|
||||
{
|
||||
if (hwnd == data->windowList[index])
|
||||
{
|
||||
if (FALSE == fRegister)
|
||||
{
|
||||
data->windowList.eraseAt(index);
|
||||
if (0 == data->windowList.size())
|
||||
{
|
||||
if (NULL != data->hHook)
|
||||
UnhookWindowsHookEx(data->hHook);
|
||||
WASABI_API_APP->SetThreadStorage(threadStorage, NULL);
|
||||
delete data;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE != fRegister)
|
||||
{
|
||||
data->windowList.push_back(hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LoginPopup::EnumeratePopups(HWND hHost, Enumerator callback, LPARAM param)
|
||||
{
|
||||
if (NULL == callback ||
|
||||
NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
|
||||
return FALSE;
|
||||
|
||||
THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
|
||||
(THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
|
||||
if (NULL == data)
|
||||
return FALSE;
|
||||
|
||||
size_t index = data->windowList.size();
|
||||
while(index--)
|
||||
{
|
||||
HWND hPopup = data->windowList[index];
|
||||
if (IsChild(hHost, hPopup) && FALSE == callback(hPopup, param))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoginPopup::AnyPopup(HWND hHost)
|
||||
{
|
||||
if (NULL == hHost || GetWindowThreadProcessId(hHost, NULL) != GetCurrentThreadId())
|
||||
return FALSE;
|
||||
|
||||
THREADPOPUPDATA *data = (TLS_OUT_OF_INDEXES != threadStorage && NULL != WASABI_API_APP) ?
|
||||
(THREADPOPUPDATA *)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
|
||||
if (NULL == data)
|
||||
return FALSE;
|
||||
|
||||
size_t index = data->windowList.size();
|
||||
while(index--)
|
||||
{
|
||||
if (IsChild(hHost, data->windowList[index]))
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPopup::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
|
||||
HWND hNotifier;
|
||||
hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
|
||||
if (NULL != hNotifier)
|
||||
{
|
||||
INT height = LoginNotifier_GetIdealHeight(hNotifier);
|
||||
SetWindowPos(hNotifier, NULL, rect.left, rect.top, rect.right - rect.left, height,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPopup::Paint(HDC hdc, const RECT *prcPaint, BOOL fErase)
|
||||
{
|
||||
if (FALSE != fErase)
|
||||
{
|
||||
RECT clientRect;
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
|
||||
COLORREF rgbOrig, rgbPart;
|
||||
rgbOrig = GetBkColor(hdc);
|
||||
|
||||
if (buttonHeight > 0)
|
||||
{
|
||||
RECT buttonRect;
|
||||
SetRect(&buttonRect,
|
||||
clientRect.left, clientRect.bottom - (2* clientMargins.bottom + buttonHeight),
|
||||
clientRect.right, clientRect.bottom);
|
||||
|
||||
clientRect.bottom = buttonRect.top;
|
||||
|
||||
buttonRect.top++;
|
||||
rgbPart = GetSysColor(COLOR_3DFACE);
|
||||
SetBkColor(hdc, rgbPart);
|
||||
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
|
||||
|
||||
buttonRect.bottom = buttonRect.top;
|
||||
buttonRect.top--;
|
||||
|
||||
rgbPart = GetSysColor(COLOR_3DLIGHT);
|
||||
SetBkColor(hdc, rgbPart);
|
||||
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &buttonRect, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
rgbPart = GetSysColor(COLOR_CLIENT);
|
||||
SetBkColor(hdc, rgbPart);
|
||||
ExtTextOut(hdc, 0, 0, ETO_OPAQUE, &clientRect, NULL, 0, NULL);
|
||||
|
||||
SetBkColor(hdc, rgbOrig);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPopup::EndDialog(INT_PTR code)
|
||||
{
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
void LoginPopup::UpdateMargins()
|
||||
{
|
||||
SetRect(&clientMargins, 8, 6, 8, 6);
|
||||
MapDialogRect(hwnd, &clientMargins);
|
||||
|
||||
SetRect(&infoMargins, 6, 8, 6, 8);
|
||||
MapDialogRect(hwnd, &infoMargins);
|
||||
|
||||
RECT rect;
|
||||
SetRect(&rect, 4, 15, 0, 0);
|
||||
MapDialogRect(hwnd, &rect);
|
||||
buttonHeight = rect.top;
|
||||
buttonSpace = rect.left;
|
||||
}
|
||||
|
||||
void LoginPopup::SetTitle(UINT type, LPCWSTR title)
|
||||
{
|
||||
popupType = type;
|
||||
|
||||
|
||||
if (NULL == title || FALSE == IS_INTRESOURCE(title))
|
||||
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)title);
|
||||
else
|
||||
{
|
||||
WCHAR szBuffer[256] = {0};
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)title, szBuffer, ARRAYSIZE(szBuffer));
|
||||
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)szBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPopup::UpdateTitle(BOOL playBeep)
|
||||
{
|
||||
HWND hNotifier;
|
||||
hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
|
||||
if (NULL == hNotifier) return;
|
||||
|
||||
WCHAR szBuffer[512] = {0};
|
||||
LPCWSTR text;
|
||||
UINT type;
|
||||
|
||||
if (-1 != alertType && NULL != alertMessage)
|
||||
{
|
||||
type = alertType;
|
||||
text = (IS_INTRESOURCE(alertMessage)) ?
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)alertMessage, szBuffer, ARRAYSIZE(szBuffer)) :
|
||||
alertMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
type = popupType;
|
||||
SendMessage(hwnd, WM_GETTEXT, (WPARAM)ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
|
||||
text = szBuffer;
|
||||
}
|
||||
|
||||
LoginNotifier_Notify(hNotifier, type, text);
|
||||
|
||||
UINT windowStyle = GetWindowStyle(hNotifier);
|
||||
if (0 == (WS_VISIBLE & windowStyle))
|
||||
{
|
||||
ShowWindow(hNotifier, SW_SHOWNA);
|
||||
}
|
||||
|
||||
if (FALSE != playBeep)
|
||||
LoginNotifier_PlayBeep(hNotifier);
|
||||
}
|
||||
|
||||
void LoginPopup::SetAlert(UINT type, LPCWSTR message)
|
||||
{
|
||||
alertType = type;
|
||||
|
||||
if (FALSE == IS_INTRESOURCE(alertMessage))
|
||||
LoginBox_FreeString(alertMessage);
|
||||
|
||||
if (NULL == message)
|
||||
{
|
||||
alertMessage = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_INTRESOURCE(message))
|
||||
alertMessage = (LPWSTR)message;
|
||||
else
|
||||
alertMessage = LoginBox_CopyString(message);
|
||||
}
|
||||
|
||||
void LoginPopup::RemoveAlert()
|
||||
{
|
||||
SetAlert(-1, NULL);
|
||||
}
|
||||
|
||||
LRESULT LoginPopup::SendNotification(UINT code, NMHDR *pnmh)
|
||||
{
|
||||
if (NULL == pnmh) return 0L;
|
||||
|
||||
HWND hParent = GetAncestor(hwnd, GA_PARENT);
|
||||
if(NULL == hParent) return 0L;
|
||||
|
||||
pnmh->code = code;
|
||||
pnmh->hwndFrom = hwnd;
|
||||
pnmh->idFrom = (UINT_PTR)GetWindowLongPtr(hwnd, GWLP_ID);
|
||||
|
||||
return SendMessage(hParent, WM_NOTIFY, (WPARAM)pnmh->idFrom, (LPARAM)pnmh);
|
||||
}
|
||||
|
||||
|
||||
BOOL LoginPopup::GetInfoRect(RECT *rect)
|
||||
{
|
||||
if (NULL == rect)
|
||||
return FALSE;
|
||||
|
||||
LONG notifierHeight = 0;
|
||||
HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
|
||||
if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
|
||||
FALSE != GetWindowRect(hNotifier, rect))
|
||||
{
|
||||
notifierHeight = rect->bottom - rect->top;
|
||||
if (notifierHeight < 0) notifierHeight = 0;
|
||||
}
|
||||
|
||||
if (FALSE == GetClientRect(hwnd, rect))
|
||||
return FALSE;
|
||||
|
||||
rect->left += (clientMargins.left + infoMargins.left);
|
||||
rect->right -= (clientMargins.right + infoMargins.right);
|
||||
|
||||
|
||||
if (0 != notifierHeight)
|
||||
rect->top += (notifierHeight + infoMargins.top);
|
||||
else
|
||||
rect->top += (clientMargins.top + infoMargins.top);
|
||||
|
||||
if (buttonHeight > 0)
|
||||
rect->bottom -= (2 * clientMargins.bottom + buttonHeight + infoMargins.bottom);
|
||||
else
|
||||
rect->bottom -= (clientMargins.bottom + infoMargins.bottom);
|
||||
|
||||
if (rect->right < rect->left) rect->right = rect->left;
|
||||
if (rect->bottom < rect->top) rect->bottom = rect->top;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoginPopup::CalculateWindowRect(LONG infoWidth, LONG infoHeight, const INT *buttonList, UINT buttonCount, BOOL includeTitle, RECT *rect)
|
||||
{
|
||||
if (NULL == rect)
|
||||
return FALSE;
|
||||
|
||||
if (infoWidth < 110) infoWidth = 110;
|
||||
if (infoHeight < 32) infoHeight = 32;
|
||||
|
||||
LONG minWidth = 0;
|
||||
|
||||
LONG notifierHeight = 0;
|
||||
|
||||
HWND hNotifier = GetDlgItem(hwnd, IDC_NOTIFIER);
|
||||
if (NULL != hNotifier && 0 != (WS_VISIBLE & GetWindowStyle(hNotifier)) &&
|
||||
FALSE != GetWindowRect(hNotifier, rect))
|
||||
{
|
||||
notifierHeight = rect->bottom - rect->top;
|
||||
if (notifierHeight < 0) notifierHeight = 0;
|
||||
|
||||
if (FALSE != includeTitle)
|
||||
{
|
||||
SIZE size;
|
||||
if (FALSE != LoginNotifier_GetIdealSize(hNotifier, &size))
|
||||
minWidth = size.cx + clientMargins.right;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != buttonList && buttonCount > 0 &&
|
||||
((HDWP)TRUE) == LayoutButtons(NULL, buttonList, buttonCount, FALSE, rect))
|
||||
{
|
||||
LONG buttonWidth = (rect->right - rect->left) + clientMargins.left + clientMargins.right;
|
||||
if (buttonWidth > minWidth)
|
||||
minWidth = buttonWidth;
|
||||
}
|
||||
|
||||
rect->left = 0;
|
||||
rect->top = 0;
|
||||
rect->right = rect->left + infoWidth;
|
||||
rect->bottom = rect->top + infoHeight;
|
||||
|
||||
rect->right += (clientMargins.left + infoMargins.left + clientMargins.right + infoMargins.right);
|
||||
if ((rect->right - rect->left) < minWidth)
|
||||
rect->right = rect->left + minWidth;
|
||||
|
||||
rect->bottom += (0 != notifierHeight) ?
|
||||
(notifierHeight + infoMargins.top) : (clientMargins.top + infoMargins.top);
|
||||
|
||||
rect->bottom += (buttonHeight > 0) ?
|
||||
(2 * clientMargins.bottom + buttonHeight + infoMargins.bottom) : (clientMargins.bottom + infoMargins.bottom);
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
HDWP LoginPopup::LayoutButtons(HDWP hdwp, const INT *buttonList, UINT buttonCount, BOOL redraw, RECT *rectOut)
|
||||
{
|
||||
RECT rect;
|
||||
GetClientRect(hwnd, &rect);
|
||||
rect.left += clientMargins.left;
|
||||
rect.top += clientMargins.top;
|
||||
rect.right -= clientMargins.right;
|
||||
rect.bottom -= clientMargins.bottom;
|
||||
|
||||
return LoginBox_LayoutButtonBar(hdwp, hwnd, buttonList, buttonCount, &rect,
|
||||
buttonHeight, buttonSpace, redraw, rectOut);
|
||||
}
|
||||
|
||||
BOOL LoginPopup::GetTextSize(HWND hText, LONG width, SIZE *size)
|
||||
{
|
||||
if (NULL == hText) return FALSE;
|
||||
|
||||
WCHAR szBuffer[4096] = {0};
|
||||
INT cchLen = (INT)SendMessage(hText, WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
|
||||
if (0 == cchLen)
|
||||
{
|
||||
size->cx = 0;
|
||||
size->cy = 0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HDC hdc = GetDCEx(hText, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
|
||||
if (NULL == hdc)
|
||||
return FALSE;
|
||||
|
||||
HFONT font = (HFONT)SendMessage(hText, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
BOOL resultOk;
|
||||
RECT rect;
|
||||
SetRect(&rect, 0, 0, width, 0);
|
||||
resultOk = DrawText(hdc, szBuffer, cchLen, &rect,
|
||||
DT_CALCRECT | DT_EXTERNALLEADING | DT_LEFT | DT_NOPREFIX | DT_WORDBREAK);
|
||||
|
||||
if(FALSE != resultOk)
|
||||
{
|
||||
size->cx = (rect.right - rect.left);
|
||||
size->cy = (rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hText, hdc);
|
||||
|
||||
return resultOk;
|
||||
}
|
||||
|
||||
BOOL LoginPopup::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
RegisterPopup(hwnd, TRUE);
|
||||
|
||||
RECT rect;
|
||||
if (FALSE == GetWindowRect(hwnd, &rect))
|
||||
SetRectEmpty(&rect);
|
||||
|
||||
idealSize.cx = rect.right - rect.left;
|
||||
idealSize.cy = rect.bottom - rect.top;
|
||||
|
||||
|
||||
HWND hNotifier = LoginNotifier_CreateWindow(0, WS_CHILD | WS_CLIPSIBLINGS, 0, 0, 0, 0, hwnd, IDC_NOTIFIER);
|
||||
if (NULL != hNotifier)
|
||||
{
|
||||
HFONT hFont = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
|
||||
if (NULL != hFont)
|
||||
SendMessage(hNotifier, WM_SETFONT, (WPARAM)hFont, 0L);
|
||||
|
||||
#ifdef COLOR_TITLE
|
||||
LoginNotifier_SetBkColor(hNotifier, GetSysColor(COLOR_TITLE));
|
||||
#endif //COLOR_TITLE
|
||||
|
||||
#ifdef COLOR_TITLETEXT
|
||||
LoginNotifier_SetTextColor(hNotifier, GetSysColor(COLOR_TITLETEXT));
|
||||
#endif //COLOR_TITLETEXT
|
||||
|
||||
UpdateTitle(FALSE);
|
||||
}
|
||||
|
||||
UpdateMargins();
|
||||
UpdateLayout(FALSE);
|
||||
|
||||
PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPopup::OnDestroy()
|
||||
{
|
||||
}
|
||||
|
||||
void LoginPopup::OnWindowPosChanged(const WINDOWPOS *pwp)
|
||||
{
|
||||
if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
||||
UpdateLayout(0 == (SWP_NOREDRAW & pwp->flags));
|
||||
}
|
||||
|
||||
void LoginPopup::OnCommand(UINT commandId, UINT eventType, HWND hControl)
|
||||
{
|
||||
switch(commandId)
|
||||
{
|
||||
case IDOK:
|
||||
case IDCANCEL:
|
||||
EndDialog(commandId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT LoginPopup::OnNotify(UINT controlId, const NMHDR *pnmh)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPopup::OnPaint()
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
if (BeginPaint(hwnd, &ps))
|
||||
{
|
||||
if (ps.rcPaint.left != ps.rcPaint.right)
|
||||
Paint(ps.hdc, &ps.rcPaint, ps.fErase);
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPopup::OnPrintClient(HDC hdc, UINT options)
|
||||
{
|
||||
if (0 != (PRF_CLIENT & options))
|
||||
{
|
||||
RECT clientRect;
|
||||
if (GetClientRect(hwnd, &clientRect))
|
||||
Paint(hdc, &clientRect, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
HBRUSH LoginPopup::OnGetStaticColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
HBRUSH hb = (HBRUSH)GetSysColorBrush(COLOR_CLIENT);
|
||||
SetTextColor(hdc, GetSysColor(COLOR_CLIENTTEXT));
|
||||
SetBkColor(hdc, GetSysColor(COLOR_CLIENT));
|
||||
return hb;
|
||||
}
|
||||
|
||||
void LoginPopup::OnSetFont(HFONT font, BOOL redraw)
|
||||
{
|
||||
DefDlgProc(hwnd, WM_SETFONT, (WPARAM)font, MAKELPARAM(redraw, 0));
|
||||
UpdateMargins();
|
||||
}
|
||||
|
||||
void LoginPopup::OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LoginPopup::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
|
||||
{
|
||||
if (NULL == clientRect || NULL == rectOut)
|
||||
return FALSE;
|
||||
|
||||
LONG width = idealSize.cx;
|
||||
LONG height = idealSize.cy;
|
||||
rectOut->left = clientRect->left + ((clientRect->right - clientRect->left) - width)/2;
|
||||
rectOut->top = clientRect->top+ ((clientRect->bottom - clientRect->top) - height)/2;
|
||||
rectOut->right = rectOut->left + width;
|
||||
rectOut->bottom = rectOut->top + height;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LoginPopup::OnPlayBeep()
|
||||
{
|
||||
LoginBox_MessageBeep(MB_ICONASTERISK);
|
||||
}
|
||||
|
||||
INT_PTR LoginPopup::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
|
||||
case WM_DESTROY: OnDestroy(); return TRUE;
|
||||
case WM_NOTIFY: MSGRESULT(hwnd, OnNotify((INT)wParam, (NMHDR*)lParam));
|
||||
case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
|
||||
case WM_WINDOWPOSCHANGED: OnWindowPosChanged((WINDOWPOS*)lParam); return TRUE;
|
||||
case WM_SIZE: return TRUE;
|
||||
case WM_SETFONT: OnSetFont((HFONT)wParam, (BOOL)LOWORD(lParam)); return TRUE;
|
||||
case WM_ERASEBKGND: MSGRESULT(hwnd, 0);
|
||||
case WM_PAINT: OnPaint(); return TRUE;
|
||||
case WM_PRINTCLIENT: OnPrintClient((HDC)wParam, (UINT)lParam); return TRUE;
|
||||
case WM_CTLCOLORSTATIC: return (INT_PTR)OnGetStaticColor((HDC)wParam, (HWND)lParam);
|
||||
case WM_PARENTNOTIFY: OnParentNotify(LOWORD(wParam), HIWORD(wParam), lParam); return TRUE;
|
||||
|
||||
case NLPOPUP_UPDATEWNDPOS: MSGRESULT(hwnd, OnUpdateWindowPos((const RECT*)wParam, (RECT*)lParam));
|
||||
case NLPOPUP_PLAYBEEP: OnPlayBeep(); return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK LoginPopup_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static ATOM LOGINPOPUP_PROP = 0;
|
||||
LoginPopup *popup = (LoginPopup*)GetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
|
||||
|
||||
if (NULL == popup)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
if (0 == LOGINPOPUP_PROP)
|
||||
{
|
||||
LOGINPOPUP_PROP = GlobalAddAtomW(L"NullsoftLoginPopupProp");
|
||||
if (0 == LOGINPOPUP_PROP)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (NULL != lParam)
|
||||
{
|
||||
LOGINPOPUPCREATEPARAM *create = (LOGINPOPUPCREATEPARAM*)lParam;
|
||||
lParam = create->lParam;
|
||||
if (SUCCEEDED(create->fnCreator(hwnd, lParam, &popup)))
|
||||
{
|
||||
if (FALSE == SetProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP), (HANDLE)popup))
|
||||
{
|
||||
delete(popup);
|
||||
popup = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != popup)
|
||||
return popup->DialogProc(uMsg, wParam, lParam);
|
||||
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR result = popup->DialogProc(uMsg, wParam, lParam);
|
||||
|
||||
if (WM_NCDESTROY == uMsg)
|
||||
{
|
||||
RemoveProp(hwnd, MAKEINTATOM(LOGINPOPUP_PROP));
|
||||
delete(popup);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK LoginPopup_MessageFilter(INT code, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
THREADPOPUPDATA *data = (NULL != WASABI_API_APP && TLS_OUT_OF_INDEXES != threadStorage) ?
|
||||
(THREADPOPUPDATA*)WASABI_API_APP->GetThreadStorage(threadStorage) : NULL;
|
||||
if (NULL == data)
|
||||
return 0;
|
||||
|
||||
if (code >= 0)
|
||||
{
|
||||
MSG *pMsg = (MSG*)lParam;
|
||||
if (pMsg->message >= WM_KEYFIRST && pMsg->message <= WM_KEYLAST)
|
||||
{
|
||||
if (L'C' == pMsg->wParam && 0 == (0x40000000 & pMsg->lParam) &&
|
||||
0 != (0x8000 & GetAsyncKeyState(VK_MENU)))
|
||||
{
|
||||
pMsg->wParam = VK_ESCAPE;
|
||||
}
|
||||
|
||||
if ((VK_ESCAPE == pMsg->wParam || VK_RETURN == pMsg->wParam) &&
|
||||
0 == (0x40000000 & pMsg->lParam))
|
||||
{
|
||||
size_t index = data->windowList.size();
|
||||
while(index--)
|
||||
{
|
||||
HWND hPopup = data->windowList[index];
|
||||
if (IsChild(hPopup, pMsg->hwnd))
|
||||
{
|
||||
INT commandId;
|
||||
switch(pMsg->wParam)
|
||||
{
|
||||
case VK_ESCAPE:
|
||||
commandId = IDCANCEL;
|
||||
break;
|
||||
case VK_RETURN:
|
||||
if (0 != (DLGC_BUTTON & SendMessage(pMsg->hwnd, WM_GETDLGCODE, 0, 0L)) &&
|
||||
IsWindowVisible(pMsg->hwnd) && IsWindowEnabled(pMsg->hwnd))
|
||||
{
|
||||
commandId = (INT)(INT_PTR)GetWindowLongPtr(pMsg->hwnd, GWLP_ID);
|
||||
}
|
||||
else
|
||||
{
|
||||
commandId = (INT)(INT_PTR)SendMessage(hPopup, DM_GETDEFID, 0, 0L);
|
||||
if (DC_HASDEFID != HIWORD(commandId))
|
||||
commandId = IDOK;
|
||||
}
|
||||
break;
|
||||
}
|
||||
SendMessage(hPopup, WM_COMMAND, MAKEWPARAM(commandId, 0), (LPARAM)pMsg->hwnd);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add mnemonic support here (http://msdn.microsoft.com/en-us/library/ms644995%28VS.85%29.aspx)
|
||||
//HWND hPopup;
|
||||
//size_t index = data->windowList.size();
|
||||
//while(index--)
|
||||
//{
|
||||
// hPopup = data->windowList[index];
|
||||
// if (pMsg->hwnd == hPopup || IsChild(hPopup, pMsg->hwnd))
|
||||
// {
|
||||
//
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
return CallNextHookEx(data->hHook, code, wParam, lParam);
|
||||
}
|
||||
100
Src/auth/Loginbox/loginPopup.h
Normal file
100
Src/auth/Loginbox/loginPopup.h
Normal file
@@ -0,0 +1,100 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPOPUP_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPOPUP_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
// messages
|
||||
#define NLPOPUP_FIRST (WM_APP + 100)
|
||||
#define NLPOPUP_UPDATEWNDPOS (NLPOPUP_FIRST + 0) // wParam - (WPARAM)(const RECT*)clientRect, lParam = (LPARAM)(RECT*)popupRectOut; Return TRUE if you set controlRect;
|
||||
#define LoginPopup_UpdateWindowPos(/*HWND*/ __hwnd, /*const RECT* */__clientRect, /*RECT* */__popupRectOut)\
|
||||
((BOOL)SNDMSG((__hwnd), NLPOPUP_UPDATEWNDPOS, (WPARAM)(__clientRect), (LPARAM)(__popupRectOut)))
|
||||
|
||||
#define NLPOPUP_PLAYBEEP (NLPOPUP_FIRST + 1) // wParam - not used, lParam - not used; Return ignored
|
||||
#define LoginPopup_PlayBeep(/*HWND*/ __hwnd)\
|
||||
(SNDMSG((__hwnd), NLPOPUP_PLAYBEEP, 0, 0L))
|
||||
|
||||
// notifications
|
||||
#define NLPOPUPN_FIRST (100)
|
||||
|
||||
typedef struct __NLPNRESULT
|
||||
{
|
||||
NMHDR hdr;
|
||||
INT_PTR exitCode;
|
||||
} NLPNRESULT;
|
||||
|
||||
#define NLPN_RESULT (NLPOPUPN_FIRST + 0)
|
||||
|
||||
class __declspec(novtable) LoginPopup
|
||||
{
|
||||
public:
|
||||
typedef HRESULT (CALLBACK *Creator)(HWND /*hwnd*/, LPARAM /*param*/, LoginPopup** /*instance*/);
|
||||
typedef BOOL (CALLBACK *Enumerator)(HWND /*hwnd*/, LPARAM /*param*/);
|
||||
|
||||
protected:
|
||||
LoginPopup(HWND hwnd, UINT popupType, LPCWSTR pszTitle);
|
||||
virtual ~LoginPopup();
|
||||
|
||||
protected:
|
||||
static HWND CreatePopup(LPCWSTR pszTemplate, HWND hParent, LPARAM param, Creator fnCreator);
|
||||
|
||||
public:
|
||||
static BOOL RegisterPopup(HWND hwnd, BOOL fRegister);
|
||||
static BOOL EnumeratePopups(HWND hHost, Enumerator callback, LPARAM param);
|
||||
static BOOL AnyPopup(HWND hHost);
|
||||
|
||||
protected:
|
||||
virtual void UpdateLayout(BOOL fRedraw);
|
||||
virtual void Paint(HDC hdc, const RECT *prcPaint, BOOL fErase);
|
||||
virtual void EndDialog(INT_PTR code);
|
||||
virtual void UpdateMargins();
|
||||
virtual void SetTitle(UINT type, LPCWSTR title);
|
||||
virtual void SetAlert(UINT type, LPCWSTR message);
|
||||
virtual void RemoveAlert();
|
||||
virtual void UpdateTitle(BOOL playBeep);
|
||||
|
||||
BOOL GetInfoRect(RECT *rect);
|
||||
BOOL CalculateWindowRect(LONG infoWidth, LONG infoHeight, const INT *buttonList, UINT buttonCount, BOOL includeTitle, RECT *rect);
|
||||
|
||||
HDWP LayoutButtons(HDWP hdwp, const INT *buttonList, UINT buttonCount, BOOL redraw, RECT *rectOut);
|
||||
LRESULT SendNotification(UINT code, NMHDR *pnmh);
|
||||
BOOL GetTextSize(HWND hText, LONG width, SIZE *size);
|
||||
|
||||
protected:
|
||||
virtual BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
virtual void OnDestroy();
|
||||
virtual void OnCommand(UINT commandId, UINT eventType, HWND hControl);
|
||||
virtual LRESULT OnNotify(UINT controlId, const NMHDR *pnmh);
|
||||
virtual HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
virtual void OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam);
|
||||
|
||||
void OnPaint();
|
||||
void OnWindowPosChanged(const WINDOWPOS *pwp);
|
||||
void OnPrintClient(HDC hdc, UINT options);
|
||||
void OnSetFont(HFONT font, BOOL redraw);
|
||||
|
||||
virtual BOOL OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut);
|
||||
virtual void OnPlayBeep();
|
||||
|
||||
virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
friend static INT_PTR CALLBACK LoginPopup_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
friend static LRESULT CALLBACK LoginPopup_MessageFilter(INT code, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
HWND hwnd;
|
||||
SIZE idealSize;
|
||||
RECT clientMargins;
|
||||
RECT infoMargins;
|
||||
LONG buttonHeight;
|
||||
LONG buttonSpace;
|
||||
UINT popupType;
|
||||
UINT alertType;
|
||||
LPWSTR alertMessage;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPOPUP_HEADER
|
||||
231
Src/auth/Loginbox/loginProvider.cpp
Normal file
231
Src/auth/Loginbox/loginProvider.cpp
Normal file
@@ -0,0 +1,231 @@
|
||||
#include "./loginProvider.h"
|
||||
#include "./loginTemplate.h"
|
||||
#include "./loginCommand.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
|
||||
static HRESULT LoginProvider_SetString(LPWSTR *ppszTarget, LPCWSTR pszSource)
|
||||
{
|
||||
if (NULL == ppszTarget)
|
||||
return E_POINTER;
|
||||
if (NULL != *ppszTarget)
|
||||
free(*ppszTarget);
|
||||
|
||||
|
||||
if (NULL == pszSource)
|
||||
*ppszTarget = NULL;
|
||||
else
|
||||
{
|
||||
*ppszTarget = LoginBox_CopyString(pszSource);
|
||||
if (NULL == *ppszTarget) return E_OUTOFMEMORY;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginProvider::LoginProvider(const GUID *providerUid)
|
||||
: ref(1), name(NULL), description(NULL), imagePath(NULL), tosUrl(NULL),
|
||||
privacyUrl(NULL), helpUrl(NULL), pageTemplate(NULL), command(NULL)
|
||||
{
|
||||
id = (NULL != providerUid) ? *providerUid : GUID_NULL;
|
||||
}
|
||||
|
||||
LoginProvider::~LoginProvider()
|
||||
{
|
||||
LoginBox_FreeString(name);
|
||||
LoginBox_FreeString(description);
|
||||
LoginBox_FreeString(imagePath);
|
||||
LoginBox_FreeString(tosUrl);
|
||||
LoginBox_FreeString(privacyUrl);
|
||||
LoginBox_FreeString(helpUrl);
|
||||
if (NULL != pageTemplate) pageTemplate->Release();
|
||||
if (NULL != command) command->Release();
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::CreateInstance(const GUID *providerUid, LoginProvider **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == providerUid) return E_INVALIDARG;
|
||||
*instance = new LoginProvider(providerUid);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
ULONG LoginProvider::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginProvider::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::IsIdentical(LoginProvider *test)
|
||||
{
|
||||
if (NULL == test)
|
||||
return E_INVALIDARG;
|
||||
|
||||
if (FALSE == IsEqualGUID(id, test->id))
|
||||
return S_FALSE;
|
||||
|
||||
|
||||
if (S_OK != LoginBox_IsStrEq(name, test->name) ||
|
||||
S_OK != LoginBox_IsStrEq(description, test->description) ||
|
||||
S_OK != LoginBox_IsStrEqInvI(imagePath, test->imagePath) ||
|
||||
S_OK != LoginBox_IsStrEqInvI(tosUrl, test->tosUrl) ||
|
||||
S_OK != LoginBox_IsStrEqInvI(privacyUrl, test->privacyUrl) ||
|
||||
S_OK != LoginBox_IsStrEqInvI(helpUrl, test->helpUrl))
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
if ((NULL == pageTemplate) != (NULL == test->pageTemplate))
|
||||
return S_FALSE;
|
||||
|
||||
if (NULL != pageTemplate)
|
||||
{
|
||||
HRESULT hr = pageTemplate->IsIdentical(test->pageTemplate);
|
||||
if (S_OK != hr) return hr;
|
||||
}
|
||||
|
||||
if ((NULL == command) != (NULL == test->command))
|
||||
return S_FALSE;
|
||||
|
||||
if (NULL != command)
|
||||
{
|
||||
HRESULT hr = command->IsIdentical(test->command);
|
||||
if (S_OK != hr) return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::IsValid()
|
||||
{
|
||||
return (NULL != pageTemplate && NULL != command) ? S_OK :S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetId(GUID *pId)
|
||||
{
|
||||
if (NULL == pId) return E_POINTER;
|
||||
*pId = id;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetName(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, name, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetDescription(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, description, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetImagePath(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, imagePath, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetTosLink(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, tosUrl, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetPrivacyLink(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, privacyUrl, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetHelpLink(LPWSTR pszBuffer, UINT cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer) return E_INVALIDARG;
|
||||
return StringCchCopyEx(pszBuffer, cchBufferMax, helpUrl, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetTemplate(LoginTemplate **ppTemplate)
|
||||
{
|
||||
if (NULL == ppTemplate)
|
||||
return E_POINTER;
|
||||
|
||||
*ppTemplate = pageTemplate;
|
||||
if (NULL != pageTemplate)
|
||||
pageTemplate->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::GetCommand(LoginCommand **ppCommand)
|
||||
{
|
||||
if (NULL == ppCommand)
|
||||
return E_POINTER;
|
||||
|
||||
*ppCommand = command;
|
||||
if (NULL != command)
|
||||
command->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetName(LPCWSTR pszName)
|
||||
{
|
||||
return LoginProvider_SetString(&name, pszName);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetDescription(LPCWSTR pszDescription)
|
||||
{
|
||||
return LoginProvider_SetString(&description, pszDescription);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetImagePath(LPCWSTR pszImagePath)
|
||||
{
|
||||
return LoginProvider_SetString(&imagePath, pszImagePath);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetTosLink(LPCWSTR pszUrl)
|
||||
{
|
||||
return LoginProvider_SetString(&tosUrl, pszUrl);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetPrivacyLink(LPCWSTR pszUrl)
|
||||
{
|
||||
return LoginProvider_SetString(&privacyUrl, pszUrl);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetHelpLink(LPCWSTR pszUrl)
|
||||
{
|
||||
return LoginProvider_SetString(&helpUrl, pszUrl);
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetTemplate(LoginTemplate *pTemplate)
|
||||
{
|
||||
if (NULL != pageTemplate) pageTemplate->Release();
|
||||
pageTemplate = pTemplate;
|
||||
if (NULL != pageTemplate) pageTemplate->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProvider::SetCommand(LoginCommand *pCommand)
|
||||
{
|
||||
if (NULL != command) command->Release();
|
||||
command = pCommand;
|
||||
if (NULL != command) command->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
64
Src/auth/Loginbox/loginProvider.h
Normal file
64
Src/auth/Loginbox/loginProvider.h
Normal file
@@ -0,0 +1,64 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPROVIDER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPROVIDER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginTemplate;
|
||||
class LoginCommand;
|
||||
|
||||
class LoginProvider
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginProvider(const GUID *providerUid);
|
||||
virtual ~LoginProvider();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(const GUID *providerUid, LoginProvider **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
HRESULT IsIdentical(LoginProvider *test);
|
||||
HRESULT IsValid();
|
||||
|
||||
// get
|
||||
HRESULT GetId(GUID *pId);
|
||||
HRESULT GetName(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetDescription(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetImagePath(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetTosLink(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetPrivacyLink(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetHelpLink(LPWSTR pszBuffer, UINT cchBufferMax);
|
||||
HRESULT GetTemplate(LoginTemplate **ppTemplate);
|
||||
HRESULT GetCommand(LoginCommand **ppCommand);
|
||||
|
||||
// set
|
||||
HRESULT SetName(LPCWSTR pszName);
|
||||
HRESULT SetDescription(LPCWSTR pszDescription);
|
||||
HRESULT SetImagePath(LPCWSTR pszImagePath);
|
||||
HRESULT SetTosLink(LPCWSTR pszUrl);
|
||||
HRESULT SetPrivacyLink(LPCWSTR pszUrl);
|
||||
HRESULT SetHelpLink(LPCWSTR pszUrl);
|
||||
HRESULT SetTemplate(LoginTemplate *pTemplate);
|
||||
HRESULT SetCommand(LoginCommand *pCommand);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
GUID id;
|
||||
LPWSTR name;
|
||||
LPWSTR description;
|
||||
LPWSTR imagePath;
|
||||
LPWSTR tosUrl;
|
||||
LPWSTR privacyUrl;
|
||||
LPWSTR helpUrl;
|
||||
LoginTemplate *pageTemplate;
|
||||
LoginCommand *command;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPROVIDER_HEADER
|
||||
35
Src/auth/Loginbox/loginResult.h
Normal file
35
Src/auth/Loginbox/loginResult.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINRESULT_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINRESULT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginData;
|
||||
|
||||
class __declspec(novtable) LoginResult : public IUnknown
|
||||
{
|
||||
|
||||
public:
|
||||
typedef void (CALLBACK *Callback)(LoginResult *result);
|
||||
|
||||
protected:
|
||||
LoginResult() {}
|
||||
~LoginResult() {}
|
||||
|
||||
public:
|
||||
|
||||
virtual HRESULT GetLoginData(LoginData **loginData) = 0;
|
||||
|
||||
virtual HRESULT GetWaitHandle(HANDLE *handle) = 0;
|
||||
virtual HRESULT GetUser(void **user) = 0;
|
||||
virtual HRESULT RequestAbort(BOOL fDrop) = 0;
|
||||
virtual HRESULT IsCompleted() = 0;
|
||||
virtual HRESULT IsAborting() = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINRESULT_HEADER
|
||||
159
Src/auth/Loginbox/loginStatus.cpp
Normal file
159
Src/auth/Loginbox/loginStatus.cpp
Normal file
@@ -0,0 +1,159 @@
|
||||
#include "./loginStatus.h"
|
||||
#include "./common.h"
|
||||
|
||||
|
||||
LoginStatus::LoginStatus(HWND hTarget)
|
||||
: ref(1), hwnd(hTarget)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
}
|
||||
LoginStatus::~LoginStatus()
|
||||
{
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT LoginStatus::CreateInstance(HWND hTarget, LoginStatus **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
*instance = new LoginStatus(hTarget);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
ULONG LoginStatus::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginStatus::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
UINT LoginStatus::Add(BSTR status)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
Record r;
|
||||
r.cookie = GetNextCookie();
|
||||
r.text = status;
|
||||
list.push_back(r);
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
UpdateWindowText();
|
||||
return r.cookie;
|
||||
}
|
||||
|
||||
BOOL LoginStatus::Set(UINT cookie, BSTR status)
|
||||
{
|
||||
BOOL foundOk = FALSE;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (cookie == list[index].cookie)
|
||||
{
|
||||
SysFreeString(list[index].text);
|
||||
list[index].text = status;
|
||||
foundOk = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
UpdateWindowText();
|
||||
return foundOk;
|
||||
}
|
||||
|
||||
void LoginStatus::Remove(UINT cookie)
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (cookie == list[index].cookie)
|
||||
{
|
||||
SysFreeString(list[index].text);
|
||||
list.eraseAt(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
UpdateWindowText();
|
||||
}
|
||||
|
||||
BOOL LoginStatus::AttachWindow(HWND hTarget)
|
||||
{
|
||||
DetachWindow();
|
||||
|
||||
hwnd = hTarget;
|
||||
UpdateWindowText();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoginStatus::DetachWindow()
|
||||
{
|
||||
hwnd = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT LoginStatus::GetNextCookie()
|
||||
{
|
||||
size_t i, count;
|
||||
|
||||
count = list.size();
|
||||
UINT cookie = (UINT)count;
|
||||
|
||||
do
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
if (list[i].cookie == cookie)
|
||||
{
|
||||
cookie++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while(i != count);
|
||||
return cookie;
|
||||
}
|
||||
|
||||
BOOL LoginStatus::UpdateWindowText()
|
||||
{
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
BOOL resultOk = FALSE;
|
||||
if (NULL != hwnd)
|
||||
{
|
||||
BSTR text = NULL;
|
||||
size_t index = list.size();
|
||||
while(index--)
|
||||
{
|
||||
if (NULL != list[index].text && L'\0' != list[index].text)
|
||||
{
|
||||
text = list[index].text;
|
||||
break;
|
||||
}
|
||||
}
|
||||
resultOk = (BOOL)SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)text);
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
return resultOk;
|
||||
}
|
||||
|
||||
53
Src/auth/Loginbox/loginStatus.h
Normal file
53
Src/auth/Loginbox/loginStatus.h
Normal file
@@ -0,0 +1,53 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_STATUS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_STATUS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../nu/Vectors.h"
|
||||
|
||||
class LoginStatus
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginStatus(HWND hTarget);
|
||||
~LoginStatus();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(HWND hTarget, LoginStatus **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
UINT Add(BSTR status);
|
||||
BOOL Set(UINT cookie, BSTR status);
|
||||
void Remove(UINT cookie);
|
||||
|
||||
BOOL AttachWindow(HWND hTarget);
|
||||
BOOL DetachWindow();
|
||||
|
||||
protected:
|
||||
BOOL UpdateWindowText();
|
||||
UINT GetNextCookie();
|
||||
|
||||
protected:
|
||||
typedef struct __Record
|
||||
{
|
||||
UINT cookie;
|
||||
BSTR text;
|
||||
} Record;
|
||||
|
||||
typedef Vector<Record> RecordList;
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
HWND hwnd;
|
||||
RecordList list;
|
||||
CRITICAL_SECTION lock;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_STATUS_HEADER
|
||||
3192
Src/auth/Loginbox/loginTab.cpp
Normal file
3192
Src/auth/Loginbox/loginTab.cpp
Normal file
File diff suppressed because it is too large
Load Diff
157
Src/auth/Loginbox/loginTab.h
Normal file
157
Src/auth/Loginbox/loginTab.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_TAB_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_TAB_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#define NWC_LOGINTAB L"NullsoftLoginTab"
|
||||
|
||||
BOOL LoginTab_RegisterClass(HINSTANCE hInstance);
|
||||
HWND LoginTab_CreateWindow(UINT styleEx, LPCWSTR pszTitle, UINT style, INT x, INT y, INT cx, INT cy, HWND hParent, INT_PTR controlId);
|
||||
|
||||
typedef struct __NLTITEM
|
||||
{
|
||||
UINT mask;
|
||||
UINT dwState;
|
||||
UINT dwStateMask;
|
||||
LPWSTR pszText;
|
||||
UINT cchTextMax;
|
||||
UINT iImage;
|
||||
UINT iImageActive;
|
||||
UINT iImageDisabled;
|
||||
LPARAM param;
|
||||
} NLTITEM;
|
||||
|
||||
// Item mask flags
|
||||
#define NLTIF_STATE 0x00000001
|
||||
#define NLTIF_TEXT 0x00000002
|
||||
#define NLTIF_PARAM 0x00000004
|
||||
#define NLTIF_IMAGE_MASK (NLTIF_IMAGE | NLTIF_IMAGE_ACTIVE | NLTIF_IMAGE_DISABLED)
|
||||
#define NLTIF_IMAGE 0x00000010
|
||||
#define NLTIF_IMAGE_ACTIVE 0x00000020
|
||||
#define NLTIF_IMAGE_DISABLED 0x00000040
|
||||
|
||||
// Item states
|
||||
#define NLTIS_PRESSED 0x00000001
|
||||
#define NLTIS_HIGHLIGHTED 0x00000002
|
||||
#define NLTIS_SELECTED 0x00000004
|
||||
#define NLTIS_DISABLED 0x00000008
|
||||
|
||||
// image index values
|
||||
#define NLTM_IMAGE_NONE ((UINT)-1)
|
||||
#define NLTM_IMAGE_CALLBACK ((UINT)-2)
|
||||
|
||||
// Messages
|
||||
#define NLTM_FIRST (WM_USER + 10)
|
||||
|
||||
#define NLTM_GETIDEALHEIGHT (NLTM_FIRST + 0) // wParam - not used, lParam - not used; Return ideal height.
|
||||
#define LoginTab_GetIdealHeight(/*HWND*/ __hwnd)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_GETIDEALHEIGHT, 0, 0L))
|
||||
|
||||
#define NLTM_INSERTITEM (NLTM_FIRST + 1) // wParam = (WPARAM)(INT)iItem, lParam = (LPARAM)(NLTITEM*)pItem; Return = index of new item or -1.
|
||||
#define LoginTab_InsertItem(/*HWND*/ __hwnd, /*INT*/ __iItem, /*NLTITEM* */ __pItem)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_INSERTITEM, (WPARAM)(__iItem), (LPARAM)(__pItem)))
|
||||
|
||||
#define NLTM_SETITEM (NLTM_FIRST + 2) // wParam = (WPARAM)(INT)iItem, lParam = (LPARAM)(NLTITEM*)pItem; Return = TRUE on success.
|
||||
#define LoginTab_SetItem(/*HWND*/ __hwnd, /*INT*/ __iItem, /*NLTITEM* */ __pItem)\
|
||||
((BOOL)SNDMSG((__hwnd), NLTM_SETITEM, (WPARAM)(__iItem), (LPARAM)(__pItem)))
|
||||
|
||||
#define NLTM_GETITEM (NLTM_FIRST + 3) // wParam = (WPARAM)(INT)iItem, lParam = (LPARAM)(NLTITEM*)pItem; Return = TRUE on success.
|
||||
#define LoginTab_GetItem(/*HWND*/ __hwnd, /*INT*/ __iItem, /*NLTITEM* */ __pItem)\
|
||||
((BOOL)SNDMSG((__hwnd), NLTM_GETITEM, (WPARAM)(__iItem), (LPARAM)(__pItem)))
|
||||
|
||||
#define NLTM_DELETEITEM (NLTM_FIRST + 4) // wParam = (WPARAM)(INT)iItem, lParam - not used; Return = TRUE on success.
|
||||
#define LoginTab_DeleteItem(/*HWND*/ __hwnd, /*INT*/ __iItem)\
|
||||
((BOOL)SNDMSG((__hwnd), NLTM_DELETEITEM, (WPARAM)(__iItem), 0L))
|
||||
|
||||
#define NLTM_DELETEALLITEMS (NLTM_FIRST + 5) // wParam - not used, lParam - not used; Return = TRUE on success.
|
||||
#define LoginTab_DeleteAllItems(/*HWND*/ __hwnd)\
|
||||
((BOOL)SNDMSG((__hwnd), NLTM_DELETEALLITEMS, 0, 0L))
|
||||
|
||||
#define NLTM_GETITEMCOUNT (NLTM_FIRST + 6) // wParam - not used, lParam - not used; Return item count.
|
||||
#define LoginTab_GetItemCount(/*HWND*/ __hwnd)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_GETITEMCOUNT, 0, 0L))
|
||||
|
||||
#define NLTM_GETCURSEL (NLTM_FIRST + 7) // wParam - not used, lParam - not used; Return item index or -1
|
||||
#define LoginTab_GetCurSel(/*HWND*/ __hwnd)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_GETCURSEL, 0, 0L))
|
||||
|
||||
#define NLTM_SETCURSEL (NLTM_FIRST + 8) // wParam = (WPARAM)(INT)iItem, lParam - not used; Return index of previously selected item if successful, or -1.
|
||||
#define LoginTab_SetCurSel(/*HWND*/ __hwnd, /*INT*/ __iItem)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_SETCURSEL, (WPARAM)(__iItem), 0L))
|
||||
|
||||
#define NLTM_SETIMAGELIST (NLTM_FIRST + 9) // wParam - not used, lParam - (LPARAM)(HIMAGELIST)himl; Returns the handle to the previous image list, or NULL if there is no previous image list.
|
||||
#define LoginTab_SetImageList(/*HWND*/ __hwnd, /*HIMAGELIST*/ __himl)\
|
||||
((HIMAGELIST)SNDMSG((__hwnd), NLTM_SETIMAGELIST, 0, (LPARAM)(__himl)))
|
||||
|
||||
#define NLTM_GETIMAGELIST (NLTM_FIRST + 10) // wParam - not used, lParam - not used; Returns the handle to the image list if successful, or NULL otherwise.
|
||||
#define LoginTab_GetImageList(/*HWND*/ __hwnd)\
|
||||
((HIMAGELIST)SNDMSG((__hwnd), NLTM_GETIMAGELIST, 0, 0L))
|
||||
|
||||
#define NLTM_RESETORDER (NLTM_FIRST + 11) // wParam - not used, lParam - not used; Return - ignored
|
||||
#define LoginTab_ResetOrder(/*HWND*/ __hwnd)\
|
||||
(SNDMSG((__hwnd), NLTM_RESETORDER, 0, 0L))
|
||||
|
||||
#define NLTM_LOCKSELECTION (NLTM_FIRST + 12) // wParam - (BOOL)fLock, lParam - not used; Return - ignored.
|
||||
#define LoginTab_LockSelection(/*HWND*/ __hwnd, /*BOOL*/ __fLock)\
|
||||
(SNDMSG((__hwnd), NLTM_LOCKSELECTION, (WPARAM)(__fLock), 0L))
|
||||
|
||||
|
||||
#define NLTM_GETIDEALWIDTH (NLTM_FIRST + 13) // wParam = (WPARAM)(INT)itemCount, lParam - not used; Return ideal width.
|
||||
#define LoginTab_GetIdealWidth(/*HWND*/ __hwnd, /*INT*/ __itemCount)\
|
||||
((INT)SNDMSG((__hwnd), NLTM_GETIDEALWIDTH, (WPARAM)(__itemCount), 0L))
|
||||
|
||||
// Notifications
|
||||
|
||||
typedef struct __NMLOGINTAB
|
||||
{
|
||||
NMHDR hdr;
|
||||
INT iItem;
|
||||
} NMLOGINTAB;
|
||||
|
||||
typedef struct __NMLOGINTABHELP
|
||||
{
|
||||
NMHDR hdr;
|
||||
INT iItem;
|
||||
LPARAM param;
|
||||
BSTR bstrHelp;
|
||||
} NMLOGINTABHELP;
|
||||
|
||||
typedef struct __NMLOGINTABCLICK
|
||||
{
|
||||
NMHDR hdr;
|
||||
POINT pt;
|
||||
} NMLOGINTABCLICK;
|
||||
|
||||
typedef struct __NMLOGINTABIMAGE
|
||||
{
|
||||
NMHDR hdr;
|
||||
INT iItem;
|
||||
LPARAM param;
|
||||
HIMAGELIST imageList;
|
||||
UINT maskRequest;
|
||||
UINT maskUpdate;
|
||||
UINT iImage;
|
||||
UINT iImageActive;
|
||||
UINT iImageDisabled;
|
||||
} NMLOGINTABIMAGE;
|
||||
|
||||
#define NLTN_FIRST (0 + 10)
|
||||
|
||||
#define NLTN_SELCHANGE (NLTN_FIRST + 0) // pnmh = (NMHDR*)lParam;
|
||||
#define NLTN_DELETEITEM (NLTN_FIRST + 1) // pnmh = (NMLOGINTAB*)lParam;
|
||||
#define NLTN_DELETEALLITEMS (NLTN_FIRST + 2) // pnmh = (NMLOGINTAB*)lParam; iItem = -1, return TRUE if you don't want to receive NLTN_DELETEITEM
|
||||
#define NLTN_GETITEMHELP (NLTN_FIRST + 3) // pnmh = (NMLOGINTABHELP*)lParam;
|
||||
#define NLTN_GETITEMIMAGE (NLTN_FIRST + 4) // pnmh = (NMLOGINTABIMAGE*)lParam;
|
||||
|
||||
// common notifications
|
||||
//NM_RCLICK - pnmh = (NMLOGINTABCLICK*)lParam;
|
||||
|
||||
|
||||
//styles
|
||||
#define NLTS_LOCKED 0x00000001
|
||||
#endif //NULLSOFT_AUTH_LOGIN_TAB_HEADER
|
||||
30
Src/auth/Loginbox/loginTemplate.h
Normal file
30
Src/auth/Loginbox/loginTemplate.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_TEMPLATE_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_TEMPLATE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class __declspec(novtable) LoginTemplate
|
||||
{
|
||||
protected:
|
||||
LoginTemplate() {}
|
||||
~LoginTemplate(){}
|
||||
|
||||
public:
|
||||
virtual ULONG AddRef() = 0;
|
||||
virtual ULONG Release() = 0;
|
||||
|
||||
virtual HRESULT GetType(GUID *templateUid) = 0;
|
||||
|
||||
virtual HRESULT SetParameter(LPCWSTR pszKey, LPCWSTR pszValue) = 0;
|
||||
virtual HRESULT IsValid() = 0;
|
||||
virtual HRESULT IsIdentical(LoginTemplate *test) = 0;
|
||||
|
||||
virtual HWND CreatePage(HWND hLoginbox, HWND hParent) = 0;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_TEMPLATE_HEADER
|
||||
2804
Src/auth/Loginbox/loginbox.cpp
Normal file
2804
Src/auth/Loginbox/loginbox.cpp
Normal file
File diff suppressed because it is too large
Load Diff
90
Src/auth/Loginbox/loginbox.h
Normal file
90
Src/auth/Loginbox/loginbox.h
Normal file
@@ -0,0 +1,90 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
class api_auth;
|
||||
class LoginDownloadResult;
|
||||
class LoginProviderEnumerator;
|
||||
class ifc_omcacherecord;
|
||||
class LoginImageCache;
|
||||
|
||||
#define LBS_NOCENTEROWNER 0x00000001
|
||||
|
||||
HWND LoginBox_CreateWindow(api_auth *auth, const GUID *pRealm, HWND hOwner, UINT fStyle);
|
||||
INT_PTR LoginBox_Show(api_auth *auth, const GUID *pRealm, HWND hOwner, UINT fStyle);
|
||||
HWND LoginBox_FindActive(const GUID *pRealm);
|
||||
|
||||
|
||||
// messages
|
||||
#define NLBM_FIRST (WM_APP + 10)
|
||||
|
||||
#define NLBM_GETAUTHAPI (NLBM_FIRST + 1) // wParam - not used, lParam = (LPARAM)(api_auth**)__authApi; Returns TRUE on success
|
||||
#define LoginBox_GetAuthApi(/*HNWD*/ __hwnd, /*api_auth** */ __authApi)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_GETAUTHAPI, 0, (LPARAM)(__authApi)))
|
||||
|
||||
#define NLBM_GETREALM (NLBM_FIRST + 2) // wParam - not used, lParam = (LPARAM)(GUID*)__pGuidRealm; Returns TRUE on success
|
||||
#define LoginBox_GetRealm(/*HNWD*/ __hwnd, /*GUID* */ __pGuidRealm)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_GETREALM, 0, (LPARAM)(__pGuidRealm)))
|
||||
|
||||
#define NLBM_GETACTIVEPROVIDER (NLBM_FIRST + 3) // wParam - not used, lParam = (LPARAM)(LoginProvider**)__ppProvider; Returns TRUE on success
|
||||
#define LoginBox_GetActiveProvider(/*HNWD*/ __hwnd, /*LoginProvider** */ __ppProvider)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_GETACTIVEPROVIDER, 0, (LPARAM)(__ppProvider)))
|
||||
|
||||
#define NLBM_GETSTATUS (NLBM_FIRST + 4) // wParam - not used, lParam = (LPARAM)(LoginStatus**)ppStatus; Returns TRUE on success
|
||||
#define LoginBox_GetStatus(/*HNWD*/ __hwnd, /*LoginStatus** */ __ppLoginStatus)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_GETSTATUS, 0, (LPARAM)(__ppLoginStatus)))
|
||||
|
||||
#define NLBM_ADDSTATUS (NLBM_FIRST + 5) // wParam - not used, lParam = (LPARAM)(BSTR)bstrStatusText; Return - (UINT)statusCookie or -1
|
||||
#define LoginBox_AddStatus(/*HNWD*/ __hwnd, /*BSTR*/ __bstrStatusText)\
|
||||
((UINT)SendMessage((__hwnd), NLBM_ADDSTATUS, 0, (LPARAM)(__bstrStatusText)))
|
||||
|
||||
#define NLBM_SETSTATUS (NLBM_FIRST + 6) // wParam = (WPARAM)(UINT)statusCookie, lParam = (LPARAM)(BSTR)bstrStatusText; Return TRUE on success.
|
||||
#define LoginBox_SetStatus(/*HNWD*/ __hwnd, /*UINT*/__statusCookie, /*BSTR*/ __bstrStatusText)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_SETSTATUS, (WPARAM)(__statusCookie), (LPARAM)(__bstrStatusText)))
|
||||
|
||||
#define NLBM_REMOVESTATUS (NLBM_FIRST + 7) // wParam = (WPARAM)(UINT)statusCookie, lParam - not used. Return ingored.
|
||||
#define LoginBox_RemoveStatus(/*HNWD*/ __hwnd, /*UINT*/__statusCookie)\
|
||||
(SendMessage((__hwnd), NLBM_REMOVESTATUS, (WPARAM)(__statusCookie), 0L))
|
||||
|
||||
#define NLBM_UPDATEPROVIDERS (NLBM_FIRST + 8) // wParam - (WPARAM)(BOOL)fForce, lParam - not used.
|
||||
#define LoginBox_UpdateProviders(/*HNWD*/ __hwnd, /*BOOL*/ __forceUpdate)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_UPDATEPROVIDERS, (WPARAM)(__forceUpdate), 0L))
|
||||
|
||||
#define NLBM_GETUPDATESTATE (NLBM_FIRST + 9) // wParam - not used, lParam - not used. Return TRUE if update active.
|
||||
#define LoginBox_GetUpdateState(/*HNWD*/ __hwnd)\
|
||||
((BOOL)SendMessage((__hwnd), NLBM_GETUPDATESTATE, 0, 0L))
|
||||
|
||||
#define NLBM_LOGINCOMPLETED (NLBM_FIRST + 20) // wParam - not used, lParam = (LPARAM)(LoginResult*)__pResult;
|
||||
|
||||
typedef struct __PROVIDERUPDATERESULT
|
||||
{
|
||||
LoginDownloadResult *downloader;
|
||||
HRESULT errorCode;
|
||||
BOOL dataIdentical;
|
||||
LoginProviderEnumerator *enumerator;
|
||||
} PROVIDERUPDATERESULT;
|
||||
|
||||
#define NLBM_PROVIDERSUPDATED (NLBM_FIRST + 21) // wParam - not used, lParam = (LPARAM)(PROVIDERUPDATERESULT*)updateResult;
|
||||
#define LoginBox_ProvidersUpdated(/*HNWD*/ __hwnd, /*LoginDownloadResult*/ __downloader, /*HRESULT*/ __errorCode, /*BOOL*/__dataIdentical, /*LoginProviderEnumerator**/ __enumerator)\
|
||||
{PROVIDERUPDATERESULT __updateResult;\
|
||||
__updateResult.downloader = (__downloader);\
|
||||
__updateResult.errorCode = (__errorCode);\
|
||||
__updateResult.dataIdentical = (__dataIdentical);\
|
||||
__updateResult.enumerator = (__enumerator);\
|
||||
(SendMessage((__hwnd), NLBM_PROVIDERSUPDATED, 0, (LPARAM)&(__updateResult)));}
|
||||
|
||||
|
||||
typedef struct __IMAGECACHERESULT
|
||||
{
|
||||
LoginImageCache *imageCache;
|
||||
ifc_omcacherecord *cacheRecord;
|
||||
} IMAGECACHERESULT;
|
||||
|
||||
#define NLBM_IMAGECACHED (NLBM_FIRST + 22) // wParam - not used, lParam = (LPARAM)(IMAGECACHERESULT*)cacheResult;
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_HEADER
|
||||
323
Src/auth/Loginbox/loginboxTosReminder.cpp
Normal file
323
Src/auth/Loginbox/loginboxTosReminder.cpp
Normal file
@@ -0,0 +1,323 @@
|
||||
#include "./loginbox.h"
|
||||
#include "./loginpage.h"
|
||||
#include "../resource.h"
|
||||
|
||||
#include "../api.h"
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct __TOSREMINDERCREATEPARAM
|
||||
{
|
||||
HANDLE hModal;
|
||||
BOOL fAnimate;
|
||||
INT_PTR *pResult;
|
||||
} TOSREMINDERCREATEPARAM;
|
||||
|
||||
typedef struct __TOSREMINDER
|
||||
{
|
||||
HANDLE hModal;
|
||||
BOOL fAnimate;
|
||||
SIZE idealSize;
|
||||
INT_PTR *pResult;
|
||||
} TOSREMINDER;
|
||||
|
||||
|
||||
|
||||
#define TOSREMINDER_PROP L"LoginboxTosReminderProp"
|
||||
#define GetTosReminder(__hwnd) ((TOSREMINDER*)GetProp(__hwnd, TOSREMINDER_PROP))
|
||||
|
||||
static INT_PTR CALLBACK TosReminder_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
static INT_PTR TosReminder_EnterModalLoop(HANDLE hExit);
|
||||
|
||||
HWND TosReminder_CreateWindow(HWND hParent)
|
||||
{
|
||||
if (NULL == hParent)
|
||||
return NULL;
|
||||
|
||||
return WASABI_API_CREATEDIALOGPARAMW(IDD_TOSREMINDER, hParent, TosReminder_DialogProc, 0L);
|
||||
}
|
||||
|
||||
INT_PTR TosReminder_Show(HWND hParent, INT controlId, BOOL fAnimate)
|
||||
{
|
||||
if (NULL == hParent)
|
||||
return -1;
|
||||
|
||||
INT_PTR result;
|
||||
TOSREMINDERCREATEPARAM param;
|
||||
param.fAnimate = fAnimate;
|
||||
param.pResult = &result;
|
||||
param.hModal = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
if (NULL == param.hModal) return -1;
|
||||
|
||||
HWND hwnd = WASABI_API_CREATEDIALOGPARAMW(IDD_TOSREMINDER,
|
||||
hParent, TosReminder_DialogProc, (LPARAM)¶m);
|
||||
|
||||
if (NULL == hwnd) return -1;
|
||||
|
||||
SetWindowLongPtr(hwnd, GWLP_ID, controlId);
|
||||
SetWindowPos(hParent, NULL, 0, 0, 0, 0,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED);
|
||||
|
||||
if (FALSE == fAnimate ||
|
||||
0 == AnimateWindow(hwnd, 150, AW_ACTIVATE | AW_VER_POSITIVE | AW_SLIDE))
|
||||
{
|
||||
ShowWindow(hwnd, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
TosReminder_EnterModalLoop(param.hModal);
|
||||
return result;
|
||||
}
|
||||
|
||||
static void TosReminder_EndDialog(HWND hwnd, INT_PTR code)
|
||||
{
|
||||
TOSREMINDER *reminder = GetTosReminder(hwnd);
|
||||
if (NULL != reminder)
|
||||
{
|
||||
if (NULL != reminder->pResult)
|
||||
{
|
||||
(*reminder->pResult) = code;
|
||||
reminder->pResult = NULL;
|
||||
}
|
||||
|
||||
if (NULL != reminder->hModal)
|
||||
{
|
||||
SetEvent(reminder->hModal);
|
||||
reminder->hModal = NULL;
|
||||
}
|
||||
|
||||
if (FALSE == reminder->fAnimate ||
|
||||
0 == AnimateWindow(hwnd, 150, AW_HIDE | AW_VER_NEGATIVE | AW_SLIDE))
|
||||
{
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void TosReminder_UpdateLayout(HWND hwnd, BOOL fRedraw)
|
||||
{
|
||||
RECT clientRect;
|
||||
if (FALSE == GetClientRect(hwnd, &clientRect)) return;
|
||||
|
||||
LONG centerX = clientRect.left + (clientRect.right - clientRect.left)/2;
|
||||
LONG buttonTop = clientRect.bottom;
|
||||
const INT szControls[] = {IDOK, IDCANCEL, IDC_TEXT, };
|
||||
|
||||
RECT controlRect;
|
||||
|
||||
UINT sharedFlags = SWP_NOZORDER | SWP_NOACTIVATE;
|
||||
if (FALSE == fRedraw) sharedFlags |= SWP_NOREDRAW;
|
||||
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
|
||||
if (NULL == hdwp) return;
|
||||
|
||||
UINT controlFlags;
|
||||
LONG x, y, cx, cy;
|
||||
|
||||
for (INT i = 0; i < ARRAYSIZE(szControls); i++)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, szControls[i]);
|
||||
if (NULL == hControl || FALSE == GetWindowRect(hControl, &controlRect))
|
||||
continue;
|
||||
|
||||
controlFlags = sharedFlags;
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&controlRect, 2);
|
||||
x = controlRect.left;
|
||||
y = controlRect.top;
|
||||
cx = controlRect.right - controlRect.left;
|
||||
cy = controlRect.bottom - controlRect.top;
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDOK:
|
||||
x = centerX - cx - 8;
|
||||
if (x < clientRect.left) x = clientRect.left;
|
||||
y = (clientRect.bottom - 8) - cy;
|
||||
if (y < clientRect.top) y = clientRect.top;
|
||||
if (y < buttonTop) buttonTop = y;
|
||||
break;
|
||||
|
||||
case IDCANCEL:
|
||||
x = centerX + 8;
|
||||
if ((x + cx) > clientRect.right) x = clientRect.right - cx;
|
||||
y = (clientRect.bottom - 8) - cy;
|
||||
if (y < clientRect.top) y = clientRect.top;
|
||||
if (y < buttonTop) buttonTop = y;
|
||||
break;
|
||||
|
||||
case IDC_TEXT:
|
||||
cx = (clientRect.right - clientRect.left) - 2*x;
|
||||
cy = (buttonTop - y) - 16;
|
||||
break;
|
||||
}
|
||||
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, controlFlags);
|
||||
if (NULL == hdwp) return;
|
||||
}
|
||||
|
||||
EndDeferWindowPos(hdwp);
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_TEXT);
|
||||
if (NULL != hControl) InvalidateRect(hControl, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
static INT_PTR TosReminder_OnInitDialog(HWND hwnd, HWND hFocus, LPARAM param)
|
||||
{
|
||||
TOSREMINDER *reminder = (TOSREMINDER*)malloc(sizeof(TOSREMINDER));
|
||||
if (NULL == reminder)
|
||||
{
|
||||
DestroyWindow(hwnd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZeroMemory(reminder, sizeof(TOSREMINDER));
|
||||
SetProp(hwnd, TOSREMINDER_PROP, reminder);
|
||||
|
||||
TOSREMINDERCREATEPARAM *createParam = (TOSREMINDERCREATEPARAM*)param;
|
||||
if (NULL != createParam)
|
||||
{
|
||||
reminder->fAnimate = createParam->fAnimate;
|
||||
reminder->hModal = createParam->hModal;
|
||||
reminder->pResult = createParam->pResult;
|
||||
}
|
||||
|
||||
RECT windowRect;
|
||||
if (FALSE != GetWindowRect(hwnd, &windowRect))
|
||||
{
|
||||
reminder->idealSize.cx = windowRect.right - windowRect.left;
|
||||
reminder->idealSize.cy = windowRect.bottom - windowRect.top;
|
||||
}
|
||||
|
||||
PostMessage(hwnd, WM_CHANGEUISTATE, MAKEWPARAM(UIS_INITIALIZE, UISF_HIDEACCEL | UISF_HIDEFOCUS), 0L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void TosReminder_OnDestroy(HWND hwnd)
|
||||
{
|
||||
TOSREMINDER *reminder = GetTosReminder(hwnd);
|
||||
RemoveProp(hwnd, TOSREMINDER_PROP);
|
||||
if (NULL == reminder)
|
||||
return;
|
||||
|
||||
if (NULL != reminder->pResult)
|
||||
{
|
||||
(*reminder->pResult) = -1;
|
||||
}
|
||||
|
||||
if (NULL != reminder->hModal)
|
||||
{
|
||||
SetEvent(reminder->hModal);
|
||||
reminder->hModal = NULL;
|
||||
}
|
||||
|
||||
free(reminder);
|
||||
}
|
||||
|
||||
|
||||
static void TosReminder_OnWindowPosChanged(HWND hwnd, WINDOWPOS *pwp)
|
||||
{
|
||||
if (SWP_NOSIZE != ((SWP_NOSIZE | SWP_FRAMECHANGED) & pwp->flags))
|
||||
{
|
||||
TosReminder_UpdateLayout(hwnd, 0 == (SWP_NOREDRAW & pwp->flags));
|
||||
}
|
||||
}
|
||||
|
||||
static void TosReminder_OnCommand(HWND hwnd, INT commandId, INT eventId, HWND hControl)
|
||||
{
|
||||
|
||||
switch(commandId)
|
||||
{
|
||||
case IDOK:
|
||||
TosReminder_EndDialog(hwnd, commandId);
|
||||
break;
|
||||
|
||||
case IDCANCEL:
|
||||
TosReminder_EndDialog(hwnd, commandId);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static BOOL TosReminder_OnGetIdealSize(HWND hwnd, SIZE *pSize)
|
||||
{
|
||||
TOSREMINDER *reminder = GetTosReminder(hwnd);
|
||||
if (NULL == reminder || NULL == pSize) return FALSE;
|
||||
|
||||
CopyMemory(pSize, &reminder->idealSize, sizeof(SIZE));
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
static BOOL TosReminder_OnClose(HWND hwnd, BOOL *pfAbort)
|
||||
{
|
||||
TOSREMINDER *reminder = GetTosReminder(hwnd);
|
||||
if (NULL != reminder) reminder->fAnimate = FALSE;
|
||||
|
||||
TosReminder_EndDialog(hwnd, IDCANCEL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK TosReminder_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG: return TosReminder_OnInitDialog(hwnd, (HWND)wParam, lParam);
|
||||
case WM_DESTROY: TosReminder_OnDestroy(hwnd); return 0;
|
||||
case WM_WINDOWPOSCHANGED: TosReminder_OnWindowPosChanged(hwnd, (WINDOWPOS*)lParam); return TRUE;
|
||||
case WM_COMMAND: TosReminder_OnCommand(hwnd, LOWORD(wParam), HIWORD(wParam), (HWND)lParam); return TRUE;
|
||||
|
||||
case NLPM_GETIDEALSIZE: MSGRESULT(hwnd, TosReminder_OnGetIdealSize(hwnd, (SIZE*)lParam));
|
||||
case NLPM_CLOSE: MSGRESULT(hwnd, TosReminder_OnClose(hwnd, (BOOL*)lParam));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL TosReminder_PumpMessages()
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
||||
{
|
||||
if (WM_QUIT == msg.message)
|
||||
{
|
||||
PostQuitMessage((int)msg.wParam);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!CallMsgFilter(&msg, MSGF_DIALOGBOX))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static INT_PTR TosReminder_EnterModalLoop(HANDLE hExit)
|
||||
{
|
||||
if (NULL == hExit)
|
||||
return FALSE;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
DWORD code = MsgWaitForMultipleObjectsEx(1, &hExit, INFINITE, QS_ALLINPUT, MWMO_ALERTABLE | MWMO_INPUTAVAILABLE);
|
||||
switch(code)
|
||||
{
|
||||
case WAIT_FAILED:
|
||||
return FALSE;
|
||||
|
||||
case WAIT_OBJECT_0:
|
||||
return TRUE;
|
||||
|
||||
case (WAIT_OBJECT_0 + 1):
|
||||
if (FALSE != TosReminder_PumpMessages())
|
||||
return TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
13
Src/auth/Loginbox/loginboxTosReminder.h
Normal file
13
Src/auth/Loginbox/loginboxTosReminder.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINBOX_TOS_REMINDER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINBOX_TOS_REMINDER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
HWND TosReminder_CreateWindow(HWND hParent);
|
||||
INT_PTR TosReminder_Show(HWND hParent, INT controlId, BOOL fAnimate);
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINBOX_TOS_REMINDER_HEADER
|
||||
101
Src/auth/Loginbox/loginpage.h
Normal file
101
Src/auth/Loginbox/loginpage.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPAGE_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPAGE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
#define NLPM_FIRST (WM_APP + 10)
|
||||
#define NLPM_PAGEFIRST (NLPM_FIRST + 40)
|
||||
|
||||
#define NLPM_GETLOGINDATA (NLPM_FIRST + 0) // wParam - not used, lParam = (LPARAM)(LoginData**)__ppLoginData; Return: TRUE on success.
|
||||
#define LoginPage_GetData(/*HWND*/ __hwnd, /*LoginData** */ __ppLoginData)\
|
||||
((BOOL)(SNDMSG((__hwnd), NLPM_GETLOGINDATA, 0, (LPARAM)(__ppLoginData))))
|
||||
|
||||
#define NLPM_UPDATESTATECHANGE (NLPM_FIRST + 1) // wParam - not used, lParam = (BOOL)__updateActive; Return - ignored
|
||||
#define LoginPage_UpdateStateChange(/*HWND*/ __hwnd, /*BOOL*/ __updateActive)\
|
||||
((BOOL)(SNDMSG((__hwnd), NLPM_UPDATESTATECHANGE, 0, (LPARAM)(__updateActive))))
|
||||
|
||||
#define NLPM_SETUSERNAME (NLPM_FIRST + 2) // wParam - not used, lParam = (LPARAM)(LPCWSTR)__pszUsername; Return TRUE on success
|
||||
#define LoginPage_SetUsername(/*HWND*/ __hwnd, /*LPCWSTR*/ __pszUsername)\
|
||||
((BOOL)(SNDMSG((__hwnd), NLPM_SETUSERNAME, 0, (LPARAM)(__pszUsername))))
|
||||
|
||||
#define NLPM_SETPASSWORD (NLPM_FIRST + 3) // wParam - not used, lParam = (LPARAM)(LPCWSTR)__pszPassword; Return TRUE on success
|
||||
#define LoginPage_SetPassword(/*HWND*/ __hwnd, /*LPCWSTR*/ __pszPassword)\
|
||||
((BOOL)(SNDMSG((__hwnd), NLPM_SETPASSWORD, 0, (LPARAM)(__pszPassword))))
|
||||
|
||||
#define NLPM_GETFIRSTITEM (NLPM_FIRST + 4) // wParam - not used, lParam - not used; Return HWND where you want focus to be on page create or NULL.
|
||||
#define LoginPage_GetFirstItem(/*HWND*/ __hwnd)\
|
||||
((HWND)(SNDMSG((__hwnd), NLPM_GETFIRSTITEM, 0, 0L)))
|
||||
|
||||
#define NLPM_SETTITLE (NLPM_FIRST + 5) // wParam - not used, lParam = (LPARAM)(LPCWSTR)__pszTitle; Return TRUE on success
|
||||
#define LoginPage_SetTitle(/*HWND*/ __hwnd, /*LPCWSTR*/ __pszTitle)\
|
||||
((BOOL)(SNDMSG((__hwnd), NLPM_SETTITLE, 0, (LPARAM)(__pszTitle))))
|
||||
|
||||
class LoginPage;
|
||||
class LoginData;
|
||||
|
||||
typedef HRESULT (CALLBACK *LOGINPAGECREATOR)(HWND /*hwnd*/, HWND /*hLoginbox*/, LoginPage** /*instance*/);
|
||||
|
||||
class __declspec(novtable) LoginPage
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginPage(HWND hwnd, HWND hLoginbox);
|
||||
virtual ~LoginPage();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, LPCWSTR pszTemplate, HWND hParent, LPARAM param, LOGINPAGECREATOR fnCreator);
|
||||
|
||||
protected:
|
||||
virtual void UpdateMargins();
|
||||
virtual void UpdateColors();
|
||||
virtual void UpdateLayout(BOOL fRedraw);
|
||||
|
||||
virtual BOOL GetPageRect(RECT *prc);
|
||||
BOOL ShowHelp();
|
||||
BOOL IsHelpAvailable();
|
||||
INT GetTitleSpacing();
|
||||
BOOL SetLabelText(INT controlId, LPCWSTR pszText);
|
||||
|
||||
|
||||
protected:
|
||||
virtual BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
virtual void OnDestroy();
|
||||
virtual void OnWindowPosChanged(const WINDOWPOS *pwp);
|
||||
virtual void OnCommand(UINT commandId, UINT eventType, HWND hControl);
|
||||
virtual BOOL OnNotify(UINT controlId, const NMHDR *pnmh);
|
||||
virtual BOOL OnSetCursor(HWND hTarget, INT hitCode, INT uMsg);
|
||||
virtual HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
virtual HBRUSH OnGetDialogColor(HDC hdc, HWND hControl);
|
||||
virtual BOOL OnHelp(HELPINFO *phi);
|
||||
virtual void OnThemeChanged();
|
||||
virtual void OnSysColorChanged();
|
||||
|
||||
virtual BOOL OnGetLoginData(LoginData **ppLoginData);
|
||||
virtual void OnUpdateStateChange(BOOL updateActive);
|
||||
virtual BOOL OnSetUsername(LPCWSTR pszUsername);
|
||||
virtual BOOL OnSetPassword(LPCWSTR pszPassword);
|
||||
virtual HWND OnGetFirstItem();
|
||||
virtual BOOL OnSetTitle(LPCWSTR pszTitle);
|
||||
|
||||
virtual INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
friend static INT_PTR CALLBACK LoginPage_DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
HWND hwnd;
|
||||
HWND hLoginbox;
|
||||
RECT margins;
|
||||
COLORREF rgbTitle;
|
||||
COLORREF rgbSecondaryText;
|
||||
COLORREF rgbText;
|
||||
COLORREF rgbBack;
|
||||
HBRUSH hbrBack;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPAGE_HEADER
|
||||
342
Src/auth/Loginbox/pageAddress.cpp
Normal file
342
Src/auth/Loginbox/pageAddress.cpp
Normal file
@@ -0,0 +1,342 @@
|
||||
#include "./pageAddress.h"
|
||||
#include "./dataAddress.h"
|
||||
#include "./common.h"
|
||||
#include "./addressEncoder.h"
|
||||
#include "./addressEditbox.h"
|
||||
#include "./loginGui.h"
|
||||
|
||||
#include "../resource.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <wininet.h>
|
||||
|
||||
|
||||
|
||||
static HRESULT CALLBACK LoginPageAddress_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPageAddress(hwnd, hLoginbox);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPageAddress::LoginPageAddress(HWND hwnd, HWND hLoginbox)
|
||||
: LoginPage(hwnd, hLoginbox)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL != hEdit)
|
||||
AddressEditbox_AttachWindow(hEdit);
|
||||
|
||||
}
|
||||
|
||||
LoginPageAddress::~LoginPageAddress()
|
||||
{
|
||||
}
|
||||
|
||||
HWND LoginPageAddress::CreatePage(HWND hLoginbox, HWND hParent)
|
||||
{
|
||||
return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_ADDRESS),
|
||||
hParent, NULL, LoginPageAddress_CreateInstance);
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
HFONT fontEdit = NULL, fontLabel = NULL;
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
fontLabel = loginGui->GetTextFont();
|
||||
fontEdit = loginGui->GetEditorFont();
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
if (NULL != fontLabel)
|
||||
{
|
||||
HWND hLabel = GetDlgItem(hwnd, IDC_ADDRESS_LABEL);
|
||||
if (NULL != hLabel)
|
||||
SendMessage(hLabel, WM_SETFONT, (WPARAM)fontLabel, 0L);
|
||||
|
||||
hLabel = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL != hLabel)
|
||||
SendMessage(hLabel, WM_SETFONT, (WPARAM)fontLabel, 0L);
|
||||
}
|
||||
|
||||
if (NULL != fontEdit)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL != hEdit)
|
||||
SendMessage(hEdit, WM_SETFONT, (WPARAM)fontEdit, 0L);
|
||||
}
|
||||
|
||||
LoginPage::OnInitDialog(hFocus, param);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPageAddress::OnDestroy()
|
||||
{
|
||||
LoginPage::OnDestroy();
|
||||
}
|
||||
|
||||
void LoginPageAddress::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPage::UpdateLayout(fRedraw);
|
||||
|
||||
RECT pageRect;
|
||||
GetPageRect(&pageRect);
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW;
|
||||
|
||||
const INT szControls[] = { IDC_ADDRESS_LABEL, IDC_ADDRESS_EDIT, IDC_MESSAGE, };
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
|
||||
|
||||
INT baseunitX, baseunitY;
|
||||
if (FALSE == LoginBox_GetWindowBaseUnits(hwnd, &baseunitX, &baseunitY))
|
||||
{
|
||||
baseunitY = 13;
|
||||
}
|
||||
|
||||
HRGN invalidRegion = CreateRectRgn(0, 0, 0, 0);
|
||||
HRGN tempRegion = CreateRectRgn(0, 0, 0, 0);
|
||||
HWND hControl;
|
||||
|
||||
INT nextTop = pageRect.top;
|
||||
INT x, y, cx, cy;
|
||||
|
||||
RECT rect;
|
||||
|
||||
INT maxWidth = pageRect.right - pageRect.left;
|
||||
hControl = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT fontControl = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, fontControl);
|
||||
|
||||
maxWidth = LoginBox_GetAveStrWidth(hdc, 80);
|
||||
if(maxWidth > (pageRect.right - pageRect.left))
|
||||
maxWidth = pageRect.right - pageRect.left;
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hControl, hdc);
|
||||
}
|
||||
}
|
||||
|
||||
for (INT i = 0; i < ARRAYSIZE(szControls); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szControls[i]);
|
||||
if (NULL == hControl || FALSE == GetWindowRect(hControl, &rect)) continue;
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&rect, 2);
|
||||
x = rect.left;
|
||||
y = rect.top;
|
||||
cx = rect.right - rect.left;
|
||||
cy = rect.bottom - rect.top;
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_ADDRESS_LABEL:
|
||||
case IDC_MESSAGE:
|
||||
x = pageRect.left;
|
||||
y = nextTop;
|
||||
LoginBox_GetWindowTextSize(hControl, maxWidth, &cx, &cy);
|
||||
nextTop += (cy + MulDiv(2, baseunitY, 8));
|
||||
break;
|
||||
case IDC_ADDRESS_EDIT:
|
||||
x = pageRect.left;
|
||||
y = nextTop;
|
||||
cy = LoginBox_GetWindowTextHeight(hControl, 0);
|
||||
{
|
||||
RECT r1, r2;
|
||||
GetWindowRect(hControl, &r1);
|
||||
SendMessage(hControl, EM_GETRECT, 0, (LPARAM)&r2);
|
||||
INT t = (r1.bottom - r1.top) - (r2.bottom - r2.top);
|
||||
cy += t;
|
||||
}
|
||||
cx = maxWidth;
|
||||
nextTop += (cy + MulDiv(7, baseunitY, 8));
|
||||
break;
|
||||
}
|
||||
|
||||
if (rect.left != x || rect.top != y ||
|
||||
(rect.right - rect.left) != cx || (rect.bottom - rect.top) != cy)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, flags);
|
||||
if (NULL == hdwp) break;
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
SetRectRgn(tempRegion, rect.left, rect.top, rect.right, rect.bottom);
|
||||
CombineRgn(invalidRegion, invalidRegion, tempRegion, RGN_OR);
|
||||
|
||||
SetRectRgn(tempRegion, x, y , x + cx, y + cy);
|
||||
CombineRgn(invalidRegion, invalidRegion, tempRegion, RGN_OR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != hdwp)
|
||||
EndDeferWindowPos(hdwp);
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
RedrawWindow(hwnd, NULL, invalidRegion,
|
||||
RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ERASENOW | RDW_ALLCHILDREN | RDW_VALIDATE);
|
||||
}
|
||||
|
||||
if (NULL != invalidRegion)
|
||||
DeleteObject(invalidRegion);
|
||||
if (NULL != tempRegion)
|
||||
DeleteObject(tempRegion);
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnGetLoginData(LoginData **ppLoginData)
|
||||
{
|
||||
if (NULL == ppLoginData)
|
||||
return FALSE;
|
||||
|
||||
HWND hEdit;
|
||||
LPWSTR address;
|
||||
|
||||
hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL == hEdit || FAILED(LoginBox_GetWindowText(hEdit, &address, NULL)))
|
||||
address = NULL;
|
||||
else
|
||||
{
|
||||
size_t encodedMax = lstrlen(address)*2;
|
||||
LPWSTR addressEncoded = LoginBox_MallocString(encodedMax);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
if (FALSE == InternetCanonicalizeUrl(address, addressEncoded, (DWORD*)&encodedMax, ICU_ENCODE_PERCENT | ICU_NO_META))
|
||||
{
|
||||
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
|
||||
{
|
||||
LoginBox_FreeString(addressEncoded);
|
||||
addressEncoded = LoginBox_MallocString(encodedMax);
|
||||
if (NULL != addressEncoded)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LoginBox_FreeString(address);
|
||||
address = LoginBox_CopyString(addressEncoded);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
for(;;)
|
||||
{
|
||||
hr = AddressEncoder_EncodeString(address, addressEncoded, &encodedMax, ICU_BROWSER_MODE);
|
||||
if (ENC_E_INSUFFICIENT_BUFFER == hr)
|
||||
{
|
||||
LoginBox_FreeString(addressEncoded);
|
||||
addressEncoded = LoginBox_MallocString(encodedMax);
|
||||
if (NULL == addressEncoded)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LoginBox_FreeString(address);
|
||||
address = addressEncoded;
|
||||
addressEncoded = NULL;
|
||||
}
|
||||
else
|
||||
LoginBox_FreeString(addressEncoded);
|
||||
}
|
||||
|
||||
HRESULT hr = LoginDataAddress::CreateInstance(NULL, hwnd, hLoginbox,
|
||||
address, (LoginDataAddress**)ppLoginData);
|
||||
|
||||
LoginBox_FreeString(address);
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnSetUsername(LPCWSTR pszUsername)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL == hEdit) return FALSE;
|
||||
|
||||
if (NULL == pszUsername || L'\0' == *pszUsername)
|
||||
return FALSE;
|
||||
|
||||
INT cchLen = lstrlen(pszUsername);
|
||||
|
||||
INT f, l;
|
||||
SNDMSG(hEdit, EM_GETSEL, (WPARAM)&f, (LPARAM)&l);
|
||||
if (f == l) return FALSE;
|
||||
|
||||
SNDMSG(hEdit, EM_REPLACESEL, FALSE, (LPARAM)pszUsername);
|
||||
SNDMSG(hEdit, EM_SETSEL, (WPARAM)f, (LPARAM)f + cchLen);
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
HBRUSH LoginPageAddress::OnGetStaticColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
INT_PTR controlId = (INT_PTR)GetWindowLongPtr(hControl, GWLP_ID);
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_MESSAGE:
|
||||
SetTextColor(hdc, rgbSecondaryText);
|
||||
SetBkColor(hdc, rgbBack);
|
||||
return hbrBack;
|
||||
}
|
||||
|
||||
return LoginPage::OnGetStaticColor(hdc, hControl);
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnSetAddress(LPCWSTR pszAddress, BOOL replaceUsername)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_ADDRESS_EDIT);
|
||||
if (NULL == hEdit) return FALSE;
|
||||
|
||||
BOOL succeeded;
|
||||
LPWSTR addressDecoded;
|
||||
|
||||
if (SUCCEEDED(AddressEncoder_DecodeString(pszAddress, &addressDecoded)))
|
||||
{
|
||||
succeeded = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)addressDecoded);
|
||||
LoginBox_FreeString(addressDecoded);
|
||||
}
|
||||
else
|
||||
succeeded = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)pszAddress);
|
||||
|
||||
|
||||
return succeeded;
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnSetAddressTitle(LPCWSTR pszTitle)
|
||||
{
|
||||
return SetLabelText(IDC_ADDRESS_LABEL, pszTitle);
|
||||
}
|
||||
|
||||
BOOL LoginPageAddress::OnSetMessage(LPCWSTR pszMessage)
|
||||
{
|
||||
HWND hLabel = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL == hLabel) return FALSE;
|
||||
|
||||
return SetWindowText(hLabel, pszMessage);
|
||||
}
|
||||
|
||||
INT_PTR LoginPageAddress::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case NLPAM_SETADDRESS: MSGRESULT(hwnd, OnSetAddress((LPCWSTR)lParam, (BOOL)wParam));
|
||||
case NLPAM_SETADDRESSTITLE: MSGRESULT(hwnd, OnSetAddressTitle((LPCWSTR)lParam));
|
||||
case NLPAM_SETMESSAGE: MSGRESULT(hwnd, OnSetMessage((LPCWSTR)lParam));
|
||||
|
||||
}
|
||||
return __super::DialogProc(uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
58
Src/auth/Loginbox/pageAddress.h
Normal file
58
Src/auth/Loginbox/pageAddress.h
Normal file
@@ -0,0 +1,58 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PAGE_ADDRESS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PAGE_ADDRESS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPage.h"
|
||||
|
||||
#define NLPAM_FIRST (NLPM_PAGEFIRST + 0)
|
||||
|
||||
#define NLPAM_SETADDRESS (NLPAM_FIRST + 0) //wParam = (WPARAM)(BOOL)replaceUsername, lParam = (LPARAM)(LPCWSTR)pszAddress; Return - TRUE on succeess.
|
||||
#define LoginPageAddress_SetAddress(/*HWND*/ __hwnd, /*LPCWSTR*/ __address, /*BOOL*/ __replaceUsername)\
|
||||
((BOOL)SNDMSG((__hwnd), NLPAM_SETADDRESS, (WPARAM)(__replaceUsername), (LPARAM)(__address)))
|
||||
|
||||
#define NLPAM_SETADDRESSTITLE (NLPAM_FIRST + 1) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszAddressTitle; Return - TRUE on succeess.
|
||||
#define LoginPageAddress_SetAddressTitle(/*HWND*/ __hwnd, /*LPCWSTR*/ __addressTitle)\
|
||||
((BOOL)SNDMSG((__hwnd), NLPAM_SETADDRESSTITLE, 0, (LPARAM)(__addressTitle)))
|
||||
|
||||
#define NLPAM_SETMESSAGE (NLPAM_FIRST + 2) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszMessage; Return - TRUE on succeess.
|
||||
#define LoginPageAddress_SetMessage(/*HWND*/ __hwnd, /*LPCWSTR*/ __pszMessage)\
|
||||
((BOOL)SNDMSG((__hwnd), NLPAM_SETMESSAGE, 0, (LPARAM)(__pszMessage)))
|
||||
|
||||
|
||||
class LoginPageAddress : public LoginPage
|
||||
{
|
||||
protected:
|
||||
LoginPageAddress(HWND hwnd, HWND hLoginbox);
|
||||
~LoginPageAddress();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, HWND hParent);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
void OnDestroy();
|
||||
|
||||
BOOL OnGetLoginData(LoginData **ppLoginData);
|
||||
BOOL OnSetUsername(LPCWSTR pszUsername);
|
||||
|
||||
HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
|
||||
BOOL OnSetAddress(LPCWSTR pszAddress, BOOL replaceUsername);
|
||||
BOOL OnSetAddressTitle(LPCWSTR pszTitle);
|
||||
BOOL OnSetMessage(LPCWSTR pszMessage);
|
||||
|
||||
INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPageAddress_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PAGE_ADDRESS_HEADER
|
||||
416
Src/auth/Loginbox/pageCredentials.cpp
Normal file
416
Src/auth/Loginbox/pageCredentials.cpp
Normal file
@@ -0,0 +1,416 @@
|
||||
#include "./pageCredentials.h"
|
||||
#include "./dataCredentials.h"
|
||||
#include "./common.h"
|
||||
#include "./loginGui.h"
|
||||
#include "../../winamp/commandLink.h"
|
||||
#include "../resource.h"
|
||||
|
||||
#include <commctrl.h>
|
||||
|
||||
|
||||
static HRESULT CALLBACK LoginPageCredentials_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPageCredentials(hwnd, hLoginbox);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPageCredentials::LoginPageCredentials(HWND hwnd, HWND hLoginbox)
|
||||
: LoginPage(hwnd, hLoginbox), accountRecoverUrl(NULL), accountCreateUrl(NULL)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
LoginPageCredentials::~LoginPageCredentials()
|
||||
{
|
||||
LoginBox_FreeString(accountRecoverUrl);
|
||||
LoginBox_FreeString(accountCreateUrl);
|
||||
}
|
||||
|
||||
HWND LoginPageCredentials::CreatePage(HWND hLoginbox, HWND hParent)
|
||||
{
|
||||
return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_CREDENTIALS),
|
||||
hParent, NULL, LoginPageCredentials_CreateInstance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LoginPageCredentials::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPage::UpdateLayout(fRedraw);
|
||||
|
||||
RECT pageRect;
|
||||
if (FALSE == GetPageRect(&pageRect))
|
||||
return;
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
const INT szControls[] = { IDC_USERNAME_LABEL, IDC_USERNAME, IDC_PASSWORD_LABEL, IDC_PASSWORD};
|
||||
const INT szLinks[] = { IDC_CREATE_ACCOUNT, IDC_RECOVER_ACCOUNT };
|
||||
|
||||
INT baseunitX, baseunitY;
|
||||
if (FALSE == LoginBox_GetWindowBaseUnits(hwnd, &baseunitX, &baseunitY))
|
||||
{
|
||||
baseunitX = 6;
|
||||
baseunitY = 13;
|
||||
}
|
||||
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls) + ARRAYSIZE(szLinks));
|
||||
|
||||
HWND hControl;
|
||||
INT cx, cy, x, y;
|
||||
|
||||
INT editWidth = 0;
|
||||
INT column1Width = 0;
|
||||
INT column2Width = 0;
|
||||
INT columnSpace = MulDiv(7, baseunitX, 4);
|
||||
SIZE sizeLink;
|
||||
RECT linkMargins;
|
||||
|
||||
// column 1 width
|
||||
for (INT i = 0; i < ARRAYSIZE(szControls); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szControls[i]);
|
||||
if (NULL == hControl) continue;
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_USERNAME_LABEL:
|
||||
case IDC_PASSWORD_LABEL:
|
||||
if (FALSE != (LoginBox_GetWindowTextSize(hControl, pageRect.right - pageRect.left, &cx, &cy)) &&
|
||||
cx > column1Width)
|
||||
{
|
||||
column1Width = cx;
|
||||
}
|
||||
break;
|
||||
case IDC_USERNAME:
|
||||
case IDC_PASSWORD:
|
||||
if (0 == editWidth)
|
||||
{
|
||||
HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT fontControl = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, fontControl);
|
||||
|
||||
editWidth = LoginBox_GetAveStrWidth(hdc, 28);
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hControl, hdc);
|
||||
}
|
||||
if (0 != editWidth)
|
||||
{
|
||||
LRESULT editMargins = SendMessage(hControl, EM_GETMARGINS, 0,0L);
|
||||
editWidth += (LOWORD(editMargins) + HIWORD(editMargins));
|
||||
}
|
||||
}
|
||||
if (editWidth > column1Width)
|
||||
column1Width = editWidth;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// column 2 width
|
||||
for (INT i = 0; i < ARRAYSIZE(szLinks); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szLinks[i]);
|
||||
if (NULL != hControl &&
|
||||
0 != (WS_VISIBLE & GetWindowStyle(hControl)) &&
|
||||
FALSE != CommandLink_GetIdealSize(hControl, &sizeLink))
|
||||
|
||||
{
|
||||
if (FALSE != CommandLink_GetMargins(hControl, &linkMargins))
|
||||
sizeLink.cx -= linkMargins.right;
|
||||
|
||||
if (column2Width < sizeLink.cx)
|
||||
column2Width = sizeLink.cx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL multiColumnLayout;
|
||||
if (column2Width > 0 &&
|
||||
(column1Width + columnSpace + column2Width) <= (pageRect.right - pageRect.left))
|
||||
{
|
||||
multiColumnLayout = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
multiColumnLayout = FALSE;
|
||||
}
|
||||
|
||||
INT nextTop = 0;
|
||||
|
||||
if (column2Width != 0)
|
||||
{
|
||||
if(FALSE == multiColumnLayout)
|
||||
nextTop = pageRect.top - GetTitleSpacing()/2;
|
||||
else
|
||||
{
|
||||
nextTop = pageRect.top;
|
||||
HWND hLabel = GetDlgItem(hwnd, IDC_USERNAME_LABEL);
|
||||
INT offsetY = (NULL != hLabel) ? LoginBox_GetWindowTextHeight(hLabel, 0) : 0;
|
||||
if (0 == offsetY) offsetY = baseunitY;
|
||||
nextTop += (offsetY - 1);
|
||||
}
|
||||
|
||||
for (INT i = 0; i < ARRAYSIZE(szLinks); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szLinks[i]);
|
||||
if (NULL == hControl || 0 == (WS_VISIBLE & GetWindowStyle(hControl)))
|
||||
continue;
|
||||
|
||||
if (FALSE == CommandLink_GetIdealSize(hControl, &sizeLink))
|
||||
ZeroMemory(&sizeLink, sizeof(SIZE));
|
||||
|
||||
x = pageRect.right - sizeLink.cx;
|
||||
if (x < pageRect.left) x = pageRect.left;
|
||||
|
||||
if (FALSE != CommandLink_GetMargins(hControl, &linkMargins))
|
||||
x += linkMargins.right;
|
||||
|
||||
if (i == 0)
|
||||
nextTop -= linkMargins.top;
|
||||
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, x, nextTop, sizeLink.cx, sizeLink.cy, flags);
|
||||
if (NULL == hdwp) break;
|
||||
|
||||
nextTop += sizeLink.cy;
|
||||
|
||||
if (i != (ARRAYSIZE(szLinks) -1))
|
||||
nextTop += MulDiv(1, baseunitY, 8);
|
||||
}
|
||||
}
|
||||
|
||||
if (FALSE != multiColumnLayout || 0 == column2Width)
|
||||
nextTop = pageRect.top;
|
||||
else
|
||||
nextTop += MulDiv(2, baseunitY, 8);
|
||||
|
||||
for (INT i = 0; i < ARRAYSIZE(szControls); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szControls[i]);
|
||||
if (NULL == hControl) continue;
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_USERNAME_LABEL:
|
||||
case IDC_PASSWORD_LABEL:
|
||||
x = pageRect.left;
|
||||
y = nextTop;
|
||||
LoginBox_GetWindowTextSize(hControl, pageRect.right - pageRect.left, &cx, &cy);
|
||||
nextTop += (cy + MulDiv(2, baseunitY, 8));
|
||||
if (cx > column1Width)
|
||||
cx = column1Width;
|
||||
break;
|
||||
case IDC_USERNAME:
|
||||
case IDC_PASSWORD:
|
||||
x = pageRect.left;
|
||||
y = nextTop;
|
||||
cy = LoginBox_GetWindowTextHeight(hControl, 0);
|
||||
{
|
||||
RECT r1, r2;
|
||||
GetWindowRect(hControl, &r1);
|
||||
SendMessage(hControl, EM_GETRECT, 0, (LPARAM)&r2);
|
||||
INT t = (r1.bottom - r1.top) - (r2.bottom - r2.top);
|
||||
cy += t;
|
||||
}
|
||||
nextTop += (cy + MulDiv(4, baseunitY, 8));
|
||||
|
||||
cx = column1Width;
|
||||
if ((x + cx) > pageRect.right)
|
||||
cx = pageRect.right - x;
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
hdwp = DeferWindowPos(hdwp, hControl, NULL, x, y, cx, cy, flags);
|
||||
if (NULL == hdwp) break;
|
||||
}
|
||||
|
||||
if (NULL != hdwp)
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
|
||||
|
||||
BOOL LoginPageCredentials::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
HWND hControl;
|
||||
const INT szLinks[] = { IDC_CREATE_ACCOUNT, IDC_RECOVER_ACCOUNT };
|
||||
for (INT i = 0; i < ARRAYSIZE(szLinks); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szLinks[i]);
|
||||
if (NULL == hControl) continue;
|
||||
|
||||
RECT linkMargins;
|
||||
SetRect(&linkMargins, 2, 0, 2, 2);
|
||||
MapDialogRect(hwnd, &linkMargins);
|
||||
CommandLink_SetMargins(hControl, &linkMargins);
|
||||
}
|
||||
|
||||
HFONT fontLabel = NULL, fontEdit = NULL;
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
fontLabel = loginGui->GetTextFont();
|
||||
fontEdit = loginGui->GetEditorFont();
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
if (NULL != fontLabel)
|
||||
{
|
||||
const INT szLabels[] = { IDC_USERNAME_LABEL, IDC_PASSWORD_LABEL};
|
||||
for (INT i = 0; i < ARRAYSIZE(szLabels); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szLabels[i]);
|
||||
if (NULL != hControl)
|
||||
SendMessage(hControl, WM_SETFONT, (WPARAM)fontLabel, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != fontEdit)
|
||||
{
|
||||
const INT szEdits[] = { IDC_USERNAME, IDC_PASSWORD};
|
||||
for (INT i = 0; i < ARRAYSIZE(szEdits); i++)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, szEdits[i]);
|
||||
if (NULL != hControl)
|
||||
SendMessage(hControl, WM_SETFONT, (WPARAM)fontEdit, 0L);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LoginPage::OnInitDialog(hFocus, param);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL LoginPageCredentials::OnNotify(UINT controlId, const NMHDR *pnmh)
|
||||
{
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_CREATE_ACCOUNT:
|
||||
if (pnmh->code == NM_CLICK && NULL != accountCreateUrl && L'\0' != *accountCreateUrl)
|
||||
LoginBox_OpenUrl(hwnd, accountCreateUrl, TRUE);
|
||||
return TRUE;
|
||||
|
||||
case IDC_RECOVER_ACCOUNT:
|
||||
if (pnmh->code == NM_CLICK && NULL != accountRecoverUrl && L'\0' != *accountRecoverUrl)
|
||||
LoginBox_OpenUrl(hwnd, accountRecoverUrl, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
return LoginPage::OnNotify(controlId, pnmh);
|
||||
}
|
||||
BOOL LoginPageCredentials::OnGetLoginData(LoginData **ppLoginData)
|
||||
{
|
||||
if (NULL == ppLoginData)
|
||||
return FALSE;
|
||||
|
||||
HWND hEdit;
|
||||
LPWSTR username, password;
|
||||
|
||||
hEdit = GetDlgItem(hwnd, IDC_USERNAME);
|
||||
if (NULL == hEdit || FAILED(LoginBox_GetWindowText(hEdit, &username, NULL)))
|
||||
username = NULL;
|
||||
|
||||
hEdit = GetDlgItem(hwnd, IDC_PASSWORD);
|
||||
if (NULL == hEdit || FAILED(LoginBox_GetWindowText(hEdit, &password, NULL)))
|
||||
password = NULL;
|
||||
|
||||
HRESULT hr = LoginDataCredentials::CreateInstance(NULL, hwnd, hLoginbox,
|
||||
username, password, (LoginDataCredentials**)ppLoginData);
|
||||
|
||||
LoginBox_FreeStringSecure(username);
|
||||
LoginBox_FreeStringSecure(password);
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
void LoginPageCredentials::OnSetAccountRecoverUrl(LPCWSTR pszUrl)
|
||||
{
|
||||
LoginBox_FreeString(accountRecoverUrl);
|
||||
accountRecoverUrl = LoginBox_CopyString(pszUrl);
|
||||
|
||||
HWND hLink = GetDlgItem(hwnd, IDC_RECOVER_ACCOUNT);
|
||||
if (NULL != hLink)
|
||||
{
|
||||
INT showWindow = (NULL != accountRecoverUrl && S_OK == IsValidURL(NULL, accountRecoverUrl, 0)) ? SW_SHOWNA : SW_HIDE;
|
||||
ShowWindow(hLink, showWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPageCredentials::OnSetAccountCreateUrl(LPCWSTR pszUrl)
|
||||
{
|
||||
LoginBox_FreeString(accountCreateUrl);
|
||||
accountCreateUrl = LoginBox_CopyString(pszUrl);
|
||||
|
||||
HWND hLink = GetDlgItem(hwnd, IDC_CREATE_ACCOUNT);
|
||||
if (NULL != hLink)
|
||||
{
|
||||
INT showWindow = (NULL != accountCreateUrl && S_OK == IsValidURL(NULL, accountCreateUrl, 0)) ? SW_SHOWNA : SW_HIDE;
|
||||
ShowWindow(hLink, showWindow);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPageCredentials::OnSetUsernameLabel(LPCWSTR pszLabel)
|
||||
{
|
||||
SetLabelText(IDC_USERNAME_LABEL, pszLabel);
|
||||
}
|
||||
|
||||
void LoginPageCredentials::OnSetPasswordLabel(LPCWSTR pszLabel)
|
||||
{
|
||||
SetLabelText(IDC_PASSWORD_LABEL, pszLabel);
|
||||
}
|
||||
|
||||
BOOL LoginPageCredentials::OnSetUsername(LPCWSTR pszUsername)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_USERNAME);
|
||||
if (NULL == hEdit) return FALSE;
|
||||
|
||||
BOOL result = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)pszUsername);
|
||||
if (FALSE != result)
|
||||
{
|
||||
SNDMSG(hEdit, EM_SETSEL, 0, -1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
BOOL LoginPageCredentials::OnSetPassword(LPCWSTR pszPassword)
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_PASSWORD);
|
||||
if (NULL == hEdit) return FALSE;
|
||||
|
||||
BOOL result = (BOOL)SNDMSG(hEdit, WM_SETTEXT, 0, (LPARAM)pszPassword);
|
||||
if (FALSE != result)
|
||||
{
|
||||
SNDMSG(hEdit, EM_SETSEL, 0, -1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HWND LoginPageCredentials::OnGetFirstItem()
|
||||
{
|
||||
HWND hEdit = GetDlgItem(hwnd, IDC_USERNAME);
|
||||
if (NULL != hEdit && (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & GetWindowStyle(hEdit))))
|
||||
return hEdit;
|
||||
|
||||
return LoginPage::OnGetFirstItem();
|
||||
}
|
||||
|
||||
|
||||
INT_PTR LoginPageCredentials::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case NLPCM_SETACCOUNTRECOVERURL: OnSetAccountRecoverUrl((LPCWSTR)lParam); return TRUE;
|
||||
case NLPCM_SETACCOUNTCREATEURL: OnSetAccountCreateUrl((LPCWSTR)lParam); return TRUE;
|
||||
case NLPCM_SETUSERNAMELABEL: OnSetUsernameLabel((LPCWSTR)lParam); return TRUE;
|
||||
case NLPCM_SETPASSWORDLABEL: OnSetPasswordLabel((LPCWSTR)lParam); return TRUE;
|
||||
}
|
||||
return __super::DialogProc(uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
66
Src/auth/Loginbox/pageCredentials.h
Normal file
66
Src/auth/Loginbox/pageCredentials.h
Normal file
@@ -0,0 +1,66 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PAGE_CREDENTIALS_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PAGE_CREDENTIALS_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPage.h"
|
||||
|
||||
#define NLPCM_FIRST (NLPM_PAGEFIRST + 0)
|
||||
|
||||
#define NLPCM_SETACCOUNTRECOVERURL (NLPCM_FIRST + 1) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszAccountRecoverUrl; Return - no return value.
|
||||
#define LoginPageCredentials_SetAccountRecoverUrl(/*HWND*/ __hwnd, /*LPCWSTR*/ __url)\
|
||||
(SNDMSG((__hwnd), NLPCM_SETACCOUNTRECOVERURL, 0, (LPARAM)(__url)))
|
||||
|
||||
#define NLPCM_SETACCOUNTCREATEURL (NLPCM_FIRST + 2) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszAccountCreateUrl; Return - no return value.
|
||||
#define LoginPageCredentials_SetAccountCreateUrl(/*HWND*/ __hwnd, /*LPCWSTR*/ __url)\
|
||||
(SNDMSG((__hwnd), NLPCM_SETACCOUNTCREATEURL, 0, (LPARAM)(__url)))
|
||||
|
||||
#define NLPCM_SETUSERNAMELABEL (NLPCM_FIRST + 3) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszUsernameLabel; Return - no return value.
|
||||
#define LoginPageCredentials_SetUsernameLabel(/*HWND*/ __hwnd, /*LPCWSTR*/ __label)\
|
||||
(SNDMSG((__hwnd), NLPCM_SETUSERNAMELABEL, 0, (LPARAM)(__label)))
|
||||
|
||||
#define NLPCM_SETPASSWORDLABEL (NLPCM_FIRST + 4) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszPasswordLabel; Return - no return value.
|
||||
#define LoginPageCredentials_SetPasswordLabel(/*HWND*/ __hwnd, /*LPCWSTR*/ __label)\
|
||||
(SNDMSG((__hwnd), NLPCM_SETPASSWORDLABEL, 0, (LPARAM)(__label)))
|
||||
|
||||
class LoginPageCredentials : public LoginPage
|
||||
{
|
||||
protected:
|
||||
LoginPageCredentials(HWND hwnd, HWND hLoginbox);
|
||||
~LoginPageCredentials();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, HWND hParent);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
BOOL OnNotify(UINT controlId, const NMHDR *pnmh);
|
||||
|
||||
BOOL OnGetLoginData(LoginData **ppLoginData);
|
||||
BOOL OnSetUsername(LPCWSTR pszUsername);
|
||||
BOOL OnSetPassword(LPCWSTR pszPassword);
|
||||
HWND OnGetFirstItem();
|
||||
|
||||
void OnSetAccountRecoverUrl(LPCWSTR pszUrl);
|
||||
void OnSetAccountCreateUrl(LPCWSTR pszUrl);
|
||||
void OnSetUsernameLabel(LPCWSTR pszLabel);
|
||||
void OnSetPasswordLabel(LPCWSTR pszLabel);
|
||||
|
||||
|
||||
INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPageCredentials_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance);
|
||||
|
||||
protected:
|
||||
LPWSTR accountRecoverUrl;
|
||||
LPWSTR accountCreateUrl;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PAGE_CREDENTIALS_HEADER
|
||||
171
Src/auth/Loginbox/pageEmpty.cpp
Normal file
171
Src/auth/Loginbox/pageEmpty.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
#include "./pageEmpty.h"
|
||||
#include "./loginBox.h"
|
||||
#include "./common.h"
|
||||
#include "../resource.h"
|
||||
|
||||
|
||||
static HRESULT CALLBACK LoginPageEmpty_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPageEmpty(hwnd, hLoginbox);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPageEmpty::LoginPageEmpty(HWND hwnd, HWND hLoginbox)
|
||||
: LoginPage(hwnd, hLoginbox)
|
||||
{
|
||||
}
|
||||
|
||||
LoginPageEmpty::~LoginPageEmpty()
|
||||
{
|
||||
}
|
||||
|
||||
HWND LoginPageEmpty::CreatePage(HWND hLoginbox, HWND hParent)
|
||||
{
|
||||
return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_EMPTY),
|
||||
hParent, NULL, LoginPageEmpty_CreateInstance);
|
||||
}
|
||||
|
||||
BOOL LoginPageEmpty::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
if (NULL != hLoginbox)
|
||||
{
|
||||
BOOL updateActive = LoginBox_GetUpdateState(hLoginbox);
|
||||
EnableCheckButton(FALSE == updateActive);
|
||||
}
|
||||
|
||||
LoginPage::OnInitDialog(hFocus, param);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPageEmpty::OnCommand(UINT commandId, UINT eventType, HWND hControl)
|
||||
{
|
||||
switch(commandId)
|
||||
{
|
||||
case IDC_CHECKNOW:
|
||||
if (BN_CLICKED == eventType && NULL != hLoginbox)
|
||||
LoginBox_UpdateProviders(hLoginbox, TRUE);
|
||||
break;
|
||||
}
|
||||
LoginPage::OnCommand(commandId, eventType, hControl);
|
||||
}
|
||||
|
||||
void LoginPageEmpty::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPage::UpdateLayout(fRedraw);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
|
||||
RECT offsetRect;
|
||||
SetRect(&offsetRect, 2, 4, 4, 22);
|
||||
MapDialogRect(hwnd, &offsetRect);
|
||||
|
||||
clientRect.left += offsetRect.left;
|
||||
clientRect.top += offsetRect.top;
|
||||
clientRect.right -= offsetRect.right;
|
||||
clientRect.bottom -= offsetRect.bottom;
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
const INT szControls[] = { IDC_MESSAGE, IDC_CHECKNOW, IDC_CHECK_STATUS};
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
|
||||
|
||||
RECT rect;
|
||||
LONG clientTop = clientRect.top;
|
||||
LONG left, top = clientRect.top;
|
||||
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);
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_MESSAGE:
|
||||
top = clientRect.top + ((clientRect.bottom - clientRect.top) - (rect.bottom - rect.top))/2;
|
||||
left = clientRect.left + ((clientRect.right - clientRect.left) - (rect.right - rect.left))/2;
|
||||
OffsetRect(&rect, left - rect.left, top - rect.top);
|
||||
clientTop = rect.bottom;
|
||||
break;
|
||||
case IDC_CHECKNOW:
|
||||
top = clientTop + 2*offsetRect.top;
|
||||
left = clientRect.left + ((clientRect.right - clientRect.left) - (rect.right - rect.left))/2;
|
||||
OffsetRect(&rect, left - rect.left, top - rect.top);
|
||||
break;
|
||||
case IDC_CHECK_STATUS:
|
||||
top = clientTop + offsetRect.top;
|
||||
left = clientRect.left + ((clientRect.right - clientRect.left) - (rect.right - rect.left))/2;
|
||||
OffsetRect(&rect, left - rect.left, top - rect.top);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
HBRUSH LoginPageEmpty::OnGetStaticColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
INT_PTR controlId = (INT_PTR)GetWindowLongPtr(hControl, GWLP_ID);
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_MESSAGE:
|
||||
case IDC_CHECK_STATUS:
|
||||
SetTextColor(hdc, rgbSecondaryText);
|
||||
SetBkColor(hdc, rgbBack);
|
||||
return hbrBack;
|
||||
}
|
||||
|
||||
return LoginPage::OnGetStaticColor(hdc, hControl);
|
||||
}
|
||||
|
||||
BOOL LoginPageEmpty::OnGetLoginData(LoginData **ppLoginData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void LoginPageEmpty::OnUpdateStateChange(BOOL updateActive)
|
||||
{
|
||||
EnableCheckButton(FALSE == updateActive);
|
||||
}
|
||||
|
||||
void LoginPageEmpty::EnableCheckButton(BOOL fEnable)
|
||||
{
|
||||
HWND hButton = GetDlgItem(hwnd, IDC_CHECKNOW);
|
||||
HWND hStatus = GetDlgItem(hwnd, IDC_CHECK_STATUS);
|
||||
|
||||
if (FALSE != fEnable)
|
||||
{
|
||||
if (NULL != hStatus)
|
||||
ShowWindow(hStatus, SW_HIDE);
|
||||
|
||||
if (NULL != hButton)
|
||||
{
|
||||
EnableWindow(hButton, TRUE);
|
||||
ShowWindow(hButton, SW_SHOWNA);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if (NULL != hButton)
|
||||
{
|
||||
if (NULL != hStatus)
|
||||
ShowWindow(hButton, SW_HIDE);
|
||||
EnableWindow(hButton, FALSE);
|
||||
}
|
||||
if (NULL != hStatus)
|
||||
ShowWindow(hStatus, SW_SHOWNA);
|
||||
}
|
||||
}
|
||||
|
||||
37
Src/auth/Loginbox/pageEmpty.h
Normal file
37
Src/auth/Loginbox/pageEmpty.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PAGE_EMPTY_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PAGE_EMPTY_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPage.h"
|
||||
|
||||
class LoginPageEmpty: public LoginPage
|
||||
{
|
||||
protected:
|
||||
LoginPageEmpty(HWND hwnd, HWND hLoginbox);
|
||||
~LoginPageEmpty();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, HWND hParent);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
void EnableCheckButton(BOOL fEnable);
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
void OnCommand(UINT commandId, UINT eventType, HWND hControl);
|
||||
|
||||
BOOL OnGetLoginData(LoginData **ppLoginData);
|
||||
void OnUpdateStateChange(BOOL updateActive);
|
||||
|
||||
HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPageEmpty_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PAGE_EMPTY_HEADER
|
||||
98
Src/auth/Loginbox/pageError.cpp
Normal file
98
Src/auth/Loginbox/pageError.cpp
Normal file
@@ -0,0 +1,98 @@
|
||||
#include "./pageError.h"
|
||||
#include "./loginBox.h"
|
||||
#include "./common.h"
|
||||
#include "../resource.h"
|
||||
|
||||
|
||||
static HRESULT CALLBACK LoginPageError_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPageError(hwnd, hLoginbox);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPageError::LoginPageError(HWND hwnd, HWND hLoginbox)
|
||||
: LoginPage(hwnd, hLoginbox)
|
||||
{
|
||||
}
|
||||
|
||||
LoginPageError::~LoginPageError()
|
||||
{
|
||||
}
|
||||
|
||||
HWND LoginPageError::CreatePage(HWND hLoginbox, HWND hParent)
|
||||
{
|
||||
return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_ERROR),
|
||||
hParent, NULL, LoginPageError_CreateInstance);
|
||||
}
|
||||
|
||||
void LoginPageError::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPage::UpdateLayout(fRedraw);
|
||||
|
||||
RECT clientRect;
|
||||
GetClientRect(hwnd, &clientRect);
|
||||
|
||||
RECT offsetRect;
|
||||
SetRect(&offsetRect, 2, 4, 4, 22);
|
||||
MapDialogRect(hwnd, &offsetRect);
|
||||
|
||||
clientRect.left += offsetRect.left;
|
||||
clientRect.top += offsetRect.top;
|
||||
clientRect.right -= offsetRect.right;
|
||||
clientRect.bottom -= offsetRect.bottom;
|
||||
|
||||
UINT flags = SWP_NOACTIVATE | SWP_NOZORDER;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
const INT szControls[] = { IDC_MESSAGE, };
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szControls));
|
||||
|
||||
RECT rect;
|
||||
LONG left, top = clientRect.top;
|
||||
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);
|
||||
|
||||
switch(szControls[i])
|
||||
{
|
||||
case IDC_MESSAGE:
|
||||
top = clientRect.top + ((clientRect.bottom - clientRect.top) - (rect.bottom - rect.top))/2;
|
||||
left = clientRect.left + ((clientRect.right - clientRect.left) - (rect.right - rect.left))/2;
|
||||
OffsetRect(&rect, left - rect.left, top - rect.top);
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
HBRUSH LoginPageError::OnGetStaticColor(HDC hdc, HWND hControl)
|
||||
{
|
||||
INT_PTR controlId = (INT_PTR)GetWindowLongPtr(hControl, GWLP_ID);
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_MESSAGE:
|
||||
SetTextColor(hdc, rgbSecondaryText);
|
||||
SetBkColor(hdc, rgbBack);
|
||||
return hbrBack;
|
||||
}
|
||||
|
||||
return LoginPage::OnGetStaticColor(hdc, hControl);
|
||||
}
|
||||
|
||||
BOOL LoginPageError::OnGetLoginData(LoginData **ppLoginData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
31
Src/auth/Loginbox/pageError.h
Normal file
31
Src/auth/Loginbox/pageError.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PAGE_ERROR_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PAGE_ERROR_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPage.h"
|
||||
|
||||
class LoginPageError : public LoginPage
|
||||
{
|
||||
protected:
|
||||
LoginPageError(HWND hwnd, HWND hLoginbox);
|
||||
~LoginPageError();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, HWND hParent);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
|
||||
HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
BOOL OnGetLoginData(LoginData **ppLoginData);
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPageError_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PAGE_ERROR_HEADER
|
||||
131
Src/auth/Loginbox/pageInfo.cpp
Normal file
131
Src/auth/Loginbox/pageInfo.cpp
Normal file
@@ -0,0 +1,131 @@
|
||||
#include "./pageInfo.h"
|
||||
#include "./common.h"
|
||||
#include "./loginGui.h"
|
||||
#include "../resource.h"
|
||||
|
||||
|
||||
static HRESULT CALLBACK LoginPageInfo_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd || NULL == hLoginbox) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPageInfo(hwnd, hLoginbox);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPageInfo::LoginPageInfo(HWND hwnd, HWND hLoginbox)
|
||||
: LoginPage(hwnd, hLoginbox)
|
||||
{
|
||||
}
|
||||
|
||||
LoginPageInfo::~LoginPageInfo()
|
||||
{
|
||||
}
|
||||
|
||||
HWND LoginPageInfo::CreatePage(HWND hLoginbox, HWND hParent)
|
||||
{
|
||||
return LoginPage::CreatePage(hLoginbox, MAKEINTRESOURCE(IDD_PAGE_INFO),
|
||||
hParent, NULL, LoginPageInfo_CreateInstance);
|
||||
}
|
||||
|
||||
void LoginPageInfo::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPage::UpdateLayout(fRedraw);
|
||||
|
||||
RECT pageRect;
|
||||
if (FALSE == GetPageRect(&pageRect))
|
||||
return;
|
||||
|
||||
|
||||
HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL == hMessage) return;
|
||||
|
||||
INT cx, cy;
|
||||
cx = pageRect.right - pageRect.left;
|
||||
|
||||
HDC hdc = GetDCEx(hMessage, NULL, DCX_CACHE | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT fontControl = (HFONT)SendMessage(hMessage, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, fontControl);
|
||||
|
||||
INT maxWidth = LoginBox_GetAveStrWidth(hdc, 80);
|
||||
if (cx > maxWidth) cx = maxWidth;
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hMessage, hdc);
|
||||
}
|
||||
|
||||
LoginBox_GetWindowTextSize(hMessage, cx, &cx, &cy);
|
||||
if(cy > (pageRect.bottom - pageRect.top))
|
||||
cy = pageRect.bottom - pageRect.top;
|
||||
|
||||
RECT messageRect;
|
||||
GetWindowRect(hMessage, &messageRect);
|
||||
MapWindowPoints(HWND_DESKTOP, hwnd, (POINT*)&messageRect, 2);
|
||||
if (messageRect.left != pageRect.left ||
|
||||
messageRect.top != pageRect.top ||
|
||||
(messageRect.right - messageRect.left) != cx ||
|
||||
(messageRect.bottom - messageRect.top) != cy)
|
||||
{
|
||||
|
||||
SetWindowPos(hMessage, NULL, pageRect.left, pageRect.top, cx, cy,
|
||||
SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOREDRAW);
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
HRGN rgn1 = CreateRectRgnIndirect(&messageRect);
|
||||
HRGN rgn2 = CreateRectRgn(pageRect.left, pageRect.top, pageRect.left + cx, pageRect.top + cy);
|
||||
CombineRgn(rgn1, rgn1, rgn2, RGN_OR);
|
||||
RedrawWindow(hwnd, NULL, rgn1, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE | RDW_ERASENOW | RDW_VALIDATE | RDW_ALLCHILDREN);
|
||||
DeleteObject(rgn1);
|
||||
DeleteObject(rgn2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL LoginPageInfo::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
HFONT fontText = NULL;
|
||||
LoginGuiObject *loginGui;
|
||||
if (SUCCEEDED(LoginGuiObject::QueryInstance(&loginGui)))
|
||||
{
|
||||
fontText = loginGui->GetTextFont();
|
||||
loginGui->Release();
|
||||
}
|
||||
|
||||
if (NULL != fontText)
|
||||
{
|
||||
HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL != hMessage)
|
||||
SendMessage(hMessage, WM_SETFONT, (WPARAM)fontText, 0L);
|
||||
}
|
||||
|
||||
LoginPage::OnInitDialog(hFocus, param);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
void LoginPageInfo::OnSetMessage(LPCWSTR pszMessage)
|
||||
{
|
||||
HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL != hMessage)
|
||||
{
|
||||
SetWindowText(hMessage, pszMessage);
|
||||
INT showWindow = (NULL != pszMessage && L'\0' != *pszMessage) ? SW_SHOWNA : SW_HIDE;
|
||||
ShowWindow(hMessage, showWindow);
|
||||
}
|
||||
}
|
||||
|
||||
INT_PTR LoginPageInfo::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case NLPIM_SETMESSAGE: OnSetMessage((LPCWSTR)lParam); return TRUE;
|
||||
}
|
||||
return __super::DialogProc(uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
41
Src/auth/Loginbox/pageInfo.h
Normal file
41
Src/auth/Loginbox/pageInfo.h
Normal file
@@ -0,0 +1,41 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PAGE_INFO_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PAGE_INFO_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPage.h"
|
||||
|
||||
#define NLPIM_FIRST (NLPM_PAGEFIRST + 0)
|
||||
|
||||
#define NLPIM_SETMESSAGE (NLPIM_FIRST + 0) //wParam - not used, lParam = (LPARAM)(LPCWSTR)pszMessage; Return - no return value.
|
||||
#define LoginPageInfo_SetMessage(/*HWND*/ __hwnd, /*LPCWSTR*/ __pszMessage)\
|
||||
(SNDMSG((__hwnd), NLPIM_SETMESSAGE, 0, (LPARAM)(__pszMessage)))
|
||||
|
||||
class LoginPageInfo: public LoginPage
|
||||
{
|
||||
protected:
|
||||
LoginPageInfo(HWND hwnd, HWND hLoginbox);
|
||||
~LoginPageInfo();
|
||||
|
||||
public:
|
||||
static HWND CreatePage(HWND hLoginbox, HWND hParent);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
|
||||
void OnSetMessage(LPCWSTR pszMessage);
|
||||
|
||||
INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPageInfo_CreateInstance(HWND hwnd, HWND hLoginbox, LoginPage **instance);
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PAGE_INFO_HEADER
|
||||
16
Src/auth/Loginbox/png.rc
Normal file
16
Src/auth/Loginbox/png.rc
Normal file
@@ -0,0 +1,16 @@
|
||||
#include "../resource.h"
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Data
|
||||
//
|
||||
IDR_POPUPBORDER_IMAGE RCDATA
|
||||
".\\resources\\popupBorder.png"
|
||||
|
||||
IDR_NOTIFIERICONS_IMAGE RCDATA
|
||||
".\\resources\\notifierIcons.png"
|
||||
|
||||
IDR_SELECTIONFRAME_IMAGE RCDATA
|
||||
".\\resources\\selection.png"
|
||||
|
||||
IDR_ARROW_IMAGE RCDATA
|
||||
".\\resources\\arrow.png"
|
||||
567
Src/auth/Loginbox/popupAgreement.cpp
Normal file
567
Src/auth/Loginbox/popupAgreement.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
#include "./popupAgreement.h"
|
||||
#include "./loginNotifier.h"
|
||||
#include "./loginProvider.h"
|
||||
|
||||
#include "./common.h"
|
||||
#include "../resource.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include "../../winamp/commandLink.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define LINK_TOS 0
|
||||
#define STATIC_AND 1
|
||||
#define LINK_PRIVACY 2
|
||||
|
||||
#define IDC_AOL 11000
|
||||
#define IDC_AOL_TOS (IDC_AOL + LINK_TOS)
|
||||
#define IDC_AOL_AND (IDC_AOL + STATIC_AND)
|
||||
#define IDC_AOL_PRIVACY (IDC_AOL + LINK_PRIVACY)
|
||||
|
||||
#define IDC_3DPARTY 11010
|
||||
#define IDC_3DPARTY_TOS (IDC_3DPARTY + LINK_TOS)
|
||||
#define IDC_3DPARTY_AND (IDC_3DPARTY + STATIC_AND)
|
||||
#define IDC_3DPARTY_PRIVACY (IDC_3DPARTY + LINK_PRIVACY)
|
||||
|
||||
|
||||
#define LINK_TARGET L"LinkTargetProp"
|
||||
|
||||
typedef struct __PARTSIZE
|
||||
{
|
||||
HWND hwnd;
|
||||
LONG cx;
|
||||
LONG cy;
|
||||
} PARTSIZE;
|
||||
|
||||
typedef struct __LINKSIZEINFO
|
||||
{
|
||||
PARTSIZE tos;
|
||||
PARTSIZE and;
|
||||
PARTSIZE privacy;
|
||||
LONG spaceWidth;
|
||||
RECT linkMargins;
|
||||
} LINKSIZEINFO;
|
||||
|
||||
static HRESULT CALLBACK LoginPopupAgreement_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPopupAgreement(hwnd);
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPopupAgreement::LoginPopupAgreement(HWND hwnd)
|
||||
: LoginPopup(hwnd, -1, MAKEINTRESOURCE(IDS_POPUP_AGREEMENT_TITLE))
|
||||
{
|
||||
}
|
||||
|
||||
LoginPopupAgreement::~LoginPopupAgreement()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
HWND LoginPopupAgreement::CreatePopup(HWND hParent, LoginProvider *provider)
|
||||
{
|
||||
if (NULL == provider)
|
||||
return NULL;
|
||||
|
||||
return LoginPopup::CreatePopup(MAKEINTRESOURCE(IDD_POPUP_AGREEMENT), hParent, (LPARAM)provider, LoginPopupAgreement_CreateInstance);
|
||||
}
|
||||
|
||||
void LoginPopupAgreement::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPopup::UpdateLayout(fRedraw);
|
||||
|
||||
RECT rect;
|
||||
if (FALSE == GetInfoRect(&rect)) return;
|
||||
|
||||
const INT szButtons[] = { IDOK, IDCANCEL, };
|
||||
|
||||
|
||||
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
HDWP hdwp = BeginDeferWindowPos(ARRAYSIZE(szButtons) + 1 + 2*3);
|
||||
if (NULL == hdwp) return;
|
||||
|
||||
hdwp = LayoutButtons(hdwp, szButtons, ARRAYSIZE(szButtons), fRedraw, NULL);
|
||||
|
||||
LONG top = rect.top;
|
||||
SIZE partSize;
|
||||
HWND hText = GetDlgItem(hwnd, IDC_TEXT);
|
||||
if (NULL != hText && FALSE != GetTextSize(hText, rect.right - rect.left, &partSize))
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, hText, NULL, rect.left, top, partSize.cx, partSize.cy, flags);
|
||||
if (NULL == hdwp) return;
|
||||
top += partSize.cy;
|
||||
}
|
||||
|
||||
top += marginLinkFirst;
|
||||
hdwp = LayoutProviderLinks(hdwp, IDC_AOL, NULL, rect.left + marginLinkLeft, top, flags, &partSize);
|
||||
if (NULL == hdwp) return;
|
||||
|
||||
if (0 != partSize.cy)
|
||||
top += partSize.cy + marginLinkNext;
|
||||
hdwp = LayoutProviderLinks(hdwp, IDC_3DPARTY, NULL, rect.left + marginLinkLeft, top, flags, &partSize);
|
||||
if (NULL == hdwp) return;
|
||||
|
||||
EndDeferWindowPos(hdwp);
|
||||
|
||||
if (FALSE != fRedraw)
|
||||
{
|
||||
HWND hControl = GetDlgItem(hwnd, IDC_TEXT);
|
||||
if (NULL != hControl) InvalidateRect(hControl, NULL, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginPopupAgreement::EndDialog(INT_PTR code)
|
||||
{
|
||||
NLPNRESULT result;
|
||||
result.exitCode = code;
|
||||
SendNotification(NLPN_RESULT, (NMHDR*)&result);
|
||||
|
||||
LoginPopup::EndDialog(code);
|
||||
}
|
||||
|
||||
void LoginPopupAgreement::UpdateMargins()
|
||||
{
|
||||
RECT rect;
|
||||
SetRect(&rect, 8, 8, 0, 2);
|
||||
MapDialogRect(hwnd, &rect);
|
||||
|
||||
marginLinkLeft = rect.left;
|
||||
marginLinkFirst = rect.top;
|
||||
marginLinkNext = rect.bottom;
|
||||
|
||||
LoginPopup::UpdateMargins();
|
||||
}
|
||||
|
||||
static BOOL ProviderLinks_GetSizeInfo(HWND hwnd, INT groupId, LINKSIZEINFO *sizeInfo)
|
||||
{
|
||||
if(NULL == sizeInfo)
|
||||
return FALSE;
|
||||
|
||||
HWND hControl;
|
||||
SIZE partSize;
|
||||
|
||||
SetRectEmpty(&sizeInfo->linkMargins);
|
||||
|
||||
hControl = GetDlgItem(hwnd, groupId + LINK_TOS);
|
||||
if (NULL == hControl ||
|
||||
0 == (WS_VISIBLE & GetWindowStyle(hControl)) ||
|
||||
FALSE == CommandLink_GetIdealSize(hControl, &partSize))
|
||||
{
|
||||
ZeroMemory(&sizeInfo->tos, sizeof(PARTSIZE));
|
||||
}
|
||||
else
|
||||
{
|
||||
sizeInfo->tos.hwnd = hControl;
|
||||
sizeInfo->tos.cx = partSize.cx;
|
||||
sizeInfo->tos.cy = partSize.cy;
|
||||
|
||||
CommandLink_GetMargins(hControl, &sizeInfo->linkMargins);
|
||||
}
|
||||
|
||||
hControl = GetDlgItem(hwnd, groupId + LINK_PRIVACY);
|
||||
if (NULL == hControl ||
|
||||
0 == (WS_VISIBLE & GetWindowStyle(hControl)) ||
|
||||
FALSE == CommandLink_GetIdealSize(hControl, &partSize))
|
||||
{
|
||||
ZeroMemory(&sizeInfo->privacy, sizeof(PARTSIZE));
|
||||
}
|
||||
else
|
||||
{
|
||||
sizeInfo->privacy.hwnd = hControl;
|
||||
sizeInfo->privacy.cx = partSize.cx;
|
||||
sizeInfo->privacy.cy = partSize.cy;
|
||||
|
||||
if (IsRectEmpty(&sizeInfo->linkMargins))
|
||||
CommandLink_GetMargins(hControl, &sizeInfo->linkMargins);
|
||||
}
|
||||
|
||||
if (NULL == sizeInfo->tos.hwnd && NULL == sizeInfo->privacy.hwnd)
|
||||
return FALSE;
|
||||
|
||||
ZeroMemory(&sizeInfo->and, sizeof(PARTSIZE));
|
||||
sizeInfo->spaceWidth = 0;
|
||||
|
||||
if (NULL != sizeInfo->tos.hwnd && NULL != sizeInfo->privacy.hwnd)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, groupId + STATIC_AND);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
WCHAR szBuffer[64] = {0};
|
||||
INT cchLen = (INT)SendMessage(hControl, WM_GETTEXT, ARRAYSIZE(szBuffer), (LPARAM)szBuffer);
|
||||
if (cchLen > 0)
|
||||
{
|
||||
HDC hdc = GetDCEx(hControl, NULL, DCX_CACHE | DCX_WINDOW | DCX_NORESETATTRS);
|
||||
if (NULL != hdc)
|
||||
{
|
||||
HFONT font = (HFONT)SendMessage(hControl, WM_GETFONT, 0, 0L);
|
||||
HFONT fontOrig = (HFONT)SelectObject(hdc, font);
|
||||
|
||||
if (FALSE != GetTextExtentPoint32W(hdc, szBuffer, cchLen, &partSize))
|
||||
{
|
||||
sizeInfo->and.hwnd = hControl;
|
||||
sizeInfo->and.cx = partSize.cx;
|
||||
sizeInfo->and.cy = partSize.cy;
|
||||
}
|
||||
|
||||
if (FALSE != GetTextExtentPoint32W(hdc, L" ", 1, &partSize))
|
||||
{
|
||||
sizeInfo->spaceWidth = partSize.cx;
|
||||
}
|
||||
|
||||
SelectObject(hdc, fontOrig);
|
||||
ReleaseDC(hControl, hdc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HDWP LoginPopupAgreement::LayoutProviderLinks(HDWP hdwp, INT groupId, HWND hwndInsertAfter, INT x, INT y, UINT flags, SIZE *size)
|
||||
{
|
||||
if (NULL == hdwp)
|
||||
{
|
||||
if (NULL == size)
|
||||
return NULL;
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
LONG ox = x, cy = 0;
|
||||
|
||||
LINKSIZEINFO sizeInfo;
|
||||
if (FALSE == ProviderLinks_GetSizeInfo(hwnd, groupId, &sizeInfo))
|
||||
return hdwp;
|
||||
|
||||
if (NULL != sizeInfo.tos.hwnd)
|
||||
{
|
||||
if (NULL != hdwp)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, sizeInfo.tos.hwnd, hwndInsertAfter, x, y, sizeInfo.tos.cx, sizeInfo.tos.cy, flags);
|
||||
if (NULL == hdwp) return NULL;
|
||||
}
|
||||
|
||||
x += sizeInfo.tos.cx;
|
||||
if (cy < sizeInfo.tos.cy) cy = sizeInfo.tos.cy;
|
||||
}
|
||||
|
||||
if (NULL != sizeInfo.and.hwnd)
|
||||
{
|
||||
LONG top = y + ((sizeInfo.tos.cy - (sizeInfo.linkMargins.bottom + sizeInfo.linkMargins.top)) - sizeInfo.and.cy)/2;
|
||||
LONG space = (sizeInfo.spaceWidth - sizeInfo.linkMargins.right);
|
||||
if (space < 1) space = 1;
|
||||
x += space;
|
||||
if (NULL != hdwp)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, sizeInfo.and.hwnd, hwndInsertAfter, x, top, sizeInfo.and.cx, sizeInfo.and.cy, flags);
|
||||
if (NULL == hdwp) return NULL;
|
||||
}
|
||||
|
||||
x += sizeInfo.and.cx;
|
||||
if (cy < sizeInfo.and.cy) cy = sizeInfo.and.cy;
|
||||
}
|
||||
|
||||
if (NULL != sizeInfo.privacy.hwnd)
|
||||
{
|
||||
if (NULL != sizeInfo.and.hwnd)
|
||||
{
|
||||
LONG space = (sizeInfo.spaceWidth - sizeInfo.linkMargins.left);
|
||||
if (space < 1) space = 1;
|
||||
x += space;
|
||||
}
|
||||
|
||||
if (NULL != hdwp)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, sizeInfo.privacy.hwnd, hwndInsertAfter, x, y, sizeInfo.privacy.cx, sizeInfo.privacy.cy, flags);
|
||||
if (NULL == hdwp) return NULL;
|
||||
}
|
||||
|
||||
x += sizeInfo.privacy.cx;
|
||||
if (cy < sizeInfo.privacy.cy) cy = sizeInfo.privacy.cy;
|
||||
|
||||
}
|
||||
|
||||
if (NULL != size)
|
||||
{
|
||||
size->cx = (x - ox);
|
||||
size->cy = cy;
|
||||
}
|
||||
|
||||
return (NULL == hdwp) ? (HDWP)(TRUE) : hdwp;
|
||||
}
|
||||
|
||||
BOOL LoginPopupAgreement::CreateProviderLinks(LPCWSTR pszProvider, LPCWSTR pszTos, LPCWSTR pszPrivacy, INT groupId, HWND hwndInsertAfter)
|
||||
{
|
||||
WCHAR szTemplate[256] = {0}, szBuffer[256] = {0};
|
||||
UINT linkStyle = WS_CHILD | WS_TABSTOP | WS_GROUP | WS_VISIBLE |
|
||||
CLS_DEFAULTCOLORS | CLS_HOTTRACK /*| CLS_ALWAYSUNDERLINE*/;
|
||||
|
||||
HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
|
||||
|
||||
LPWSTR pszUrl;
|
||||
HWND hControl;
|
||||
INT createdCount = 0;
|
||||
INT failedCount = 0;
|
||||
if (NULL != pszTos && L'\0' != *pszTos)
|
||||
{
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_TOSLINK_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate));
|
||||
StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, pszProvider);
|
||||
hControl = CommandLink_CreateWindow(0, szBuffer, linkStyle, 0, 0, 0, 0, hwnd, groupId + LINK_TOS);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
pszUrl = LoginBox_CopyString(pszTos);
|
||||
if (NULL == pszUrl || FALSE == SetProp(hControl, LINK_TARGET, pszUrl))
|
||||
{
|
||||
LoginBox_FreeString(pszUrl);
|
||||
DestroyWindow(hControl);
|
||||
hControl = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != hControl)
|
||||
{
|
||||
SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L);
|
||||
SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
|
||||
hwndInsertAfter = hControl;
|
||||
createdCount++;
|
||||
}
|
||||
else failedCount++;
|
||||
}
|
||||
|
||||
if (0 == failedCount && NULL != pszPrivacy && L'\0' != *pszPrivacy)
|
||||
{
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_PRIVACYLINK_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate));
|
||||
StringCchPrintf(szBuffer, ARRAYSIZE(szBuffer), szTemplate, pszProvider);
|
||||
hControl = CommandLink_CreateWindow(0, szBuffer, linkStyle, 0, 0, 0, 0, hwnd, groupId + LINK_PRIVACY);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
pszUrl = LoginBox_CopyString(pszPrivacy);
|
||||
if (NULL == pszUrl || FALSE == SetProp(hControl, LINK_TARGET, pszUrl))
|
||||
{
|
||||
LoginBox_FreeString(pszUrl);
|
||||
DestroyWindow(hControl);
|
||||
hControl = NULL;
|
||||
}
|
||||
}
|
||||
if (NULL != hControl)
|
||||
{
|
||||
SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L);
|
||||
SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
|
||||
hwndInsertAfter = hControl;
|
||||
createdCount++;
|
||||
}
|
||||
else failedCount++;
|
||||
}
|
||||
|
||||
if (0 == failedCount && createdCount > 1)
|
||||
{
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_AND, szBuffer, ARRAYSIZE(szBuffer));
|
||||
hControl = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Static", szBuffer, WS_CHILD | WS_VISIBLE | SS_LEFT,
|
||||
0, 0, 0, 0, hwnd, (HMENU)(INT_PTR)(groupId + STATIC_AND), NULL, 0L);
|
||||
if (NULL != hControl)
|
||||
{
|
||||
SendMessage(hControl, WM_SETFONT, (WPARAM)font, 0L);
|
||||
SetWindowPos(hControl, hwndInsertAfter, 0, 0,0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW);
|
||||
hwndInsertAfter = hControl;
|
||||
createdCount++;
|
||||
}
|
||||
else
|
||||
failedCount++;
|
||||
}
|
||||
|
||||
if (0 != failedCount)
|
||||
{
|
||||
hControl = GetDlgItem(hwnd, (groupId + LINK_TOS));
|
||||
if (NULL != hControl) DestroyWindow(hControl);
|
||||
hControl = GetDlgItem(hwnd, (groupId + LINK_PRIVACY));
|
||||
if (NULL != hControl) DestroyWindow(hControl);
|
||||
hControl = GetDlgItem(hwnd, (groupId + STATIC_AND));
|
||||
if (NULL != hControl) DestroyWindow(hControl);
|
||||
}
|
||||
|
||||
return (0 == failedCount);
|
||||
}
|
||||
|
||||
BOOL LoginPopupAgreement::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
LoginProvider *provider = (LoginProvider*)param;
|
||||
if (NULL != provider)
|
||||
{
|
||||
WCHAR szName[128] = {0}, szTos[4096] = {0}, szPrivacy[4096] = {0};
|
||||
if (FAILED(provider->GetTosLink(szTos, ARRAYSIZE(szTos))))
|
||||
szTos[0] = L'\0';
|
||||
if (FAILED(provider->GetPrivacyLink(szPrivacy, ARRAYSIZE(szPrivacy))))
|
||||
szPrivacy[0] = L'\0';
|
||||
|
||||
if((L'\0' != szTos[0] || L'\0' != szPrivacy[0]) &&
|
||||
SUCCEEDED(provider->GetName(szName, ARRAYSIZE(szName))))
|
||||
{
|
||||
CreateProviderLinks(szName, szTos, szPrivacy, IDC_3DPARTY, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
CreateProviderLinks(L"AOL", L"https://new.aol.com/freeaolweb/resources/jsp/mem_tos.jsp",
|
||||
L"http://about.aol.com/aolnetwork/mem_policy", IDC_AOL, NULL);
|
||||
|
||||
LoginPopup::OnInitDialog(hFocus, param);
|
||||
|
||||
HWND hAgree = GetDlgItem(hwnd, IDOK);
|
||||
if (NULL != hAgree && (WS_VISIBLE == ((WS_VISIBLE | WS_DISABLED) & GetWindowStyle(hAgree))))
|
||||
{
|
||||
PostMessage(hwnd, WM_NEXTDLGCTL, (WPARAM)hAgree, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
void LoginPopupAgreement::OnDestroy()
|
||||
{
|
||||
INT szLinks[] = {IDC_AOL_TOS, IDC_AOL_PRIVACY, IDC_3DPARTY_TOS, IDC_3DPARTY_PRIVACY, };
|
||||
for (INT i = 0; i < ARRAYSIZE(szLinks); i++)
|
||||
{
|
||||
HWND hLink = GetDlgItem(hwnd, szLinks[i]);
|
||||
if (NULL != hLink) DestroyWindow(hLink);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LoginPopupAgreement::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
|
||||
{
|
||||
if (NULL == clientRect || NULL == rectOut)
|
||||
return FALSE;
|
||||
|
||||
SIZE maxSize;
|
||||
SIZE partSize;
|
||||
|
||||
maxSize.cx = 0;
|
||||
maxSize.cy = 0;
|
||||
|
||||
if (((HDWP)TRUE) == LayoutProviderLinks(NULL, IDC_AOL, NULL, 0, 0, 0, &partSize))
|
||||
{
|
||||
if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx;
|
||||
maxSize.cy += (partSize.cy + marginLinkFirst);
|
||||
}
|
||||
|
||||
if (((HDWP)TRUE) == LayoutProviderLinks(NULL, IDC_3DPARTY, NULL, 0, 0, 0, &partSize))
|
||||
{
|
||||
if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx;
|
||||
maxSize.cy += (partSize.cy + ((0 == maxSize.cy) ? marginLinkFirst : marginLinkNext));
|
||||
}
|
||||
|
||||
if (0 != maxSize.cx)
|
||||
maxSize.cx += marginLinkLeft;
|
||||
|
||||
if (0 != maxSize.cy)
|
||||
maxSize.cy += marginLinkFirst;
|
||||
|
||||
LONG maxWidth = clientRect->right - clientRect->left -
|
||||
(clientMargins.right + clientMargins.left) -
|
||||
(infoMargins.right + infoMargins.left);
|
||||
|
||||
if (maxSize.cx > maxWidth)
|
||||
maxSize.cx = maxWidth;
|
||||
|
||||
if (FALSE != GetTextSize(GetDlgItem(hwnd, IDC_TEXT), maxWidth, &partSize))
|
||||
{
|
||||
if (maxSize.cx < partSize.cx) maxSize.cx = partSize.cx;
|
||||
maxSize.cy += partSize.cy;
|
||||
}
|
||||
|
||||
if (FALSE == CalculateWindowRect(maxSize.cx, maxSize.cy, NULL, 0, TRUE, rectOut))
|
||||
return FALSE;
|
||||
|
||||
|
||||
LONG ox = clientRect->left + ((clientRect->right - clientRect->left) - (rectOut->right - rectOut->left))/2;
|
||||
LONG oy = clientRect->top + ((clientRect->bottom - clientRect->top) - (rectOut->bottom - rectOut->top))/2;
|
||||
|
||||
if (ox < clientRect->left) ox = clientRect->left;
|
||||
if (oy < clientRect->top) oy = clientRect->top;
|
||||
|
||||
OffsetRect(rectOut, ox, oy);
|
||||
return TRUE;
|
||||
}
|
||||
HBRUSH LoginPopupAgreement::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_AOL_AND:
|
||||
case IDC_3DPARTY_AND:
|
||||
{
|
||||
HWND hLink = GetDlgItem(hwnd, (controlId - STATIC_AND));
|
||||
if (NULL != hLink)
|
||||
{
|
||||
// SetTextColor(hdc, CommandLink_GetTextColor(hLink));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return hb;
|
||||
}
|
||||
|
||||
void LoginPopupAgreement::OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam)
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case WM_DESTROY:
|
||||
switch(wParam)
|
||||
{
|
||||
case IDC_AOL_TOS:
|
||||
case IDC_AOL_PRIVACY:
|
||||
case IDC_3DPARTY_TOS:
|
||||
case IDC_3DPARTY_PRIVACY:
|
||||
{
|
||||
LPWSTR url = (LPWSTR)GetProp((HWND)lParam, LINK_TARGET);
|
||||
RemoveProp((HWND)lParam, LINK_TARGET);
|
||||
LoginBox_FreeString(url);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
LoginPopup::OnParentNotify(eventId, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
void LoginPopupAgreement::OnLinkClicked(HWND hLink)
|
||||
{
|
||||
if (NULL == hLink)
|
||||
return;
|
||||
|
||||
LPCWSTR pszTarget = (LPCWSTR)GetProp(hLink, LINK_TARGET);
|
||||
if (NULL != pszTarget && L'\0' != *pszTarget)
|
||||
{
|
||||
LoginBox_OpenUrl(hwnd, pszTarget, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT LoginPopupAgreement::OnNotify(UINT controlId, const NMHDR *pnmh)
|
||||
{
|
||||
switch(controlId)
|
||||
{
|
||||
case IDC_AOL_TOS:
|
||||
case IDC_AOL_PRIVACY:
|
||||
case IDC_3DPARTY_TOS:
|
||||
case IDC_3DPARTY_PRIVACY:
|
||||
switch(pnmh->code)
|
||||
{
|
||||
case NM_CLICK:
|
||||
OnLinkClicked(pnmh->hwndFrom);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return LoginPopup::OnNotify(controlId, pnmh);
|
||||
}
|
||||
48
Src/auth/Loginbox/popupAgreement.h
Normal file
48
Src/auth/Loginbox/popupAgreement.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPOPUP_AGREEMENT_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPOPUP_AGREEMENT_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPopup.h"
|
||||
|
||||
class LoginProvider;
|
||||
|
||||
class LoginPopupAgreement : public LoginPopup
|
||||
{
|
||||
protected:
|
||||
LoginPopupAgreement(HWND hwnd);
|
||||
~LoginPopupAgreement();
|
||||
|
||||
public:
|
||||
static HWND CreatePopup(HWND hParent, LoginProvider *provider);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
void EndDialog(INT_PTR code);
|
||||
void UpdateMargins();
|
||||
|
||||
BOOL CreateProviderLinks(LPCWSTR pszProvider, LPCWSTR pszTos, LPCWSTR pszPrivacy, INT groupId, HWND hwndInsertAfter);
|
||||
HDWP LayoutProviderLinks(HDWP hdwp, INT groupId, HWND hwndInsertAfter, INT x, INT y, UINT flags, SIZE *size); // pass hdwp = NULL to get ideal size
|
||||
|
||||
|
||||
void OnLinkClicked(HWND hLink);
|
||||
HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
LRESULT OnNotify(UINT controlId, const NMHDR *pnmh);
|
||||
void OnParentNotify(UINT eventId, UINT wParam, LPARAM lParam);
|
||||
BOOL OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut);
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
void OnDestroy();
|
||||
|
||||
protected:
|
||||
LONG marginLinkLeft;
|
||||
LONG marginLinkFirst;
|
||||
LONG marginLinkNext;
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPopupAgreement_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance);
|
||||
};
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPOPUP_AGREEMENT_HEADER
|
||||
253
Src/auth/Loginbox/popupMessage.cpp
Normal file
253
Src/auth/Loginbox/popupMessage.cpp
Normal file
@@ -0,0 +1,253 @@
|
||||
#include "./popupMessage.h"
|
||||
#include "./loginNotifier.h"
|
||||
#include "./common.h"
|
||||
|
||||
#include "../resource.h"
|
||||
#include "../api.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
typedef struct __MESSAGECREATEPARAM
|
||||
{
|
||||
UINT type;
|
||||
LPCWSTR title;
|
||||
LPCWSTR message;
|
||||
LoginPopupMessage::ResultCallback callback;
|
||||
LPARAM param;
|
||||
} MESSAGECREATEPARAM;
|
||||
|
||||
typedef struct __MESSAGEBUTTON
|
||||
{
|
||||
INT id;
|
||||
LPCWSTR pTitle;
|
||||
BOOL fGroup;
|
||||
BOOL fDisabled;
|
||||
BOOL fDefault;
|
||||
} MESSAGEBUTTON;
|
||||
|
||||
const static MESSAGEBUTTON szTypeContinue[] =
|
||||
{
|
||||
{ IDOK, MAKEINTRESOURCE(IDS_BUTTON_CONTINUE), TRUE, FALSE, TRUE, },
|
||||
};
|
||||
|
||||
const static MESSAGEBUTTON szTypeYesNo[] =
|
||||
{
|
||||
{ IDYES, MAKEINTRESOURCE(IDS_BUTTON_YES), TRUE, FALSE, TRUE, },
|
||||
{ IDNO, MAKEINTRESOURCE(IDS_BUTTON_NO), FALSE, FALSE, FALSE, },
|
||||
};
|
||||
|
||||
static HRESULT CALLBACK LoginPopupMessage_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == hwnd) return E_INVALIDARG;
|
||||
|
||||
*instance = new LoginPopupMessage(hwnd);
|
||||
|
||||
if (NULL == instance) return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
LoginPopupMessage::LoginPopupMessage(HWND hwnd)
|
||||
: LoginPopup(hwnd, NLNTYPE_INFORMATION, NULL), callback(NULL), param(0L),
|
||||
buttonsCount(0)
|
||||
{
|
||||
memset(szButtons, 0, sizeof(szButtons));
|
||||
}
|
||||
|
||||
LoginPopupMessage::~LoginPopupMessage()
|
||||
{
|
||||
}
|
||||
|
||||
HWND LoginPopupMessage::CreatePopup(HWND hParent, LPCWSTR pszTitle, LPCWSTR pszMessage, UINT uType, ResultCallback callback, LPARAM param)
|
||||
{
|
||||
switch(typeMask & uType)
|
||||
{
|
||||
case typeContinue:
|
||||
case typeYesNo:
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MESSAGECREATEPARAM createParam;
|
||||
createParam.type = uType;
|
||||
createParam.title = pszTitle;
|
||||
createParam.message = pszMessage;
|
||||
createParam.callback = callback;
|
||||
createParam.param = param;
|
||||
|
||||
return LoginPopup::CreatePopup(MAKEINTRESOURCE(IDD_POPUP_MESSAGE), hParent,
|
||||
(LPARAM)&createParam, LoginPopupMessage_CreateInstance);
|
||||
}
|
||||
|
||||
void LoginPopupMessage::UpdateLayout(BOOL fRedraw)
|
||||
{
|
||||
LoginPopup::UpdateLayout(fRedraw);
|
||||
|
||||
RECT rect;
|
||||
if (FALSE == GetInfoRect(&rect)) return;
|
||||
|
||||
HDWP hdwp = BeginDeferWindowPos(1 + buttonsCount);
|
||||
if (NULL == hdwp) return;
|
||||
|
||||
UINT flags = SWP_NOZORDER | SWP_NOACTIVATE;
|
||||
if (FALSE == fRedraw) flags |= SWP_NOREDRAW;
|
||||
|
||||
HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL != hMessage)
|
||||
{
|
||||
hdwp = DeferWindowPos(hdwp, hMessage, NULL,
|
||||
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, flags);
|
||||
|
||||
if (NULL == hdwp) return;
|
||||
}
|
||||
|
||||
if (NULL != buttonsCount)
|
||||
hdwp = LayoutButtons(hdwp, szButtons, buttonsCount, fRedraw, NULL);
|
||||
|
||||
EndDeferWindowPos(hdwp);
|
||||
}
|
||||
|
||||
|
||||
void LoginPopupMessage::EndDialog(INT_PTR code)
|
||||
{
|
||||
ResultCallback callbackCopy = callback;
|
||||
LPARAM paramCopy = param;
|
||||
|
||||
|
||||
NLPNRESULT result;
|
||||
result.exitCode = code;
|
||||
SendNotification(NLPN_RESULT, (NMHDR*)&result);
|
||||
|
||||
if (NULL != callbackCopy)
|
||||
callbackCopy(hwnd, code, paramCopy);
|
||||
|
||||
LoginPopup::EndDialog(code);
|
||||
}
|
||||
|
||||
static BOOL LoginPopupMessage_CreateButtons(HWND hwnd, const MESSAGEBUTTON *buttonList, UINT *buttonsCount, INT *buttonIdList)
|
||||
{
|
||||
if (NULL == hwnd || NULL == buttonList || NULL == buttonsCount || 0 == *buttonsCount)
|
||||
return FALSE;
|
||||
|
||||
UINT count = *buttonsCount;
|
||||
*buttonsCount = 0;
|
||||
|
||||
WCHAR szBuffer[256] = {0};
|
||||
RECT rect;
|
||||
SetRect(&rect, 50, 15, 0, 0);
|
||||
MapDialogRect(hwnd, &rect);
|
||||
|
||||
LONG width = rect.left;
|
||||
LONG height = rect.top;
|
||||
|
||||
HFONT font = (HFONT)SendMessage(hwnd, WM_GETFONT, 0, 0L);
|
||||
|
||||
for (UINT i = 0; i < count; i++)
|
||||
{
|
||||
LPCWSTR title = buttonList[i].pTitle;
|
||||
if (NULL != title && FALSE != IS_INTRESOURCE(title))
|
||||
{
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)title, szBuffer, ARRAYSIZE(szBuffer));
|
||||
title = szBuffer;
|
||||
}
|
||||
|
||||
UINT style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
|
||||
if (FALSE != buttonList[i].fGroup) style |= WS_GROUP;
|
||||
if (FALSE != buttonList[i].fDisabled) style |= WS_DISABLED;
|
||||
if (FALSE != buttonList[i].fDefault) style |= BS_DEFPUSHBUTTON;
|
||||
|
||||
HWND hButton = CreateWindowEx(WS_EX_NOPARENTNOTIFY, L"Button", title, style,
|
||||
0, 0, width, height, hwnd, (HMENU)(INT_PTR)buttonList[i].id, NULL, 0L);
|
||||
|
||||
if (NULL != hButton)
|
||||
{
|
||||
if (NULL != font)
|
||||
SendMessage(hButton, WM_SETFONT, (WPARAM)font, 0L);
|
||||
|
||||
if (NULL != buttonIdList)
|
||||
buttonIdList[*buttonsCount] = buttonList[i].id;
|
||||
|
||||
(*buttonsCount)++;
|
||||
}
|
||||
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LoginPopupMessage::OnInitDialog(HWND hFocus, LPARAM param)
|
||||
{
|
||||
MESSAGECREATEPARAM *createParam = (MESSAGECREATEPARAM*)param;
|
||||
|
||||
if (NULL != createParam)
|
||||
{
|
||||
callback = createParam->callback;
|
||||
param = createParam->param;
|
||||
|
||||
switch(iconMask & createParam->type)
|
||||
{
|
||||
case iconInfo: popupType = NLNTYPE_INFORMATION; break;
|
||||
case iconWarning: popupType = NLNTYPE_WARNING; break;
|
||||
case iconError: popupType = NLNTYPE_ERROR; break;
|
||||
}
|
||||
SetTitle(popupType, createParam->title);
|
||||
|
||||
switch(typeMask & createParam->type)
|
||||
{
|
||||
case typeContinue:
|
||||
buttonsCount = ARRAYSIZE(szTypeContinue);
|
||||
LoginPopupMessage_CreateButtons(hwnd, szTypeContinue, &buttonsCount, szButtons);
|
||||
break;
|
||||
case typeYesNo:
|
||||
buttonsCount = ARRAYSIZE(szTypeYesNo);
|
||||
LoginPopupMessage_CreateButtons(hwnd, szTypeYesNo, &buttonsCount, szButtons);
|
||||
break;
|
||||
}
|
||||
|
||||
HWND hMessage = GetDlgItem(hwnd, IDC_MESSAGE);
|
||||
if (NULL != hMessage)
|
||||
{
|
||||
if (NULL != createParam->message && FALSE != IS_INTRESOURCE(createParam->message))
|
||||
{
|
||||
WCHAR szBuffer[4096] = {0};
|
||||
WASABI_API_LNGSTRINGW_BUF((INT)(INT_PTR)createParam->message, szBuffer, ARRAYSIZE(szBuffer));
|
||||
SendMessage(hMessage, WM_SETTEXT, 0, (LPARAM)szBuffer);
|
||||
}
|
||||
else
|
||||
SendMessage(hMessage, WM_SETTEXT, 0, (LPARAM)createParam->message);
|
||||
}
|
||||
}
|
||||
return LoginPopup::OnInitDialog(hFocus, param);
|
||||
}
|
||||
|
||||
BOOL LoginPopupMessage::OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut)
|
||||
{
|
||||
if (NULL == clientRect || NULL == rectOut)
|
||||
return FALSE;
|
||||
|
||||
SIZE size;
|
||||
|
||||
LONG maxWidth = clientRect->right - clientRect->left -
|
||||
(clientMargins.right + clientMargins.left) -
|
||||
(infoMargins.right + infoMargins.left);
|
||||
|
||||
if (FALSE == GetTextSize(GetDlgItem(hwnd, IDC_MESSAGE), maxWidth, &size))
|
||||
{
|
||||
size.cx = 0;
|
||||
size.cy = 0;
|
||||
}
|
||||
|
||||
if (FALSE == CalculateWindowRect(size.cx, size.cy, szButtons, buttonsCount, TRUE, rectOut))
|
||||
return FALSE;
|
||||
|
||||
LONG ox = clientRect->left + ((clientRect->right - clientRect->left) - (rectOut->right - rectOut->left))/2;
|
||||
LONG oy = clientRect->top + ((clientRect->bottom - clientRect->top) - (rectOut->bottom - rectOut->top))/2;
|
||||
|
||||
if (ox < clientRect->left) ox = clientRect->left;
|
||||
if (oy < clientRect->top) oy = clientRect->top;
|
||||
|
||||
OffsetRect(rectOut, ox, oy);
|
||||
return TRUE;
|
||||
}
|
||||
52
Src/auth/Loginbox/popupMessage.h
Normal file
52
Src/auth/Loginbox/popupMessage.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPOPUP_MESSAGE_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPOPUP_MESSAGE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPopup.h"
|
||||
|
||||
class LoginPopupMessage : public LoginPopup
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
typeMask = 0x0000FFFF,
|
||||
typeContinue = 0x00000000,
|
||||
typeYesNo = 0x00000001,
|
||||
iconMask = 0xFFFF0000,
|
||||
iconInfo = 0x00000000,
|
||||
iconWarning = 0x00010000,
|
||||
iconError = 0x00020000,
|
||||
} Type;
|
||||
|
||||
typedef void (CALLBACK *ResultCallback)(HWND /*hPopup*/, INT_PTR /*resultCode*/, LPARAM param);
|
||||
|
||||
protected:
|
||||
LoginPopupMessage(HWND hwnd);
|
||||
~LoginPopupMessage();
|
||||
|
||||
public:
|
||||
static HWND CreatePopup(HWND hParent, LPCWSTR pszTitle, LPCWSTR pszMessage, UINT uType, ResultCallback callback, LPARAM param);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
void EndDialog(INT_PTR code);
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
BOOL OnUpdateWindowPos(const RECT* clientRect, RECT *rectOut);
|
||||
|
||||
protected:
|
||||
ResultCallback callback;
|
||||
LPARAM param;
|
||||
INT szButtons[8];
|
||||
UINT buttonsCount;
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPopupMessage_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPOPUP_MESSAGE_HEADER
|
||||
405
Src/auth/Loginbox/popupPasscode.cpp
Normal file
405
Src/auth/Loginbox/popupPasscode.cpp
Normal file
@@ -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);
|
||||
}
|
||||
65
Src/auth/Loginbox/popupPasscode.h
Normal file
65
Src/auth/Loginbox/popupPasscode.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINPOPUP_PASSCODE_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINPOPUP_PASSCODE_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginPopup.h"
|
||||
|
||||
class LoginData;
|
||||
class LoginDataCredentials;
|
||||
|
||||
|
||||
// notifications
|
||||
#define NPPN_FIRST (120)
|
||||
|
||||
typedef struct __NPPNRESULT
|
||||
{
|
||||
NMHDR hdr;
|
||||
INT_PTR exitCode;
|
||||
LoginData *loginData;
|
||||
} NPPNRESULT;
|
||||
|
||||
#define NPPN_RESULT (NPPN_FIRST + 0)
|
||||
|
||||
|
||||
class LoginPopupPasscode : public LoginPopup
|
||||
{
|
||||
protected:
|
||||
LoginPopupPasscode(HWND hwnd);
|
||||
~LoginPopupPasscode();
|
||||
|
||||
public:
|
||||
static HWND CreatePopup(HWND hParent, LoginData *loginData);
|
||||
|
||||
protected:
|
||||
void UpdateLayout(BOOL fRedraw);
|
||||
void EndDialog(INT_PTR code);
|
||||
|
||||
BOOL Validate();
|
||||
|
||||
BOOL OnInitDialog(HWND hFocus, LPARAM param);
|
||||
void OnCommand(UINT commandId, UINT eventType, HWND hControl);
|
||||
LRESULT OnNotify(UINT controlId, const NMHDR *pnmh);
|
||||
HBRUSH OnGetStaticColor(HDC hdc, HWND hControl);
|
||||
|
||||
LRESULT OnEditboxChar(HWND hEdit, UINT ch);
|
||||
LRESULT OnEditboxKey(HWND hEdit, UINT vKey, UINT flags);
|
||||
LRESULT OnEditboxPaste(HWND hEdit, LPCWSTR pszText);
|
||||
|
||||
INT_PTR DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
protected:
|
||||
LoginDataCredentials *loginData;
|
||||
LPWSTR message;
|
||||
UINT messageType;
|
||||
|
||||
private:
|
||||
friend static HRESULT CALLBACK LoginPopupPasscode_CreateInstance(HWND hwnd, LPARAM param, LoginPopup **instance);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINPOPUP_PASSCODE_HEADER
|
||||
112
Src/auth/Loginbox/providerEnumerator.cpp
Normal file
112
Src/auth/Loginbox/providerEnumerator.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "./common.h"
|
||||
#include "./providerEnumerator.h"
|
||||
#include "./loginProvider.h"
|
||||
|
||||
LoginProviderEnumerator::LoginProviderEnumerator()
|
||||
: ref(1), cursor(0), list(NULL), size(0)
|
||||
{
|
||||
}
|
||||
|
||||
LoginProviderEnumerator::~LoginProviderEnumerator()
|
||||
{
|
||||
if (NULL != list)
|
||||
{
|
||||
size_t index = size;
|
||||
while(index--)
|
||||
{
|
||||
LoginProvider *provider = list[index];
|
||||
if (NULL != provider) provider->Release();
|
||||
}
|
||||
|
||||
free(list);
|
||||
}
|
||||
}
|
||||
|
||||
ULONG LoginProviderEnumerator::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginProviderEnumerator::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderEnumerator::CreateInstance(LoginProvider **list, size_t size, LoginProviderEnumerator **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
if (NULL == list) return E_INVALIDARG;
|
||||
|
||||
LoginProviderEnumerator *enumerator = new LoginProviderEnumerator();
|
||||
if(NULL == enumerator)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
if (0 != size)
|
||||
{
|
||||
enumerator->list = (LoginProvider**)calloc(size, sizeof(LoginProvider*));
|
||||
if (NULL == enumerator->list)
|
||||
{
|
||||
enumerator->Release();
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
enumerator->size = size;
|
||||
CopyMemory(enumerator->list, list, size * sizeof(LoginProvider*));
|
||||
}
|
||||
|
||||
*instance = enumerator;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderEnumerator::Next(ULONG listSize, LoginProvider **elementList, ULONG *elementCount)
|
||||
{
|
||||
if (NULL == elementList || 0 == listSize) return E_INVALIDARG;
|
||||
if (cursor >= size)
|
||||
{
|
||||
if (NULL != elementCount) *elementCount = 0;
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
ULONG count = 0;
|
||||
|
||||
for (;cursor < size && count < listSize; cursor++)
|
||||
{
|
||||
LoginProvider *provider = list[cursor];
|
||||
if (NULL != provider)
|
||||
{
|
||||
provider->AddRef();
|
||||
elementList[count] = provider;
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != elementCount) *elementCount = count;
|
||||
|
||||
return (count == listSize) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginProviderEnumerator::Reset(void)
|
||||
{
|
||||
cursor = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderEnumerator::Skip(ULONG elementCount)
|
||||
{
|
||||
cursor += elementCount;
|
||||
if (cursor >= size)
|
||||
{
|
||||
cursor = (size - 1);
|
||||
return S_FALSE;
|
||||
}
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
38
Src/auth/Loginbox/providerEnumerator.h
Normal file
38
Src/auth/Loginbox/providerEnumerator.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PROVIDER_ENUMERATOR_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PROVIDER_ENUMERATOR_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginProvider;
|
||||
|
||||
class LoginProviderEnumerator
|
||||
{
|
||||
|
||||
protected:
|
||||
LoginProviderEnumerator();
|
||||
~LoginProviderEnumerator();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(LoginProvider **list, size_t size, LoginProviderEnumerator **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
HRESULT Next(ULONG listSize, LoginProvider **elementList, ULONG *elementCount);
|
||||
HRESULT Reset(void);
|
||||
HRESULT Skip(ULONG elementCount);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
size_t cursor;
|
||||
size_t size;
|
||||
LoginProvider **list;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PROVIDER_ENUMERATOR_HEADER
|
||||
142
Src/auth/Loginbox/providerLoader.cpp
Normal file
142
Src/auth/Loginbox/providerLoader.cpp
Normal file
@@ -0,0 +1,142 @@
|
||||
#include "./providerLoader.h"
|
||||
#include "./providerEnumerator.h"
|
||||
#include "./xmlInt32Parser.h"
|
||||
|
||||
#include "../api.h"
|
||||
#include "../../xml/obj_xml.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
|
||||
LoginProviderLoader::LoginProviderLoader()
|
||||
{
|
||||
}
|
||||
|
||||
LoginProviderLoader::~LoginProviderLoader()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT LoginProviderLoader::ReadXml(LPCWSTR pszPath, LoginProviderEnumerator **enumerator, INT *prefVisible)
|
||||
{
|
||||
if (NULL == enumerator) return E_POINTER;
|
||||
*enumerator = NULL;
|
||||
|
||||
if (NULL == pszPath || L'\0' == *pszPath)
|
||||
return E_INVALIDARG;
|
||||
|
||||
HANDLE hFile = CreateFile(pszPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
return HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL != WASABI_API_SVC)
|
||||
{
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(obj_xmlGUID);
|
||||
obj_xml *reader = (NULL != sf) ? (obj_xml*)sf->getInterface() : NULL;
|
||||
if (NULL != reader)
|
||||
{
|
||||
if (OBJ_XML_SUCCESS == reader->xmlreader_open())
|
||||
{
|
||||
providerList.clear();
|
||||
parser.SetReader(reader);
|
||||
|
||||
XmlInt32Parser visibleParser;
|
||||
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider", this);
|
||||
if (NULL != prefVisible)
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fvisibleProviders", &visibleParser);
|
||||
|
||||
hr = FeedFile(reader, hFile, 8192);
|
||||
reader->xmlreader_close();
|
||||
|
||||
parser.SetReader(NULL);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = LoginProviderEnumerator::CreateInstance(providerList.begin(), providerList.size(), enumerator);
|
||||
|
||||
if (NULL != prefVisible && FAILED(visibleParser.GetValue(prefVisible)))
|
||||
*prefVisible = 0;
|
||||
|
||||
}
|
||||
else
|
||||
hr = E_FAIL;
|
||||
|
||||
sf->releaseInterface(reader);
|
||||
}
|
||||
else
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
hr = E_UNEXPECTED;
|
||||
|
||||
|
||||
CloseHandle(hFile);
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginProviderLoader::FeedFile(obj_xml *reader, HANDLE hFile, DWORD bufferSize)
|
||||
{
|
||||
if (NULL == reader || INVALID_HANDLE_VALUE == hFile || 0 == bufferSize)
|
||||
return E_INVALIDARG;
|
||||
|
||||
BYTE *buffer = (BYTE*)calloc(bufferSize, sizeof(BYTE));
|
||||
if (NULL == buffer) return E_OUTOFMEMORY;
|
||||
|
||||
HRESULT hr;
|
||||
INT readerCode = OBJ_XML_SUCCESS;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
DWORD read = 0;
|
||||
if (FALSE == ReadFile(hFile, buffer, bufferSize, &read, NULL) || 0 == read)
|
||||
{
|
||||
DWORD errorCode = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(errorCode);
|
||||
|
||||
if (0 == read && OBJ_XML_SUCCESS == readerCode)
|
||||
reader->xmlreader_feed(0, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
readerCode = reader->xmlreader_feed(buffer, read);
|
||||
if (OBJ_XML_SUCCESS != readerCode)
|
||||
{
|
||||
hr = E_FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(buffer);
|
||||
return hr;
|
||||
}
|
||||
|
||||
void LoginProviderLoader::Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
|
||||
{
|
||||
parser.Begin(params);
|
||||
}
|
||||
|
||||
void LoginProviderLoader::Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag)
|
||||
{
|
||||
LoginProvider *provider;
|
||||
if (SUCCEEDED(parser.End(&provider)))
|
||||
{
|
||||
providerList.push_back(provider);
|
||||
}
|
||||
}
|
||||
|
||||
void LoginProviderLoader::Event_XmlError(int linenum, int errcode, const wchar_t *errstr)
|
||||
{
|
||||
parser.End(NULL);
|
||||
}
|
||||
|
||||
#define CBCLASS LoginProviderLoader
|
||||
START_DISPATCH;
|
||||
VCB(ONSTARTELEMENT, Event_XmlStartElement)
|
||||
VCB(ONENDELEMENT, Event_XmlEndElement)
|
||||
VCB(ONERROR, Event_XmlError)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
44
Src/auth/Loginbox/providerLoader.h
Normal file
44
Src/auth/Loginbox/providerLoader.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PROVIDER_LOADER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PROVIDER_LOADER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../xml/ifc_xmlreadercallback.h"
|
||||
#include "../../nu/ptrlist.h"
|
||||
#include "./providerParser.h"
|
||||
|
||||
class obj_xml;
|
||||
class LoginProviderEnumerator;
|
||||
|
||||
class LoginProviderLoader : public ifc_xmlreadercallback
|
||||
{
|
||||
|
||||
public:
|
||||
LoginProviderLoader();
|
||||
~LoginProviderLoader();
|
||||
|
||||
public:
|
||||
HRESULT ReadXml(LPCWSTR pszPath, LoginProviderEnumerator **enumerator, INT *prefVisible);
|
||||
|
||||
private:
|
||||
HRESULT FeedFile(obj_xml *reader, HANDLE hFile, DWORD bufferSize);
|
||||
|
||||
void Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
|
||||
void Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag);
|
||||
void Event_XmlError(int linenum, int errcode, const wchar_t *errstr);
|
||||
|
||||
private:
|
||||
typedef nu::PtrList<LoginProvider> ProviderList;
|
||||
|
||||
private:
|
||||
ProviderList providerList;
|
||||
LoginProviderParser parser;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PROVIDER_LOADER_HEADER
|
||||
136
Src/auth/Loginbox/providerOperation.cpp
Normal file
136
Src/auth/Loginbox/providerOperation.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include "./providerOperation.h"
|
||||
#include "./loginProvider.h"
|
||||
#include "./providerEnumerator.h"
|
||||
|
||||
LoginProviderOperation::LoginProviderOperation(LoginProvider *pSource, LoginProvider *pTarget, UINT uCode)
|
||||
: ref(1), source(pSource), target(pTarget), code(uCode)
|
||||
{
|
||||
if (NULL != source) source->AddRef();
|
||||
if (NULL != target) target->AddRef();
|
||||
}
|
||||
|
||||
LoginProviderOperation::~LoginProviderOperation()
|
||||
{
|
||||
if (NULL != source) source->Release();
|
||||
if (NULL != target) target->Release();
|
||||
}
|
||||
|
||||
HRESULT LoginProviderOperation::CreateDeleteOperation(LoginProvider *pRemove, LoginProviderOperation **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
if (NULL == pRemove)
|
||||
{
|
||||
*instance = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*instance = new LoginProviderOperation(pRemove, NULL, operationDelete);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderOperation::CreateReplaceOperation(LoginProvider *pSource, LoginProvider *pTarget, LoginProviderOperation **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
if (NULL == pSource || NULL == pTarget)
|
||||
{
|
||||
*instance = NULL;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
*instance = new LoginProviderOperation(pSource, pTarget, operationReplace);
|
||||
if (NULL == *instance) return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderOperation::CreateFromUpdate(LoginProvider *active, LoginProviderEnumerator *enumerator, LoginProviderOperation **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
*instance = NULL;
|
||||
|
||||
if (NULL == active || NULL == enumerator)
|
||||
return E_INVALIDARG;
|
||||
|
||||
GUID testId, activeId(GUID_NULL);
|
||||
HRESULT hr = active->GetId(&activeId);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
LoginProvider *test;
|
||||
BOOL providerFound = FALSE;
|
||||
enumerator->Reset();
|
||||
|
||||
BOOL loop = TRUE;
|
||||
while(TRUE == loop && S_OK == enumerator->Next(1, &test, NULL))
|
||||
{
|
||||
if (FAILED(test->GetId(&testId)))
|
||||
{
|
||||
hr = E_FAIL;
|
||||
loop = FALSE;
|
||||
}
|
||||
else if(FALSE != IsEqualGUID(activeId, testId))
|
||||
{
|
||||
providerFound = TRUE;
|
||||
if (S_OK == test->IsIdentical(active))
|
||||
hr = S_FALSE;
|
||||
else
|
||||
hr = CreateReplaceOperation(active, test, instance);
|
||||
loop = FALSE;
|
||||
}
|
||||
|
||||
test->Release();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) && FALSE == providerFound)
|
||||
hr = CreateDeleteOperation(active, instance);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
ULONG LoginProviderOperation::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
ULONG LoginProviderOperation::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
UINT LoginProviderOperation::GetCode()
|
||||
{
|
||||
return code;
|
||||
}
|
||||
HRESULT LoginProviderOperation::GetSource(LoginProvider **provider)
|
||||
{
|
||||
if (NULL == provider) return E_POINTER;
|
||||
*provider = source;
|
||||
|
||||
if (NULL != source)
|
||||
source->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderOperation::GetTarget(LoginProvider **provider)
|
||||
{
|
||||
if (NULL == provider) return E_POINTER;
|
||||
*provider = target;
|
||||
|
||||
if (NULL != target)
|
||||
target->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
47
Src/auth/Loginbox/providerOperation.h
Normal file
47
Src/auth/Loginbox/providerOperation.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PROVIDER_OPERATION_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PROVIDER_OPERATION_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
|
||||
class LoginProvider;
|
||||
class LoginProviderEnumerator;
|
||||
|
||||
class LoginProviderOperation
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
operationDelete = 0,
|
||||
operationReplace = 1,
|
||||
} OperationCode;
|
||||
|
||||
protected:
|
||||
LoginProviderOperation(LoginProvider *pSource, LoginProvider *pTarget, UINT uCode);
|
||||
~LoginProviderOperation();
|
||||
|
||||
public:
|
||||
static HRESULT CreateDeleteOperation(LoginProvider *pRemove, LoginProviderOperation **instance);
|
||||
static HRESULT CreateReplaceOperation(LoginProvider *pSource, LoginProvider *pTarget, LoginProviderOperation **instance);
|
||||
static HRESULT CreateFromUpdate(LoginProvider *active, LoginProviderEnumerator *enumerator, LoginProviderOperation **instance);
|
||||
|
||||
public:
|
||||
ULONG AddRef();
|
||||
ULONG Release();
|
||||
|
||||
UINT GetCode();
|
||||
HRESULT GetSource(LoginProvider **provider);
|
||||
HRESULT GetTarget(LoginProvider **provider);
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
LoginProvider *source;
|
||||
LoginProvider *target;
|
||||
UINT code;
|
||||
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PROVIDER_OPERATION_HEADER
|
||||
194
Src/auth/Loginbox/providerParser.cpp
Normal file
194
Src/auth/Loginbox/providerParser.cpp
Normal file
@@ -0,0 +1,194 @@
|
||||
#include "./providerParser.h"
|
||||
#include "./loginProvider.h"
|
||||
#include "./loginTemplate.h"
|
||||
#include "./loginCommand.h"
|
||||
#include "./common.h"
|
||||
|
||||
//#include "../api.h"
|
||||
#include "../../xml/obj_xml.h"
|
||||
|
||||
|
||||
typedef void (CALLBACK *PROVIDERTAGCALLBACK)(LoginProvider* /*provider*/, LPCWSTR /*value*/);
|
||||
|
||||
typedef struct __PROVIDERTAG
|
||||
{
|
||||
LPCWSTR name;
|
||||
PROVIDERTAGCALLBACK callback;
|
||||
} PROVIDERTAG;
|
||||
|
||||
static void CALLBACK ProviderTag_Name(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetName(value);
|
||||
}
|
||||
|
||||
static void CALLBACK ProviderTag_ImagePath(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetImagePath(value);
|
||||
}
|
||||
|
||||
static void CALLBACK ProviderTag_Description(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetDescription(value);
|
||||
}
|
||||
|
||||
static void CALLBACK ProviderTag_TosLink(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetTosLink(value);
|
||||
}
|
||||
|
||||
static void CALLBACK ProviderTag_PrivacyLink(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetPrivacyLink(value);
|
||||
}
|
||||
|
||||
static void CALLBACK ProviderTag_HelpLink(LoginProvider *provider, LPCWSTR value)
|
||||
{
|
||||
provider->SetHelpLink(value);
|
||||
}
|
||||
|
||||
static const PROVIDERTAG szProviderTags[PROVIDER_TAG_MAX] =
|
||||
{
|
||||
{L"name", ProviderTag_Name},
|
||||
{L"icon", ProviderTag_ImagePath},
|
||||
{L"description", ProviderTag_Description},
|
||||
{L"tos", ProviderTag_TosLink},
|
||||
{L"privacy", ProviderTag_PrivacyLink},
|
||||
{L"help", ProviderTag_HelpLink},
|
||||
};
|
||||
|
||||
LoginProviderParser::LoginProviderParser()
|
||||
: reader(NULL), provider(NULL)
|
||||
{
|
||||
ZeroMemory(hitList, sizeof(hitList));
|
||||
}
|
||||
|
||||
LoginProviderParser::~LoginProviderParser()
|
||||
{
|
||||
if (NULL != reader)
|
||||
reader->Release();
|
||||
|
||||
if (NULL != provider)
|
||||
provider->Release();
|
||||
}
|
||||
|
||||
|
||||
HRESULT LoginProviderParser::SetReader(obj_xml *pReader)
|
||||
{
|
||||
if (NULL != reader)
|
||||
{
|
||||
reader->Release();
|
||||
}
|
||||
|
||||
reader = pReader;
|
||||
if (NULL != reader)
|
||||
reader->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderParser::Begin(ifc_xmlreaderparams *params)
|
||||
{
|
||||
if (NULL != provider)
|
||||
return E_PENDING;
|
||||
|
||||
if (NULL == reader) return E_UNEXPECTED;
|
||||
if (NULL == params) return E_INVALIDARG;
|
||||
|
||||
GUID providerId;
|
||||
LPCWSTR pszId = params->getItemValue(L"id");
|
||||
if (NULL != pszId && RPC_S_OK == UuidFromString((RPC_WSTR)pszId, &providerId))
|
||||
{
|
||||
if (FAILED(LoginProvider::CreateInstance(&providerId, &provider)))
|
||||
provider = NULL;
|
||||
}
|
||||
|
||||
if (NULL == provider)
|
||||
return E_FAIL;
|
||||
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fname", this);
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\ficon", this);
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fdescription", this);
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\ftos", this);
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fprivacy", this);
|
||||
reader->xmlreader_registerCallback(L"loginProviders\fprovider\fhelp", this);
|
||||
ZeroMemory(hitList, sizeof(hitList));
|
||||
|
||||
templateNodeParser.Begin(reader, provider);
|
||||
commandNodeParser.Begin(reader, provider);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginProviderParser::End(LoginProvider **ppProvider)
|
||||
{
|
||||
templateNodeParser.End();
|
||||
commandNodeParser.End();
|
||||
reader->xmlreader_unregisterCallback(this);
|
||||
|
||||
|
||||
|
||||
if (NULL == provider || S_OK != provider->IsValid())
|
||||
{
|
||||
if (NULL != provider)
|
||||
{
|
||||
provider->Release();
|
||||
provider = NULL;
|
||||
}
|
||||
|
||||
if (NULL != ppProvider)
|
||||
*ppProvider = NULL;
|
||||
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (NULL != ppProvider)
|
||||
{
|
||||
*ppProvider = provider;
|
||||
if (NULL != provider)
|
||||
provider->AddRef();
|
||||
}
|
||||
|
||||
provider->Release();
|
||||
provider = NULL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void LoginProviderParser::Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params)
|
||||
{
|
||||
elementString.Clear();
|
||||
}
|
||||
|
||||
void LoginProviderParser::Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag)
|
||||
{
|
||||
for (INT i = 0; i < PROVIDER_TAG_MAX; i++)
|
||||
{
|
||||
if (FALSE == hitList[i] &&
|
||||
CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, szProviderTags[i].name, -1, xmltag, -1))
|
||||
{
|
||||
szProviderTags[i].callback(provider, elementString.Get());
|
||||
hitList[i] = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LoginProviderParser::Event_XmlCharData(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *value)
|
||||
{
|
||||
elementString.Append(value);
|
||||
}
|
||||
|
||||
void LoginProviderParser::Event_XmlError(int linenum, int errcode, const wchar_t *errstr)
|
||||
{
|
||||
elementString.Clear();
|
||||
}
|
||||
|
||||
#define CBCLASS LoginProviderParser
|
||||
START_DISPATCH;
|
||||
VCB(ONSTARTELEMENT, Event_XmlStartElement)
|
||||
VCB(ONENDELEMENT, Event_XmlEndElement)
|
||||
VCB(ONCHARDATA, Event_XmlCharData)
|
||||
VCB(ONERROR, Event_XmlError)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
48
Src/auth/Loginbox/providerParser.h
Normal file
48
Src/auth/Loginbox/providerParser.h
Normal file
@@ -0,0 +1,48 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGIN_PROVIDER_PARSER_HEADER
|
||||
#define NULLSOFT_AUTH_LOGIN_PROVIDER_PARSER_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../../xml/ifc_xmlreadercallback.h"
|
||||
#include "./stringBuilder.h"
|
||||
#include "./templateNodeParser.h"
|
||||
#include "./commandNodeParser.h"
|
||||
|
||||
class obj_xml;
|
||||
class LoginProvider;
|
||||
|
||||
#define PROVIDER_TAG_MAX 6
|
||||
|
||||
class LoginProviderParser : public ifc_xmlreadercallback
|
||||
{
|
||||
|
||||
public:
|
||||
LoginProviderParser();
|
||||
~LoginProviderParser();
|
||||
public:
|
||||
HRESULT SetReader(obj_xml *pReader);
|
||||
HRESULT Begin(ifc_xmlreaderparams *params);
|
||||
HRESULT End(LoginProvider **ppProvider);
|
||||
|
||||
protected:
|
||||
void Event_XmlStartElement(const wchar_t *xmlpath, const wchar_t *xmltag, ifc_xmlreaderparams *params);
|
||||
void Event_XmlEndElement(const wchar_t *xmlpath, const wchar_t *xmltag);
|
||||
void Event_XmlCharData(const wchar_t *xmlpath, const wchar_t *xmltag, const wchar_t *value);
|
||||
void Event_XmlError(int linenum, int errcode, const wchar_t *errstr);
|
||||
|
||||
protected:
|
||||
obj_xml *reader;
|
||||
StringBuilder elementString;
|
||||
LoginProvider *provider;
|
||||
LoginTemplateNodeParser templateNodeParser;
|
||||
LoginCommandNodeParser commandNodeParser;
|
||||
BOOL hitList[PROVIDER_TAG_MAX];
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGIN_PROVIDER_PARSER_HEADER
|
||||
BIN
Src/auth/Loginbox/resources/arrow.png
Normal file
BIN
Src/auth/Loginbox/resources/arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1001 B |
BIN
Src/auth/Loginbox/resources/notifierIcons.png
Normal file
BIN
Src/auth/Loginbox/resources/notifierIcons.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
BIN
Src/auth/Loginbox/resources/popupBorder.png
Normal file
BIN
Src/auth/Loginbox/resources/popupBorder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
BIN
Src/auth/Loginbox/resources/selection.png
Normal file
BIN
Src/auth/Loginbox/resources/selection.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 247 B |
842
Src/auth/Loginbox/resultWebAuth.cpp
Normal file
842
Src/auth/Loginbox/resultWebAuth.cpp
Normal file
@@ -0,0 +1,842 @@
|
||||
#include "./resultWebAuth.h"
|
||||
#include "./common.h"
|
||||
#include "./commandWebAuth.h"
|
||||
#include "./loginData.h"
|
||||
#include "./dataAddress.h"
|
||||
#include "./loginCredentials.h"
|
||||
#include "./loginBox.h"
|
||||
#include "./loginProvider.h"
|
||||
#include "./loginStatus.h"
|
||||
#include "./externalMngr.h"
|
||||
#include "./browserWindow.h"
|
||||
|
||||
#include "../resource.h"
|
||||
#include "../api.h"
|
||||
#include "../api_auth.h"
|
||||
|
||||
#include "../../omBrowser/obj_ombrowser.h"
|
||||
#include "../../omBrowser/ifc_ombrowserwndenum.h"
|
||||
#include "../../omBrowser/ifc_ombrowserwndmngr.h"
|
||||
#include "../../omBrowser/browserUiCommon.h"
|
||||
|
||||
#include "../../winamp/jsapi.h"
|
||||
#include "../../winamp/jsapi_CallbackParameters.h"
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
#define SERVICE_ID 369
|
||||
|
||||
#define DISPTABLE_CLASS LoginResultWebAuth
|
||||
DISPTABLE_BEGIN()
|
||||
DISPENTRY_ADD(DISPID_LOGINCOMPLETE, L"loginComplete", OnLoginComplete)
|
||||
DISPENTRY_ADD(DISPID_GETPAGERECT, L"getPageRect", OnGetPageRect)
|
||||
DISPENTRY_ADD(DISPID_GETBOXRECT, L"getBoxRect", OnGetBoxRect)
|
||||
DISPENTRY_ADD(DISPID_SETSTATUS, L"setStatus", OnSetStatus)
|
||||
DISPENTRY_ADD(DISPID_NAVIGATE, L"navigate", OnNavigate)
|
||||
DISPENTRY_ADD(DISPID_GETSTRING, L"getString", OnGetString)
|
||||
DISPTABLE_END
|
||||
#undef DISPTABLE_CLASS
|
||||
|
||||
LoginResultWebAuth::LoginResultWebAuth(obj_ombrowser *pManager, LPCWSTR pszTargetUrl, LoginData *pInput, Callback fnCallback, void *pUser)
|
||||
: ref(1), browserMngr(pManager), external(NULL), targetUrl(NULL), input(pInput), callback(fnCallback), user(pUser),
|
||||
credentials(NULL), authCode(AUTH_NOT_AUTHORIZED), hView(NULL), completed(NULL),
|
||||
dispId(DISPID_UNKNOWN), connectionVerified(FALSE), readyUrl(NULL)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
|
||||
targetUrl = LoginBox_CopyString(pszTargetUrl);
|
||||
input->AddRef();
|
||||
browserMngr->AddRef();
|
||||
|
||||
if(SUCCEEDED(ExternalManager::CreateInstance(&external)))
|
||||
external->AddDispatch(L"loginBox", this, &dispId);
|
||||
}
|
||||
|
||||
LoginResultWebAuth::~LoginResultWebAuth()
|
||||
{
|
||||
hView = NULL;
|
||||
|
||||
Finish();
|
||||
|
||||
if (NULL != completed)
|
||||
{
|
||||
CloseHandle(completed);
|
||||
}
|
||||
|
||||
LoginBox_FreeString(targetUrl);
|
||||
input->Release();
|
||||
|
||||
if (NULL != credentials)
|
||||
credentials->Release();
|
||||
|
||||
LoginBox_FreeString(readyUrl);
|
||||
|
||||
|
||||
|
||||
DeleteCriticalSection(&lock);
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::InitBrowserManager(obj_ombrowser **browserMngr)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(OBJ_OmBrowser);
|
||||
if (NULL == sf) return E_UNEXPECTED;
|
||||
|
||||
*browserMngr = (obj_ombrowser*)sf->getInterface();
|
||||
if (NULL == browserMngr)
|
||||
hr = E_UNEXPECTED;
|
||||
else
|
||||
{
|
||||
HWND hWinamp = (NULL != WASABI_API_WINAMP) ? WASABI_API_WINAMP->GetMainWindow() : NULL;
|
||||
if (NULL == hWinamp || FAILED((*browserMngr)->Initialize(NULL, hWinamp)))
|
||||
{
|
||||
(*browserMngr)->Release();
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = S_OK;
|
||||
}
|
||||
}
|
||||
|
||||
sf->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::CreateInstance(LPCWSTR targetUrl, LoginData *input, Callback callback, void *user, LoginResultWebAuth **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
if (NULL == targetUrl || NULL == input)
|
||||
return E_INVALIDARG;
|
||||
|
||||
obj_ombrowser *browserMngr;
|
||||
if (FAILED(InitBrowserManager(&browserMngr)))
|
||||
return E_FAIL;
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
LoginResultWebAuth *result = new LoginResultWebAuth(browserMngr, targetUrl, input, callback, user);
|
||||
if (NULL == result)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
if (DISPID_UNKNOWN == result->dispId)
|
||||
hr = E_FAIL;
|
||||
else
|
||||
hr = result->Start();
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
result->Release();
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*instance = result;
|
||||
}
|
||||
}
|
||||
|
||||
browserMngr->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) LoginResultWebAuth::AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) LoginResultWebAuth::Release(void)
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
STDMETHODIMP LoginResultWebAuth::QueryInterface(REFIID riid, PVOID *ppvObject)
|
||||
{
|
||||
if (NULL == ppvObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, IFC_OmService))
|
||||
*ppvObject = static_cast<ifc_omservice*>(this);
|
||||
else if (IsEqualIID(riid, IFC_OmServiceCommand))
|
||||
*ppvObject = static_cast<ifc_omservicecommand*>(this);
|
||||
else if (IsEqualIID(riid, LCUID_WEBAUTH))
|
||||
*ppvObject = static_cast<LoginResultWebAuth*>(this);
|
||||
else if (IsEqualIID(riid, IID_IDispatch))
|
||||
*ppvObject = static_cast<IDispatch*>(this);
|
||||
else if (IsEqualIID(riid, IID_IUnknown))
|
||||
*ppvObject = static_cast<IUnknown*>(reinterpret_cast<LoginResult*>(this));
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *ppvObject)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t LoginResultWebAuth::Wasabi_AddRef()
|
||||
{
|
||||
return AddRef();
|
||||
}
|
||||
|
||||
size_t LoginResultWebAuth::Wasabi_Release()
|
||||
{
|
||||
return Release();
|
||||
}
|
||||
|
||||
int LoginResultWebAuth::Wasabi_QueryInterface(GUID iid, void **object)
|
||||
{
|
||||
return QueryInterface(iid, object);
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::Start()
|
||||
{
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_INITIALIZING));
|
||||
|
||||
HWND hParent = input->GetPage();
|
||||
UINT viewStyle = NBCS_DISABLECONTEXTMENU | NBCS_DIALOGMODE | NBCS_POPUPOWNER |
|
||||
NBCS_DISABLEFULLSCREEN | NBCS_DISABLEHOSTCSS | NBCS_NOTOOLBAR | NBCS_NOSTATUSBAR;
|
||||
|
||||
HRESULT hr = browserMngr->CreateView(this, hParent, NULL, viewStyle, &hView);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
|
||||
if (FALSE == BrowserWindow_Attach(hView, this))
|
||||
{
|
||||
DestroyWindow(hView);
|
||||
hView = NULL;
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetWindowPos(hView, HWND_BOTTOM, 0, 0, 0, 0, SWP_NOACTIVATE);
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::Finish()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL != external)
|
||||
{
|
||||
if (DISPID_UNKNOWN != dispId)
|
||||
{
|
||||
external->DeleteMemberByDispID(dispId);
|
||||
dispId = DISPID_UNKNOWN;
|
||||
}
|
||||
external->Release();
|
||||
external = NULL;
|
||||
}
|
||||
|
||||
// try to destroy windows before browserMngr->Finish() (this will let them to lock less)
|
||||
|
||||
if (NULL != hView)
|
||||
{
|
||||
DestroyWindow(hView);
|
||||
hView = NULL;
|
||||
}
|
||||
|
||||
if (NULL != browserMngr)
|
||||
{
|
||||
ifc_ombrowserwndmngr *windowMngr;
|
||||
if (SUCCEEDED(browserMngr->QueryInterface(IFC_OmBrowserWindowManager, (void**)&windowMngr)))
|
||||
{
|
||||
ifc_ombrowserwndenum *windowEnum;
|
||||
if (SUCCEEDED(windowMngr->Enumerate(NULL, NULL, &windowEnum)))
|
||||
{
|
||||
HWND hBrowser;
|
||||
while(S_OK == windowEnum->Next(1, &hBrowser, NULL))
|
||||
{
|
||||
if (FALSE != DestroyWindow(hBrowser) && hBrowser == hView)
|
||||
hView = NULL;
|
||||
}
|
||||
windowEnum->Release();
|
||||
}
|
||||
windowMngr->Release();
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != browserMngr)
|
||||
{
|
||||
browserMngr->Finish();
|
||||
browserMngr->Release();
|
||||
browserMngr = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
void LoginResultWebAuth::NotifyComplete()
|
||||
{
|
||||
Callback callbackCopy(NULL);
|
||||
HANDLE completedCopy(NULL);
|
||||
|
||||
INT statusId;
|
||||
switch(authCode)
|
||||
{
|
||||
case AUTH_SUCCESS: statusId = IDS_STATUS_SUCCEEDED; break;
|
||||
case AUTH_SECURID: statusId = IDS_STATUS_PASSCODE_REQUIRED; break;
|
||||
case AUTH_ABORT: statusId = IDS_STATUS_ABORTED; break;
|
||||
default: statusId = IDS_STATUS_FAILED; break;
|
||||
}
|
||||
input->SetStatus(MAKEINTRESOURCE(statusId));
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
callbackCopy = callback;
|
||||
if (NULL == completed || FALSE == DuplicateHandle(GetCurrentProcess(), completed,
|
||||
GetCurrentProcess(), &completedCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
completedCopy = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != completedCopy)
|
||||
{
|
||||
SetEvent(completedCopy);
|
||||
CloseHandle(completedCopy);
|
||||
}
|
||||
|
||||
if (NULL != callbackCopy)
|
||||
callbackCopy(this);
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetWaitHandle(HANDLE *handle)
|
||||
{
|
||||
if (NULL == handle)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL == completed)
|
||||
{
|
||||
completed = CreateEvent(NULL, TRUE, (S_OK == IsCompleted()), NULL);
|
||||
if (NULL == completed)
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) &&
|
||||
FALSE == DuplicateHandle(GetCurrentProcess(), completed,
|
||||
GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetUser(void **pUser)
|
||||
{
|
||||
if (NULL == pUser) return E_POINTER;
|
||||
*pUser = user;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::RequestAbort(BOOL fDrop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
authCode = AUTH_ABORT;
|
||||
|
||||
if (NULL == browserMngr)
|
||||
hr = S_FALSE;
|
||||
else
|
||||
{
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_ABORTING));
|
||||
Finish();
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
if (NULL != credentials)
|
||||
{
|
||||
credentials->Release();
|
||||
credentials = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (S_OK == hr)
|
||||
NotifyComplete();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::IsCompleted()
|
||||
{
|
||||
return (NULL == browserMngr) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::IsAborting()
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetLoginData(LoginData **loginData)
|
||||
{
|
||||
if (NULL == loginData) return E_POINTER;
|
||||
*loginData = input;
|
||||
if (NULL != input)
|
||||
input->AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) LoginResultWebAuth::Event_BrowserReady(HWND hBrowser)
|
||||
{
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_CONNECTING));
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) LoginResultWebAuth::Event_DocumentReady(HWND hBrowser)
|
||||
{
|
||||
BOOL validateDocument = TRUE;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
if (NULL != readyUrl)
|
||||
{
|
||||
if (CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, readyUrl, -1, L"loginbox:finish", -1))
|
||||
{
|
||||
if (FAILED(BrowserWindow_QueueApc(hView, 0L)))
|
||||
{
|
||||
Finish();
|
||||
NotifyComplete();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
connectionVerified = FALSE;
|
||||
BrowserControl_Navigate(hBrowser, NAVIGATE_STOP, FALSE);
|
||||
if (FALSE != BrowserControl_Navigate(hBrowser, readyUrl, TRUE))
|
||||
validateDocument = FALSE;
|
||||
|
||||
LoginBox_FreeString(readyUrl);
|
||||
readyUrl = NULL;
|
||||
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (FALSE != validateDocument && FALSE == connectionVerified)
|
||||
{
|
||||
// time to kill it
|
||||
authCode = AUTH_404;
|
||||
Finish();
|
||||
NotifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) LoginResultWebAuth::Event_BrowserClosing(HWND hBrowser)
|
||||
{
|
||||
}
|
||||
|
||||
STDMETHODIMP_(void) LoginResultWebAuth::Event_InvokeApc(HWND hBrowser, LPARAM param)
|
||||
{
|
||||
Finish();
|
||||
NotifyComplete();
|
||||
}
|
||||
unsigned int LoginResultWebAuth::GetId()
|
||||
{
|
||||
return SERVICE_ID;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetName(wchar_t *pszBuffer, int cchBufferMax)
|
||||
{
|
||||
if (NULL == pszBuffer)
|
||||
return E_POINTER;
|
||||
|
||||
WCHAR szName[128] = {0}, szTemplate[256] = {0};
|
||||
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_WEBAUTH_CAPTION_TEMPLATE, szTemplate, ARRAYSIZE(szTemplate));
|
||||
|
||||
LoginProvider *loginProvider;
|
||||
if (SUCCEEDED(input->GetProvider(&loginProvider)) && NULL != loginProvider)
|
||||
{
|
||||
loginProvider->GetName(szName, ARRAYSIZE(szName));
|
||||
loginProvider->Release();
|
||||
}
|
||||
|
||||
return StringCchPrintf(pszBuffer, cchBufferMax, szTemplate, szName);
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetUrl(wchar_t *pszBuffer, int cchBufferMax)
|
||||
{
|
||||
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_CONNECTING));
|
||||
|
||||
LPWSTR cursor;
|
||||
size_t remaining;
|
||||
HRESULT hr = StringCchCopyEx(pszBuffer, cchBufferMax, targetUrl, &cursor, &remaining, STRSAFE_IGNORE_NULLS);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
LoginDataAddress *inputAddress;
|
||||
if (SUCCEEDED(input->QueryInterface(IID_LoginDataAddress, (void**)&inputAddress)))
|
||||
{
|
||||
LPCWSTR pszAddress = inputAddress->GetAddress();
|
||||
if (NULL != pszAddress && L'\0' != *pszAddress)
|
||||
{
|
||||
LPWSTR paramBegin = cursor;
|
||||
while (L'?' != *paramBegin && paramBegin != pszBuffer)
|
||||
paramBegin = CharPrev(pszBuffer, paramBegin);
|
||||
|
||||
WCHAR separator = (L'?' == *paramBegin) ? L'&' : L'?';
|
||||
hr = StringCchPrintfEx(cursor, remaining, &cursor, &remaining, 0, L"%cuserUrl=%s", separator, pszAddress);
|
||||
}
|
||||
inputAddress->Release();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::GetExternal(IDispatch **ppDispatch)
|
||||
{
|
||||
if (NULL == ppDispatch)
|
||||
return E_POINTER;
|
||||
|
||||
*ppDispatch = external;
|
||||
if (NULL != external)
|
||||
external->AddRef();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::QueryState(HWND hBrowser, const GUID *commandGroup, UINT commandId)
|
||||
{
|
||||
if (NULL == commandGroup)
|
||||
return E_NOTIMPL;
|
||||
|
||||
if (IsEqualGUID(*commandGroup, CMDGROUP_NAVIGATION))
|
||||
{
|
||||
switch(commandId)
|
||||
{
|
||||
case NAVCOMMAND_HOME:
|
||||
return CMDSTATE_DISABLED;
|
||||
}
|
||||
}
|
||||
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::Exec(HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg)
|
||||
{
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::DispParamsToCredentials(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, UINT FAR *puArgErr, HRESULT *errorEx, LPWSTR *finishUrl)
|
||||
{
|
||||
if (NULL != finishUrl)
|
||||
*finishUrl = NULL;
|
||||
|
||||
JSAPI_VERIFY_METHOD(wFlags);
|
||||
JSAPI_VERIFY_PARAMCOUNT_OPTIONAL(pdispparams, 5, 6);
|
||||
|
||||
BSTR username;
|
||||
BSTR token;
|
||||
BSTR sessionKey;
|
||||
__time64_t expire;
|
||||
|
||||
JSAPI_GETUNSIGNED_AS_NUMBER(authCode, pdispparams, 1, puArgErr);
|
||||
JSAPI_GETSTRING(token, pdispparams, 2, puArgErr);
|
||||
JSAPI_GETSTRING(sessionKey, pdispparams, 3, puArgErr);
|
||||
JSAPI_GETUNSIGNED_AS_NUMBER(expire, pdispparams, 4, puArgErr);
|
||||
JSAPI_GETSTRING(username, pdispparams, 5, puArgErr);
|
||||
expire += _time64(0);
|
||||
|
||||
if (NULL != finishUrl && pdispparams->cArgs > 5)
|
||||
{
|
||||
VARIANTARG *arg = &pdispparams->rgvarg[pdispparams->cArgs - 6];
|
||||
if (NULL != arg && VT_BSTR == arg->vt)
|
||||
*finishUrl = LoginBox_CopyString(arg->bstrVal);
|
||||
}
|
||||
|
||||
if (NULL != credentials)
|
||||
{
|
||||
credentials->Release();
|
||||
credentials = NULL;
|
||||
}
|
||||
|
||||
if (AUTH_SUCCESS == authCode)
|
||||
{
|
||||
GUID realm;
|
||||
HRESULT hr = input->GetRealm(&realm);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
LPSTR sessionAnsi(NULL), tokenAnsi(NULL);
|
||||
if (FAILED(LoginBox_WideCharToMultiByte(CP_UTF8, 0, sessionKey, -1, NULL, NULL, &sessionAnsi)) ||
|
||||
FAILED(LoginBox_WideCharToMultiByte(CP_UTF8, 0, token, -1, NULL, NULL, &tokenAnsi)))
|
||||
{
|
||||
hr = E_FAIL;
|
||||
}
|
||||
if (SUCCEEDED(hr))
|
||||
hr = LoginCredentials::CreateInstance(&realm, username, sessionAnsi, tokenAnsi, expire, &credentials);
|
||||
|
||||
LoginBox_FreeAnsiString(sessionAnsi);
|
||||
LoginBox_FreeAnsiString(tokenAnsi);
|
||||
}
|
||||
|
||||
if (FAILED(hr))
|
||||
{
|
||||
if (NULL != errorEx)
|
||||
*errorEx = hr;
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnLoginComplete(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_BOOL);
|
||||
|
||||
HRESULT hr, errorEx;
|
||||
BOOL finishLogin = TRUE;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
LPWSTR finishUrl;
|
||||
hr = DispParamsToCredentials(wFlags, pdispparams, pvarResult, puArgErr, &errorEx, &finishUrl);
|
||||
JSAPI_SET_RESULT(pvarResult, boolVal, (SUCCEEDED(hr) && SUCCEEDED(errorEx)) ? VARIANT_TRUE : VARIANT_FALSE);
|
||||
|
||||
if (NULL != finishUrl && L'\0' != *finishUrl)
|
||||
{
|
||||
LoginBox_FreeString(readyUrl);
|
||||
readyUrl = LoginBox_CopyString(L"loginbox:finish");
|
||||
if (NULL != readyUrl)
|
||||
{
|
||||
if (FALSE == hView || FALSE == BrowserControl_Navigate(hView, finishUrl, FALSE))
|
||||
{
|
||||
LoginBox_FreeString(readyUrl);
|
||||
readyUrl = NULL;
|
||||
}
|
||||
else
|
||||
finishLogin = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LoginBox_FreeString(finishUrl);
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (FALSE != finishLogin)
|
||||
{
|
||||
if (FAILED(BrowserWindow_QueueApc(hView, 0L)))
|
||||
{
|
||||
Finish();
|
||||
NotifyComplete();
|
||||
}
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnGetPageRect(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
JSAPI_VERIFY_METHOD(wFlags);
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_DISPATCH);
|
||||
|
||||
RECT rect;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
HWND hPage = input->GetPage();
|
||||
if (NULL == hPage || FALSE == GetWindowRect(hPage, &rect))
|
||||
SetRectEmpty(&rect);
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
JSAPI::CallbackParameters *params = new JSAPI::CallbackParameters;
|
||||
params->AddLong(L"x", rect.left);
|
||||
params->AddLong(L"y", rect.top);
|
||||
params->AddLong(L"cx", rect.right - rect.left);
|
||||
params->AddLong(L"cy", rect.bottom - rect.top);
|
||||
V_DISPATCH(pvarResult) = params;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnGetBoxRect(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
JSAPI_VERIFY_METHOD(wFlags);
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_DISPATCH);
|
||||
|
||||
RECT rect;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
HWND hBox = input->GetLoginbox();
|
||||
if (NULL == hBox || FALSE == GetWindowRect(hBox, &rect))
|
||||
SetRectEmpty(&rect);
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != pvarResult)
|
||||
{
|
||||
JSAPI::CallbackParameters *params = new JSAPI::CallbackParameters;
|
||||
params->AddLong(L"x", rect.left);
|
||||
params->AddLong(L"y", rect.top);
|
||||
params->AddLong(L"cx", rect.right - rect.left);
|
||||
params->AddLong(L"cy", rect.bottom - rect.top);
|
||||
V_DISPATCH(pvarResult) = params;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnSetStatus(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
connectionVerified = TRUE;
|
||||
|
||||
JSAPI_VERIFY_METHOD(wFlags);
|
||||
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1);
|
||||
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_BOOL);
|
||||
|
||||
LPCWSTR pszStatus = NULL;
|
||||
INT paramIndex = pdispparams->cArgs - 1;
|
||||
VARIANTARG *param = &pdispparams->rgvarg[paramIndex];
|
||||
switch(param->vt)
|
||||
{
|
||||
case VT_I4:
|
||||
pszStatus = (MAKEINTRESOURCE(param->lVal));
|
||||
break;
|
||||
case VT_BSTR:
|
||||
pszStatus = param->bstrVal;
|
||||
break;
|
||||
default:
|
||||
if (puArgErr) *puArgErr = paramIndex;
|
||||
return DISP_E_TYPEMISMATCH;
|
||||
}
|
||||
|
||||
HRESULT hr = input->SetStatus(pszStatus);
|
||||
JSAPI_SET_RESULT(pvarResult, boolVal, (SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnNavigate(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
JSAPI_VERIFY_METHOD(wFlags);
|
||||
JSAPI_VERIFY_PARAMCOUNT_OPTIONAL(pdispparams, 1, 3);
|
||||
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_BOOL);
|
||||
|
||||
BSTR targetUrl = JSAPI_PARAM_OPTIONAL(pdispparams, 1, bstrVal, NULL);
|
||||
BSTR callbackUrl = JSAPI_PARAM_OPTIONAL(pdispparams, 2, bstrVal, NULL);
|
||||
BSTR message = JSAPI_PARAM_OPTIONAL(pdispparams, 3, bstrVal, NULL);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL == targetUrl || L'\0' == *targetUrl ||
|
||||
NULL == callbackUrl || L'\0' == *callbackUrl)
|
||||
{
|
||||
hr = E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
LoginBox_FreeString(readyUrl);
|
||||
readyUrl = LoginBox_CopyString(callbackUrl);
|
||||
if (NULL == readyUrl)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
connectionVerified = FALSE;
|
||||
if (NULL == hView || FALSE == BrowserControl_Navigate(hView, targetUrl, FALSE))
|
||||
{
|
||||
LoginBox_FreeString(readyUrl);
|
||||
readyUrl = NULL;
|
||||
hr = E_FAIL;
|
||||
}
|
||||
else
|
||||
hr = S_OK;
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
JSAPI_SET_RESULT(pvarResult, boolVal, (SUCCEEDED(hr) ? VARIANT_TRUE : VARIANT_FALSE));
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWebAuth::OnGetString(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, unsigned int FAR *puArgErr)
|
||||
{
|
||||
if (0 == ((DISPATCH_METHOD |DISPATCH_PROPERTYGET) &wFlags))
|
||||
return DISP_E_MEMBERNOTFOUND;
|
||||
|
||||
JSAPI_VERIFY_PARAMCOUNT(pdispparams, 1);
|
||||
JSAPI_INIT_RESULT(pvarResult, VT_BSTR);
|
||||
|
||||
UINT stringId;
|
||||
JSAPI_GETUNSIGNED_AS_NUMBER(stringId, pdispparams, 1, puArgErr);
|
||||
|
||||
WCHAR szBuffer[4096] = {0};
|
||||
BSTR string = SysAllocString(WASABI_API_LNGSTRINGW_BUF(stringId, szBuffer, ARRAYSIZE(szBuffer)));
|
||||
JSAPI_SET_RESULT(pvarResult, bstrVal, string);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
HRESULT LoginResultWebAuth::GetResult(INT *pAuthCode, LoginCredentials **ppCredentials)
|
||||
{
|
||||
if (S_OK != IsCompleted())
|
||||
return E_PENDING;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL != pAuthCode)
|
||||
*pAuthCode = authCode;
|
||||
|
||||
if (NULL != ppCredentials)
|
||||
{
|
||||
*ppCredentials = credentials;
|
||||
if (NULL != credentials)
|
||||
credentials->AddRef();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
#define CBCLASS LoginResultWebAuth
|
||||
START_MULTIPATCH;
|
||||
START_PATCH(MPIID_OMSVC)
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, ADDREF, Wasabi_AddRef);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, RELEASE, Wasabi_Release);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, QUERYINTERFACE, Wasabi_QueryInterface);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, API_GETID, GetId);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, API_GETNAME, GetName);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, API_GETURL, GetUrl);
|
||||
M_CB(MPIID_OMSVC, ifc_omservice, API_GETEXTERNAL, GetExternal);
|
||||
NEXT_PATCH(MPIID_OMSVCCOMMAND)
|
||||
M_CB(MPIID_OMSVCCOMMAND, ifc_omservicecommand, ADDREF, Wasabi_AddRef);
|
||||
M_CB(MPIID_OMSVCCOMMAND, ifc_omservicecommand, RELEASE, Wasabi_Release);
|
||||
M_CB(MPIID_OMSVCCOMMAND, ifc_omservicecommand, QUERYINTERFACE, Wasabi_QueryInterface);
|
||||
M_CB(MPIID_OMSVCCOMMAND, ifc_omservicecommand, API_QUERYSTATE, QueryState);
|
||||
M_CB(MPIID_OMSVCCOMMAND, ifc_omservicecommand, API_EXEC, Exec);
|
||||
END_PATCH
|
||||
END_MULTIPATCH;
|
||||
#undef CBCLASS
|
||||
129
Src/auth/Loginbox/resultWebAuth.h
Normal file
129
Src/auth/Loginbox/resultWebAuth.h
Normal file
@@ -0,0 +1,129 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINRESULT_WEBAUTH_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINRESULT_WEBAUTH_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginResult.h"
|
||||
#include "./browserEvent.h"
|
||||
#include "../omBrowser/ifc_omservice.h"
|
||||
#include "../omBrowser/ifc_omservicecommand.h"
|
||||
#include "../../nu/dispatchTable.h"
|
||||
|
||||
#include <bfc/multipatch.h>
|
||||
|
||||
class LoginData;
|
||||
class LoginCredentials;
|
||||
class ExternalManager;
|
||||
class obj_ombrowser;
|
||||
|
||||
|
||||
#define MPIID_OMSVC 10
|
||||
#define MPIID_OMSVCCOMMAND 20
|
||||
|
||||
class LoginResultWebAuth : public LoginResult,
|
||||
public IDispatch,
|
||||
public BrowserEvent,
|
||||
public MultiPatch<MPIID_OMSVC, ifc_omservice>,
|
||||
public MultiPatch<MPIID_OMSVCCOMMAND, ifc_omservicecommand>
|
||||
|
||||
{
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
DISPID_LOGINCOMPLETE = 700,
|
||||
DISPID_GETPAGERECT = 701,
|
||||
DISPID_GETBOXRECT = 702,
|
||||
DISPID_SETSTATUS = 703,
|
||||
DISPID_NAVIGATE = 704,
|
||||
DISPID_GETSTRING = 705,
|
||||
} DispatchCodes;
|
||||
|
||||
protected:
|
||||
LoginResultWebAuth(obj_ombrowser *pManager, LPCWSTR pszTargetUrl, LoginData *pInput, Callback fnCallback, void *pUser);
|
||||
~LoginResultWebAuth();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(LPCWSTR targetUrl, LoginData *input, Callback callback, void *user, LoginResultWebAuth **instance);
|
||||
|
||||
public:
|
||||
/* IUnknown */
|
||||
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
|
||||
STDMETHOD_(ULONG, AddRef)(void);
|
||||
STDMETHOD_(ULONG, Release)(void);
|
||||
|
||||
/* IDispatchable */
|
||||
DISPTABLE_INCLUDE();
|
||||
DISPHANDLER_REGISTER(OnLoginComplete);
|
||||
DISPHANDLER_REGISTER(OnGetPageRect);
|
||||
DISPHANDLER_REGISTER(OnGetBoxRect);
|
||||
DISPHANDLER_REGISTER(OnSetStatus);
|
||||
DISPHANDLER_REGISTER(OnNavigate);
|
||||
DISPHANDLER_REGISTER(OnGetString);
|
||||
|
||||
/* LoignResult */
|
||||
HRESULT GetWaitHandle(HANDLE *handle);
|
||||
HRESULT GetUser(void **pUser);
|
||||
HRESULT RequestAbort(BOOL fDrop);
|
||||
HRESULT IsCompleted();
|
||||
HRESULT IsAborting();
|
||||
HRESULT GetLoginData(LoginData **loginData);
|
||||
|
||||
/* BrowserEvent */
|
||||
STDMETHOD_(void, Event_BrowserReady)(HWND hBrowser);
|
||||
STDMETHOD_(void, Event_DocumentReady)(HWND hBrowser);
|
||||
STDMETHOD_(void, Event_BrowserClosing)(HWND hBrowser);
|
||||
STDMETHOD_(void, Event_InvokeApc)(HWND hBrowser, LPARAM param);
|
||||
|
||||
protected:
|
||||
/* Dispatchable */
|
||||
size_t Wasabi_AddRef();
|
||||
size_t Wasabi_Release();
|
||||
int Wasabi_QueryInterface(GUID iid, void **object);
|
||||
|
||||
/* ifc_omservice */
|
||||
unsigned int GetId();
|
||||
HRESULT GetName(wchar_t *pszBuffer, int cchBufferMax);
|
||||
HRESULT GetUrl(wchar_t *pszBuffer, int cchBufferMax);
|
||||
HRESULT GetExternal(IDispatch **ppDispatch);
|
||||
|
||||
/* ifc_omservicecommand */
|
||||
HRESULT QueryState(HWND hBrowser, const GUID *commandGroup, UINT commandId);
|
||||
HRESULT Exec(HWND hBrowser, const GUID *commandGroup, UINT commandId, ULONG_PTR commandArg);
|
||||
|
||||
public:
|
||||
HRESULT GetResult(INT *authCode, LoginCredentials **credentials);
|
||||
|
||||
private:
|
||||
static HRESULT InitBrowserManager(obj_ombrowser **browserMngr);
|
||||
HRESULT Start();
|
||||
HRESULT Finish();
|
||||
void NotifyComplete();
|
||||
HRESULT DispParamsToCredentials(WORD wFlags, DISPPARAMS FAR *pdispparams, VARIANT FAR *pvarResult, UINT FAR *puArgErr, HRESULT *errorEx, LPWSTR *finishUrl);
|
||||
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
LoginData *input;
|
||||
Callback callback;
|
||||
void *user;
|
||||
LoginCredentials *credentials;
|
||||
INT authCode;
|
||||
obj_ombrowser *browserMngr;
|
||||
LPWSTR targetUrl;
|
||||
HWND hView;
|
||||
CRITICAL_SECTION lock;
|
||||
HANDLE completed;
|
||||
ExternalManager *external;
|
||||
DISPID dispId;
|
||||
BOOL connectionVerified;
|
||||
LPWSTR readyUrl;
|
||||
|
||||
|
||||
protected:
|
||||
RECVS_MULTIPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINRESULT_WEBAUTH_HEADER
|
||||
574
Src/auth/Loginbox/resultWinampAuth.cpp
Normal file
574
Src/auth/Loginbox/resultWinampAuth.cpp
Normal file
@@ -0,0 +1,574 @@
|
||||
#include "./resultWinampAuth.h"
|
||||
#include "./common.h"
|
||||
#include "./commandWinampAuth.h"
|
||||
#include "./loginData.h"
|
||||
#include "./dataCredentials.h"
|
||||
#include "./loginCredentials.h"
|
||||
#include "./loginbox.h"
|
||||
|
||||
#include "../resource.h"
|
||||
|
||||
LoginResultWinampAuth::LoginResultWinampAuth(api_auth *auth, LoginDataCredentials *pInput, Callback fnCallback, void *pUser)
|
||||
: ref(1), authApi(auth), input(pInput), callback(fnCallback), user(pUser),
|
||||
thread(NULL), abort(NULL), completed(NULL), credentials(NULL), authCode(AUTH_NOT_AUTHORIZED), statusCookie(0)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
|
||||
authApi->AddRef();
|
||||
input->AddRef();
|
||||
}
|
||||
|
||||
LoginResultWinampAuth::~LoginResultWinampAuth()
|
||||
{
|
||||
if (NULL != abort)
|
||||
CloseHandle(abort);
|
||||
|
||||
if (NULL != completed)
|
||||
CloseHandle(completed);
|
||||
|
||||
if (NULL != thread)
|
||||
CloseHandle(thread);
|
||||
|
||||
authApi->Release();
|
||||
input->Release();
|
||||
|
||||
if (NULL != credentials)
|
||||
credentials->Release();
|
||||
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::CreateInstance(LoginData *input, Callback callback, void *user, LoginResultWinampAuth **instance)
|
||||
{
|
||||
if (NULL == instance) return E_POINTER;
|
||||
*instance = NULL;
|
||||
|
||||
LoginDataCredentials *credentialsInput;
|
||||
if (NULL == input || FAILED(input->QueryInterface(IID_LoginDataCredentials, (void**)&credentialsInput)))
|
||||
return E_INVALIDARG;
|
||||
|
||||
HRESULT hr;
|
||||
api_auth *authApi;
|
||||
|
||||
HWND hLoginbox = credentialsInput->GetLoginbox();
|
||||
if (NULL == hLoginbox || FALSE == LoginBox_GetAuthApi(hLoginbox, &authApi))
|
||||
hr = E_FAIL;
|
||||
else
|
||||
{
|
||||
LoginResultWinampAuth *result = new LoginResultWinampAuth(authApi, credentialsInput, callback, user);
|
||||
if (NULL == result)
|
||||
hr = E_OUTOFMEMORY;
|
||||
else
|
||||
{
|
||||
hr = result->Start();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
result->Release();
|
||||
result = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
*instance = result;
|
||||
}
|
||||
}
|
||||
|
||||
authApi->Release();
|
||||
}
|
||||
credentialsInput->Release();
|
||||
return hr;
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) LoginResultWinampAuth::AddRef(void)
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
STDMETHODIMP_(ULONG) LoginResultWinampAuth::Release(void)
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
STDMETHODIMP LoginResultWinampAuth::QueryInterface(REFIID riid, PVOID *ppvObject)
|
||||
{
|
||||
if (NULL == ppvObject)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(riid, LCUID_WINAMPAUTH))
|
||||
*ppvObject = static_cast<LoginResultWinampAuth*>(this);
|
||||
else if (IsEqualIID(riid, IID_IUnknown))
|
||||
*ppvObject = static_cast<IUnknown*>(this);
|
||||
else
|
||||
{
|
||||
*ppvObject = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *ppvObject)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t LoginResultWinampAuth::Wasabi_AddRef()
|
||||
{
|
||||
return AddRef();
|
||||
}
|
||||
|
||||
size_t LoginResultWinampAuth::Wasabi_Release()
|
||||
{
|
||||
return Release();
|
||||
}
|
||||
|
||||
int LoginResultWinampAuth::Wasabi_QueryInterface(GUID iid, void **object)
|
||||
{
|
||||
return QueryInterface(iid, object);
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::Start()
|
||||
{
|
||||
//HRESULT hr;
|
||||
HANDLE threadCopy = NULL;
|
||||
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_INITIALIZING));
|
||||
EnterCriticalSection(&lock);
|
||||
if (NULL != thread)
|
||||
{
|
||||
//hr = E_PENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
AddRef();
|
||||
thread = CreateThread(NULL, 0, WinampAuth_ThreadProcCallback, this, CREATE_SUSPENDED, NULL);
|
||||
if (NULL == thread)
|
||||
{
|
||||
Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (0 == DuplicateHandle(GetCurrentProcess(), thread, GetCurrentProcess(), &threadCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
ResumeThread(thread); // grr...
|
||||
threadCopy = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
if (NULL != threadCopy)
|
||||
{
|
||||
ResumeThread(threadCopy);
|
||||
CloseHandle(threadCopy);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
DWORD LoginResultWinampAuth::ThreadProc()
|
||||
{
|
||||
Callback callbackCopy(NULL);
|
||||
HANDLE completedCopy(NULL);
|
||||
INT resultCode = AUTH_SUCCESS;
|
||||
LPWSTR username(NULL), password(NULL);
|
||||
|
||||
api_auth::AuthResults authResults;
|
||||
SecureZeroMemory(&authResults, sizeof(authResults));
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
authCode = AUTH_NOT_AUTHORIZED;
|
||||
if (NULL != credentials)
|
||||
{
|
||||
credentials->Release();
|
||||
credentials = NULL;
|
||||
}
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
username = GetUsername(input->GetUsername(), &resultCode);
|
||||
|
||||
if (AUTH_SUCCESS == resultCode)
|
||||
password = GetPassword(input->GetPassword(), &resultCode);
|
||||
|
||||
if (AUTH_SUCCESS == resultCode)
|
||||
{
|
||||
if (NULL == input->GetContext())
|
||||
{
|
||||
resultCode = authApi->Login(username, password, &authResults, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
LPWSTR passcode = GetPasscode(input->GetPasscode(), &resultCode);
|
||||
if (AUTH_SUCCESS == resultCode)
|
||||
{
|
||||
resultCode = authApi->LoginSecurID(username, password, input->GetContext(), passcode, &authResults, this);
|
||||
LoginBox_FreeStringSecure(passcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
authCode = resultCode;
|
||||
switch(authCode)
|
||||
{
|
||||
case AUTH_SUCCESS:
|
||||
{
|
||||
GUID realm;
|
||||
if (FAILED(input->GetRealm(&realm)) ||
|
||||
FAILED(LoginCredentials::CreateInstance(&realm, username, authResults.session_key,
|
||||
authResults.token, authResults.expire, &credentials)))
|
||||
{
|
||||
authCode = AUTH_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AUTH_SECURID:
|
||||
if(FAILED(input->SetContext(authResults.context)))
|
||||
authCode = AUTH_NOT_AUTHORIZED;
|
||||
break;
|
||||
}
|
||||
|
||||
INT statusId;
|
||||
switch(authCode)
|
||||
{
|
||||
case AUTH_SUCCESS: statusId = IDS_STATUS_SUCCEEDED; break;
|
||||
case AUTH_SECURID: statusId = IDS_STATUS_PASSCODE_REQUIRED; break;
|
||||
case AUTH_ABORT: statusId = IDS_STATUS_ABORTED; break;
|
||||
default: statusId = IDS_STATUS_FAILED; break;
|
||||
}
|
||||
input->SetStatus(MAKEINTRESOURCE(statusId));
|
||||
|
||||
CloseHandle(thread);
|
||||
thread = NULL;
|
||||
callbackCopy = callback;
|
||||
|
||||
if (NULL == completed || FALSE == DuplicateHandle(GetCurrentProcess(), completed,
|
||||
GetCurrentProcess(), &completedCopy, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
completedCopy = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
SecureZeroMemory(&authResults, sizeof(authResults));
|
||||
LoginBox_FreeStringSecure(username);
|
||||
LoginBox_FreeStringSecure(password);
|
||||
|
||||
if (NULL != completedCopy)
|
||||
{
|
||||
SetEvent(completedCopy);
|
||||
CloseHandle(completedCopy);
|
||||
}
|
||||
|
||||
if (NULL != callbackCopy)
|
||||
callbackCopy(this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::GetWaitHandle(HANDLE *handle)
|
||||
{
|
||||
if (NULL == handle)
|
||||
return E_POINTER;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL == completed)
|
||||
{
|
||||
completed = CreateEvent(NULL, TRUE, (S_OK == IsCompleted()), NULL);
|
||||
if (NULL == completed)
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr) &&
|
||||
FALSE == DuplicateHandle(GetCurrentProcess(), completed,
|
||||
GetCurrentProcess(), handle, 0, FALSE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
*handle = NULL;
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::GetUser(void **pUser)
|
||||
{
|
||||
if (NULL == pUser) return E_POINTER;
|
||||
EnterCriticalSection(&lock);
|
||||
*pUser = user;
|
||||
LeaveCriticalSection(&lock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::RequestAbort(BOOL fDrop)
|
||||
{
|
||||
HRESULT hr;
|
||||
EnterCriticalSection(&lock);
|
||||
if (NULL == abort)
|
||||
{
|
||||
abort = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (NULL == abort)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != abort && FALSE == SetEvent(abort))
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
hr = HRESULT_FROM_WIN32(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_ABORTING));
|
||||
}
|
||||
|
||||
if (FALSE != fDrop)
|
||||
{
|
||||
callback = NULL;
|
||||
user = NULL;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::IsCompleted()
|
||||
{
|
||||
return (NULL == thread) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::IsAborting()
|
||||
{
|
||||
return IsAbortingEx(0);
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::IsAbortingEx(UINT waitMs)
|
||||
{
|
||||
return (NULL != abort && WAIT_OBJECT_0 == WaitForSingleObjectEx(abort, waitMs, TRUE))?
|
||||
S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::GetLoginData(LoginData **loginData)
|
||||
{
|
||||
if (NULL == loginData) return E_POINTER;
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
*loginData = input;
|
||||
if (NULL != input)
|
||||
input->AddRef();
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT LoginResultWinampAuth::GetResult(INT *pAuthCode, LoginCredentials **ppCredentials)
|
||||
{
|
||||
if (S_OK != IsCompleted())
|
||||
return E_PENDING;
|
||||
|
||||
EnterCriticalSection(&lock);
|
||||
|
||||
if (NULL != pAuthCode)
|
||||
*pAuthCode = authCode;
|
||||
|
||||
if (NULL != ppCredentials)
|
||||
{
|
||||
*ppCredentials = credentials;
|
||||
if (NULL != credentials)
|
||||
credentials->AddRef();
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&lock);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
int LoginResultWinampAuth::Event_AuthConnecting()
|
||||
{
|
||||
if (S_OK == IsAbortingEx(0))
|
||||
return 1;
|
||||
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_CONNECTING));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoginResultWinampAuth::Event_AuthSending()
|
||||
{
|
||||
if (S_OK == IsAbortingEx(0))
|
||||
return 1;
|
||||
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_SENDING));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoginResultWinampAuth::Event_AuthReceiving()
|
||||
{
|
||||
if (S_OK == IsAbortingEx(0))
|
||||
return 1;
|
||||
|
||||
input->SetStatus(MAKEINTRESOURCE(IDS_STATUS_RECEIVING));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LoginResultWinampAuth::Event_AuthIdle()
|
||||
{
|
||||
if (S_OK == IsAbortingEx(50))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LPWSTR LoginResultWinampAuth::GetUsername(LPCWSTR pszInput, INT *authError)
|
||||
{
|
||||
return MakeAuthParam(pszInput, -1, 3, 48, TRUE, TRUE, (0xFFFF & ~C1_CNTRL), AUTH_USERNAME, authError);
|
||||
}
|
||||
|
||||
LPWSTR LoginResultWinampAuth::GetPassword(LPCWSTR pszInput, INT *authError)
|
||||
{
|
||||
return MakeAuthParam(pszInput, -1, 6, 48, TRUE, FALSE, (0xFFFF & ~C1_CNTRL), AUTH_PASSWORD, authError);
|
||||
}
|
||||
|
||||
LPWSTR LoginResultWinampAuth::GetPasscode(LPCWSTR pszInput, INT *authError)
|
||||
{
|
||||
return MakeAuthParam(pszInput, -1, 6, 6, FALSE, FALSE, C1_DIGIT, AUTH_PASSCODE, authError);
|
||||
}
|
||||
|
||||
LPWSTR LoginResultWinampAuth::MakeAuthParam(LPCWSTR pszInput, INT cchInput, INT min, INT max, BOOL removeSpaces, BOOL firstLetter, WORD typeMask, INT errorBase, INT *authError)
|
||||
{
|
||||
if (cchInput < 0 || NULL == pszInput)
|
||||
cchInput = (NULL != pszInput) ? lstrlen(pszInput) : 0;
|
||||
|
||||
if (cchInput < min || (FALSE == removeSpaces && cchInput > max))
|
||||
{
|
||||
if (NULL != authError)
|
||||
*authError = errorBase + ((cchInput < min) ? AUTHPARAM_TOOSHORT : AUTHPARAM_TOOLONG);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WORD *info = (WORD*)calloc(cchInput, sizeof(WORD));
|
||||
if (NULL == info)
|
||||
{
|
||||
if (NULL != authError) *authError = AUTH_UNEXPECTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (FALSE == GetStringTypeW(CT_CTYPE1, pszInput, cchInput, info))
|
||||
{
|
||||
free(info);
|
||||
if (NULL != authError) *authError = AUTH_UNEXPECTED;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
INT error = AUTH_SUCCESS;
|
||||
LPWSTR dest = NULL;
|
||||
|
||||
BOOL firstChecked = FALSE;
|
||||
INT cchSpaces = 0;
|
||||
for (INT i = 0; i < cchInput; i++)
|
||||
{
|
||||
if (FALSE != removeSpaces && 0 != (C1_SPACE & info[i]))
|
||||
cchSpaces++;
|
||||
else if (0 == (typeMask & info[i]))
|
||||
{
|
||||
error = errorBase + AUTHPARAM_BADFORMAT;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FALSE != firstLetter && FALSE == firstChecked)
|
||||
{
|
||||
if (0 == (C1_ALPHA & info[i]))
|
||||
{
|
||||
error = errorBase + AUTHPARAM_BADFORMAT;
|
||||
break;
|
||||
}
|
||||
firstChecked = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (AUTH_SUCCESS == error)
|
||||
{
|
||||
INT cchTotal = cchInput - cchSpaces;
|
||||
if (cchTotal < min)
|
||||
error = errorBase + AUTHPARAM_TOOSHORT;
|
||||
else if (cchTotal > max)
|
||||
error = errorBase + AUTHPARAM_TOOLONG;
|
||||
else
|
||||
{
|
||||
dest = LoginBox_MallocString(cchTotal + 1);
|
||||
if (NULL == dest)
|
||||
error = AUTH_UNEXPECTED;
|
||||
else
|
||||
{
|
||||
if (FALSE != removeSpaces)
|
||||
{
|
||||
LPCWSTR s = pszInput;
|
||||
LPWSTR d = dest;
|
||||
for (INT i = 0; i < cchInput; i++, s++)
|
||||
{
|
||||
if (0 == (C1_SPACE & info[i]))
|
||||
{
|
||||
*d = *s;
|
||||
d++;
|
||||
}
|
||||
}
|
||||
*d = L'\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
CopyMemory(dest, pszInput, (cchInput * sizeof(WCHAR)));
|
||||
dest[cchInput] = L'\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(info);
|
||||
|
||||
if (NULL != authError)
|
||||
*authError = error;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
|
||||
static DWORD WINAPI WinampAuth_ThreadProcCallback(void *param)
|
||||
{
|
||||
LoginResultWinampAuth *result =(LoginResultWinampAuth*)param;
|
||||
if (NULL == result) return 1;
|
||||
|
||||
INT exitCode = result->ThreadProc();
|
||||
result->Release();
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
|
||||
#define CBCLASS LoginResultWinampAuth
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, Wasabi_AddRef)
|
||||
CB(RELEASE, Wasabi_Release)
|
||||
CB(QUERYINTERFACE, Wasabi_QueryInterface)
|
||||
CB(ONCONNECTING, Event_AuthConnecting)
|
||||
CB(ONSENDING, Event_AuthSending)
|
||||
CB(ONRECEIVING, Event_AuthReceiving)
|
||||
CB(ONIDLE, Event_AuthIdle)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
85
Src/auth/Loginbox/resultWinampAuth.h
Normal file
85
Src/auth/Loginbox/resultWinampAuth.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#ifndef NULLSOFT_AUTH_LOGINRESULT_WINAMPAUTH_HEADER
|
||||
#define NULLSOFT_AUTH_LOGINRESULT_WINAMPAUTH_HEADER
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "./loginResult.h"
|
||||
#include "../auth/ifc_authcallback.h"
|
||||
#include "../auth/api_auth.h"
|
||||
|
||||
class LoginData;
|
||||
class LoginCredentials;
|
||||
class LoginDataCredentials;
|
||||
|
||||
class LoginResultWinampAuth : public LoginResult,
|
||||
public ifc_authcallback
|
||||
{
|
||||
protected:
|
||||
LoginResultWinampAuth(api_auth *auth, LoginDataCredentials *pInput, Callback callback, void *user);
|
||||
~LoginResultWinampAuth();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(LoginData *input, Callback callback, void *user, LoginResultWinampAuth **instance);
|
||||
|
||||
public:
|
||||
/* IUnknown */
|
||||
STDMETHOD(QueryInterface)(REFIID riid, PVOID *ppvObject);
|
||||
STDMETHOD_(ULONG, AddRef)(void);
|
||||
STDMETHOD_(ULONG, Release)(void);
|
||||
|
||||
/* LoginResult */
|
||||
HRESULT GetWaitHandle(HANDLE *handle);
|
||||
HRESULT GetUser(void **pUser);
|
||||
HRESULT RequestAbort(BOOL fDrop);
|
||||
HRESULT IsCompleted();
|
||||
HRESULT IsAborting();
|
||||
HRESULT GetLoginData(LoginData **loginData);
|
||||
|
||||
public:
|
||||
HRESULT GetResult(INT *authCode, LoginCredentials **credentials);
|
||||
|
||||
protected:
|
||||
/* Dispatchable */
|
||||
size_t Wasabi_AddRef();
|
||||
size_t Wasabi_Release();
|
||||
int Wasabi_QueryInterface(GUID iid, void **object);
|
||||
|
||||
/*ifc_authcallback*/
|
||||
int Event_AuthConnecting();
|
||||
int Event_AuthSending();
|
||||
int Event_AuthReceiving();
|
||||
int Event_AuthIdle();
|
||||
|
||||
private:
|
||||
HRESULT Start();
|
||||
DWORD ThreadProc();
|
||||
HRESULT IsAbortingEx(UINT waitMs);
|
||||
LPWSTR MakeAuthParam(LPCWSTR pszInput, INT cchInput, INT min, INT max, BOOL removeSpaces, BOOL firstLetter, WORD typeMask, INT errorBase, INT *authError);
|
||||
LPWSTR GetUsername(LPCWSTR pszInput, INT *authError);
|
||||
LPWSTR GetPassword(LPCWSTR pszInput, INT *authError);
|
||||
LPWSTR GetPasscode(LPCWSTR pszInput, INT *authError);
|
||||
|
||||
friend static DWORD WINAPI WinampAuth_ThreadProcCallback(void *param);
|
||||
|
||||
|
||||
protected:
|
||||
ULONG ref;
|
||||
LoginDataCredentials *input;
|
||||
Callback callback;
|
||||
void *user;
|
||||
api_auth *authApi;
|
||||
HANDLE thread;
|
||||
HANDLE abort;
|
||||
HANDLE completed;
|
||||
LoginCredentials *credentials;
|
||||
INT authCode;
|
||||
CRITICAL_SECTION lock;
|
||||
UINT statusCookie;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
#endif //NULLSOFT_AUTH_LOGINRESULT_WINAMPAUTH_HEADER
|
||||
85
Src/auth/Loginbox/stringBuilder.cpp
Normal file
85
Src/auth/Loginbox/stringBuilder.cpp
Normal file
@@ -0,0 +1,85 @@
|
||||
#include "./common.h"
|
||||
#include "./stringBuilder.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
StringBuilder::StringBuilder()
|
||||
: buffer(NULL), cursor(NULL), allocated(0), remaining(0)
|
||||
{
|
||||
}
|
||||
|
||||
StringBuilder::~StringBuilder()
|
||||
{
|
||||
LoginBox_FreeString(buffer);
|
||||
}
|
||||
|
||||
HRESULT StringBuilder::Allocate(size_t newSize)
|
||||
{
|
||||
if (newSize <= allocated)
|
||||
return S_FALSE;
|
||||
|
||||
LPWSTR t = LoginBox_ReAllocString(buffer, newSize);
|
||||
if (NULL == t) return E_OUTOFMEMORY;
|
||||
|
||||
cursor = t + (cursor - buffer);
|
||||
buffer = t;
|
||||
|
||||
remaining += newSize - allocated;
|
||||
allocated = newSize;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void StringBuilder::Clear(void)
|
||||
{
|
||||
if (NULL != buffer)
|
||||
{
|
||||
buffer[0] = L'\0';
|
||||
}
|
||||
cursor = buffer;
|
||||
remaining = allocated;
|
||||
}
|
||||
|
||||
LPCWSTR StringBuilder::Get(void)
|
||||
{
|
||||
return buffer;
|
||||
}
|
||||
|
||||
HRESULT StringBuilder::Set(size_t index, WCHAR value)
|
||||
{
|
||||
if (NULL == buffer)
|
||||
return E_POINTER;
|
||||
|
||||
if (index >= allocated)
|
||||
return E_INVALIDARG;
|
||||
|
||||
buffer[index] = value;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT StringBuilder::Append(LPCWSTR pszString)
|
||||
{
|
||||
HRESULT hr;
|
||||
if (NULL == buffer)
|
||||
{
|
||||
hr = Allocate(1024);
|
||||
if (FAILED(hr)) return hr;
|
||||
}
|
||||
|
||||
size_t cchCursor = remaining;
|
||||
hr = StringCchCopyEx(cursor, cchCursor, pszString, &cursor, &remaining, STRSAFE_IGNORE_NULLS);
|
||||
if (STRSAFE_E_INSUFFICIENT_BUFFER == hr)
|
||||
{
|
||||
size_t offset = cchCursor - remaining;
|
||||
size_t requested = lstrlen(pszString) + (allocated - remaining) + 1;
|
||||
size_t newsize = allocated * 2;
|
||||
while (newsize < requested) newsize = newsize * 2;
|
||||
|
||||
hr = Allocate(newsize);
|
||||
if (FAILED(hr)) return hr;
|
||||
|
||||
hr = StringCchCopyEx(cursor, remaining, pszString + offset, &cursor, &remaining, STRSAFE_IGNORE_NULLS);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user