ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

credui_main.c
Go to the documentation of this file.
00001 /*
00002  * Credentials User Interface
00003  *
00004  * Copyright 2006 Robert Shearman (for CodeWeavers)
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <stdarg.h>
00022 
00023 #include "windef.h"
00024 #include "winbase.h"
00025 #include "winnt.h"
00026 #include "winuser.h"
00027 #include "wincred.h"
00028 #include "commctrl.h"
00029 
00030 #include "credui_resources.h"
00031 
00032 #include "wine/debug.h"
00033 #include "wine/unicode.h"
00034 #include "wine/list.h"
00035 
00036 WINE_DEFAULT_DEBUG_CHANNEL(credui);
00037 
00038 #define TOOLID_INCORRECTPASSWORD    1
00039 #define TOOLID_CAPSLOCKON           2
00040 
00041 #define ID_CAPSLOCKPOP              1
00042 
00043 struct pending_credentials
00044 {
00045     struct list entry;
00046     PWSTR pszTargetName;
00047     PWSTR pszUsername;
00048     PWSTR pszPassword;
00049     BOOL generic;
00050 };
00051 
00052 static HINSTANCE hinstCredUI;
00053 
00054 static struct list pending_credentials_list = LIST_INIT(pending_credentials_list);
00055 
00056 static CRITICAL_SECTION csPendingCredentials;
00057 static CRITICAL_SECTION_DEBUG critsect_debug =
00058 {
00059     0, 0, &csPendingCredentials,
00060     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
00061     0, 0, { (DWORD_PTR)(__FILE__ ": csPendingCredentials") }
00062 };
00063 static CRITICAL_SECTION csPendingCredentials = { &critsect_debug, -1, 0, 0, 0, 0 };
00064 
00065 
00066 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
00067 {
00068     struct pending_credentials *entry, *cursor2;
00069     TRACE("(0x%p, %d, %p)\n",hinstDLL,fdwReason,lpvReserved);
00070 
00071     switch (fdwReason)
00072     {
00073     case DLL_WINE_PREATTACH:
00074         return FALSE;   /* prefer native version */
00075 
00076     case DLL_PROCESS_ATTACH:
00077         DisableThreadLibraryCalls(hinstDLL);
00078         hinstCredUI = hinstDLL;
00079         InitCommonControls();
00080         break;
00081 
00082     case DLL_PROCESS_DETACH:
00083         LIST_FOR_EACH_ENTRY_SAFE(entry, cursor2, &pending_credentials_list, struct pending_credentials, entry)
00084         {
00085             list_remove(&entry->entry);
00086 
00087             HeapFree(GetProcessHeap(), 0, entry->pszTargetName);
00088             HeapFree(GetProcessHeap(), 0, entry->pszUsername);
00089             ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
00090             HeapFree(GetProcessHeap(), 0, entry->pszPassword);
00091             HeapFree(GetProcessHeap(), 0, entry);
00092         }
00093         DeleteCriticalSection(&csPendingCredentials);
00094         break;
00095     }
00096 
00097     return TRUE;
00098 }
00099 
00100 static DWORD save_credentials(PCWSTR pszTargetName, PCWSTR pszUsername,
00101                               PCWSTR pszPassword, BOOL generic)
00102 {
00103     CREDENTIALW cred;
00104 
00105     TRACE("saving servername %s with username %s\n", debugstr_w(pszTargetName), debugstr_w(pszUsername));
00106 
00107     cred.Flags = 0;
00108     cred.Type = generic ? CRED_TYPE_GENERIC : CRED_TYPE_DOMAIN_PASSWORD;
00109     cred.TargetName = (LPWSTR)pszTargetName;
00110     cred.Comment = NULL;
00111     cred.CredentialBlobSize = strlenW(pszPassword) * sizeof(WCHAR);
00112     cred.CredentialBlob = (LPBYTE)pszPassword;
00113     cred.Persist = CRED_PERSIST_ENTERPRISE;
00114     cred.AttributeCount = 0;
00115     cred.Attributes = NULL;
00116     cred.TargetAlias = NULL;
00117     cred.UserName = (LPWSTR)pszUsername;
00118 
00119     if (CredWriteW(&cred, 0))
00120         return ERROR_SUCCESS;
00121     else
00122     {
00123         DWORD ret = GetLastError();
00124         ERR("CredWriteW failed with error %d\n", ret);
00125         return ret;
00126     }
00127 }
00128 
00129 struct cred_dialog_params
00130 {
00131     PCWSTR pszTargetName;
00132     PCWSTR pszMessageText;
00133     PCWSTR pszCaptionText;
00134     HBITMAP hbmBanner;
00135     PWSTR pszUsername;
00136     ULONG ulUsernameMaxChars;
00137     PWSTR pszPassword;
00138     ULONG ulPasswordMaxChars;
00139     BOOL fSave;
00140     DWORD dwFlags;
00141     HWND hwndBalloonTip;
00142     BOOL fBalloonTipActive;
00143 };
00144 
00145 static void CredDialogFillUsernameCombo(HWND hwndUsername, const struct cred_dialog_params *params)
00146 {
00147     DWORD count;
00148     DWORD i;
00149     PCREDENTIALW *credentials;
00150 
00151     if (!CredEnumerateW(NULL, 0, &count, &credentials))
00152         return;
00153 
00154     for (i = 0; i < count; i++)
00155     {
00156         COMBOBOXEXITEMW comboitem;
00157         DWORD j;
00158         BOOL duplicate = FALSE;
00159 
00160         if (params->dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS)
00161         {
00162             if ((credentials[i]->Type != CRED_TYPE_GENERIC) || !credentials[i]->UserName)
00163                 continue;
00164         }
00165         else
00166         {
00167             if (credentials[i]->Type == CRED_TYPE_GENERIC)
00168                 continue;
00169         }
00170 
00171         /* don't add another item with the same name if we've already added it */
00172         for (j = 0; j < i; j++)
00173             if (!strcmpW(credentials[i]->UserName, credentials[j]->UserName))
00174             {
00175                 duplicate = TRUE;
00176                 break;
00177             }
00178 
00179         if (duplicate)
00180             continue;
00181 
00182         comboitem.mask = CBEIF_TEXT;
00183         comboitem.iItem = -1;
00184         comboitem.pszText = credentials[i]->UserName;
00185         SendMessageW(hwndUsername, CBEM_INSERTITEMW, 0, (LPARAM)&comboitem);
00186     }
00187 
00188     CredFree(credentials);
00189 }
00190 
00191 static void CredDialogCreateBalloonTip(HWND hwndDlg, struct cred_dialog_params *params)
00192 {
00193     TTTOOLINFOW toolinfo;
00194     WCHAR wszText[256];
00195 
00196     if (params->hwndBalloonTip)
00197         return;
00198 
00199     params->hwndBalloonTip = CreateWindowExW(WS_EX_TOOLWINDOW, TOOLTIPS_CLASSW,
00200         NULL, WS_POPUP | TTS_NOPREFIX | TTS_BALLOON, CW_USEDEFAULT,
00201         CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hwndDlg, NULL,
00202         hinstCredUI, NULL);
00203     SetWindowPos(params->hwndBalloonTip, HWND_TOPMOST, 0, 0, 0, 0,
00204                  SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
00205 
00206     if (!LoadStringW(hinstCredUI, IDS_INCORRECTPASSWORD, wszText, sizeof(wszText)/sizeof(wszText[0])))
00207     {
00208         ERR("failed to load IDS_INCORRECTPASSWORD\n");
00209         return;
00210     }
00211 
00212     toolinfo.cbSize = sizeof(toolinfo);
00213     toolinfo.uFlags = TTF_TRACK;
00214     toolinfo.hwnd = hwndDlg;
00215     toolinfo.uId = TOOLID_INCORRECTPASSWORD;
00216     memset(&toolinfo.rect, 0, sizeof(toolinfo.rect));
00217     toolinfo.hinst = NULL;
00218     toolinfo.lpszText = wszText;
00219     toolinfo.lParam = 0;
00220     toolinfo.lpReserved = NULL;
00221     SendMessageW(params->hwndBalloonTip, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);
00222 
00223     if (!LoadStringW(hinstCredUI, IDS_CAPSLOCKON, wszText, sizeof(wszText)/sizeof(wszText[0])))
00224     {
00225         ERR("failed to load IDS_CAPSLOCKON\n");
00226         return;
00227     }
00228 
00229     toolinfo.uId = TOOLID_CAPSLOCKON;
00230     SendMessageW(params->hwndBalloonTip, TTM_ADDTOOLW, 0, (LPARAM)&toolinfo);
00231 }
00232 
00233 static void CredDialogShowIncorrectPasswordBalloon(HWND hwndDlg, struct cred_dialog_params *params)
00234 {
00235     TTTOOLINFOW toolinfo;
00236     RECT rcPassword;
00237     INT x;
00238     INT y;
00239     WCHAR wszTitle[256];
00240 
00241     /* user name likely wrong so balloon would be confusing. focus is also
00242      * not set to the password edit box, so more notification would need to be
00243      * handled */
00244     if (!params->pszUsername[0])
00245         return;
00246 
00247     /* don't show two balloon tips at once */
00248     if (params->fBalloonTipActive)
00249         return;
00250 
00251     if (!LoadStringW(hinstCredUI, IDS_INCORRECTPASSWORDTITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
00252     {
00253         ERR("failed to load IDS_INCORRECTPASSWORDTITLE\n");
00254         return;
00255     }
00256 
00257     CredDialogCreateBalloonTip(hwndDlg, params);
00258 
00259     memset(&toolinfo, 0, sizeof(toolinfo));
00260     toolinfo.cbSize = sizeof(toolinfo);
00261     toolinfo.hwnd = hwndDlg;
00262     toolinfo.uId = TOOLID_INCORRECTPASSWORD;
00263 
00264     SendMessageW(params->hwndBalloonTip, TTM_SETTITLEW, TTI_ERROR, (LPARAM)wszTitle);
00265 
00266     GetWindowRect(GetDlgItem(hwndDlg, IDC_PASSWORD), &rcPassword);
00267     /* centered vertically and in the right side of the password edit control */
00268     x = rcPassword.right - 12;
00269     y = (rcPassword.top + rcPassword.bottom) / 2;
00270     SendMessageW(params->hwndBalloonTip, TTM_TRACKPOSITION, 0, MAKELONG(x, y));
00271 
00272     SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&toolinfo);
00273 
00274     params->fBalloonTipActive = TRUE;
00275 }
00276 
00277 static void CredDialogShowCapsLockBalloon(HWND hwndDlg, struct cred_dialog_params *params)
00278 {
00279     TTTOOLINFOW toolinfo;
00280     RECT rcPassword;
00281     INT x;
00282     INT y;
00283     WCHAR wszTitle[256];
00284 
00285     /* don't show two balloon tips at once */
00286     if (params->fBalloonTipActive)
00287         return;
00288 
00289     if (!LoadStringW(hinstCredUI, IDS_CAPSLOCKONTITLE, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])))
00290     {
00291         ERR("failed to load IDS_IDSCAPSLOCKONTITLE\n");
00292         return;
00293     }
00294 
00295     CredDialogCreateBalloonTip(hwndDlg, params);
00296 
00297     memset(&toolinfo, 0, sizeof(toolinfo));
00298     toolinfo.cbSize = sizeof(toolinfo);
00299     toolinfo.hwnd = hwndDlg;
00300     toolinfo.uId = TOOLID_CAPSLOCKON;
00301 
00302     SendMessageW(params->hwndBalloonTip, TTM_SETTITLEW, TTI_WARNING, (LPARAM)wszTitle);
00303 
00304     GetWindowRect(GetDlgItem(hwndDlg, IDC_PASSWORD), &rcPassword);
00305     /* just inside the left side of the password edit control */
00306     x = rcPassword.left + 12;
00307     y = rcPassword.bottom - 3;
00308     SendMessageW(params->hwndBalloonTip, TTM_TRACKPOSITION, 0, MAKELONG(x, y));
00309 
00310     SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, TRUE, (LPARAM)&toolinfo);
00311 
00312     SetTimer(hwndDlg, ID_CAPSLOCKPOP,
00313              SendMessageW(params->hwndBalloonTip, TTM_GETDELAYTIME, TTDT_AUTOPOP, 0),
00314              NULL);
00315 
00316     params->fBalloonTipActive = TRUE;
00317 }
00318 
00319 static void CredDialogHideBalloonTip(HWND hwndDlg, struct cred_dialog_params *params)
00320 {
00321     TTTOOLINFOW toolinfo;
00322 
00323     if (!params->hwndBalloonTip)
00324         return;
00325 
00326     memset(&toolinfo, 0, sizeof(toolinfo));
00327 
00328     toolinfo.cbSize = sizeof(toolinfo);
00329     toolinfo.hwnd = hwndDlg;
00330     toolinfo.uId = 0;
00331     SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&toolinfo);
00332     toolinfo.uId = 1;
00333     SendMessageW(params->hwndBalloonTip, TTM_TRACKACTIVATE, FALSE, (LPARAM)&toolinfo);
00334 
00335     params->fBalloonTipActive = FALSE;
00336 }
00337 
00338 static inline BOOL CredDialogCapsLockOn(void)
00339 {
00340     return GetKeyState(VK_CAPITAL) & 0x1 ? TRUE : FALSE;
00341 }
00342 
00343 static LRESULT CALLBACK CredDialogPasswordSubclassProc(HWND hwnd, UINT uMsg,
00344     WPARAM wParam, LPARAM lParam, UINT_PTR uIdSubclass, DWORD_PTR dwRefData)
00345 {
00346     struct cred_dialog_params *params = (struct cred_dialog_params *)dwRefData;
00347     switch (uMsg)
00348     {
00349     case WM_KEYDOWN:
00350         if (wParam == VK_CAPITAL)
00351         {
00352             HWND hwndDlg = GetParent(hwnd);
00353             if (CredDialogCapsLockOn())
00354                 CredDialogShowCapsLockBalloon(hwndDlg, params);
00355             else
00356                 CredDialogHideBalloonTip(hwndDlg, params);
00357         }
00358         break;
00359     case WM_DESTROY:
00360         RemoveWindowSubclass(hwnd, CredDialogPasswordSubclassProc, uIdSubclass);
00361         break;
00362     }
00363     return DefSubclassProc(hwnd, uMsg, wParam, lParam);
00364 }
00365 
00366 static BOOL CredDialogInit(HWND hwndDlg, struct cred_dialog_params *params)
00367 {
00368     HWND hwndUsername = GetDlgItem(hwndDlg, IDC_USERNAME);
00369     HWND hwndPassword = GetDlgItem(hwndDlg, IDC_PASSWORD);
00370 
00371     SetWindowLongPtrW(hwndDlg, DWLP_USER, (LONG_PTR)params);
00372 
00373     if (params->hbmBanner)
00374         SendMessageW(GetDlgItem(hwndDlg, IDB_BANNER), STM_SETIMAGE,
00375                      IMAGE_BITMAP, (LPARAM)params->hbmBanner);
00376 
00377     if (params->pszMessageText)
00378         SetDlgItemTextW(hwndDlg, IDC_MESSAGE, params->pszMessageText);
00379     else
00380     {
00381         WCHAR format[256];
00382         WCHAR message[256];
00383         LoadStringW(hinstCredUI, IDS_MESSAGEFORMAT, format, sizeof(format)/sizeof(format[0]));
00384         snprintfW(message, sizeof(message)/sizeof(message[0]), format, params->pszTargetName);
00385         SetDlgItemTextW(hwndDlg, IDC_MESSAGE, message);
00386     }
00387     SetWindowTextW(hwndUsername, params->pszUsername);
00388     SetWindowTextW(hwndPassword, params->pszPassword);
00389 
00390     CredDialogFillUsernameCombo(hwndUsername, params);
00391 
00392     if (params->pszUsername[0])
00393     {
00394         /* prevent showing a balloon tip here */
00395         params->fBalloonTipActive = TRUE;
00396         SetFocus(hwndPassword);
00397         params->fBalloonTipActive = FALSE;
00398     }
00399     else
00400         SetFocus(hwndUsername);
00401 
00402     if (params->pszCaptionText)
00403         SetWindowTextW(hwndDlg, params->pszCaptionText);
00404     else
00405     {
00406         WCHAR format[256];
00407         WCHAR title[256];
00408         LoadStringW(hinstCredUI, IDS_TITLEFORMAT, format, sizeof(format)/sizeof(format[0]));
00409         snprintfW(title, sizeof(title)/sizeof(title[0]), format, params->pszTargetName);
00410         SetWindowTextW(hwndDlg, title);
00411     }
00412 
00413     if (params->dwFlags & (CREDUI_FLAGS_DO_NOT_PERSIST|CREDUI_FLAGS_PERSIST))
00414         ShowWindow(GetDlgItem(hwndDlg, IDC_SAVE), SW_HIDE);
00415     else if (params->fSave)
00416         CheckDlgButton(hwndDlg, IDC_SAVE, BST_CHECKED);
00417 
00418     /* setup subclassing for Caps Lock detection */
00419     SetWindowSubclass(hwndPassword, CredDialogPasswordSubclassProc, 1, (DWORD_PTR)params);
00420 
00421     if (params->dwFlags & CREDUI_FLAGS_INCORRECT_PASSWORD)
00422         CredDialogShowIncorrectPasswordBalloon(hwndDlg, params);
00423     else if ((GetFocus() == hwndPassword) && CredDialogCapsLockOn())
00424         CredDialogShowCapsLockBalloon(hwndDlg, params);
00425 
00426     return FALSE;
00427 }
00428 
00429 static void CredDialogCommandOk(HWND hwndDlg, struct cred_dialog_params *params)
00430 {
00431     HWND hwndUsername = GetDlgItem(hwndDlg, IDC_USERNAME);
00432     LPWSTR user;
00433     INT len;
00434     INT len2;
00435 
00436     len = GetWindowTextLengthW(hwndUsername);
00437     user = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR));
00438     GetWindowTextW(hwndUsername, user, len + 1);
00439 
00440     if (!user[0])
00441     {
00442         HeapFree(GetProcessHeap(), 0, user);
00443         return;
00444     }
00445 
00446     if (!strchrW(user, '\\') && !strchrW(user, '@'))
00447     {
00448         ULONG len_target = strlenW(params->pszTargetName);
00449         memcpy(params->pszUsername, params->pszTargetName,
00450                min(len_target, params->ulUsernameMaxChars) * sizeof(WCHAR));
00451         if (len_target + 1 < params->ulUsernameMaxChars)
00452             params->pszUsername[len_target] = '\\';
00453         if (len_target + 2 < params->ulUsernameMaxChars)
00454             params->pszUsername[len_target + 1] = '\0';
00455     }
00456     else if (params->ulUsernameMaxChars > 0)
00457         params->pszUsername[0] = '\0';
00458 
00459     len2 = strlenW(params->pszUsername);
00460     memcpy(params->pszUsername + len2, user, min(len, params->ulUsernameMaxChars - len2) * sizeof(WCHAR));
00461     if (params->ulUsernameMaxChars)
00462         params->pszUsername[len2 + min(len, params->ulUsernameMaxChars - len2 - 1)] = '\0';
00463 
00464     HeapFree(GetProcessHeap(), 0, user);
00465 
00466     GetDlgItemTextW(hwndDlg, IDC_PASSWORD, params->pszPassword,
00467                     params->ulPasswordMaxChars);
00468 
00469     params->fSave = IsDlgButtonChecked(hwndDlg, IDC_SAVE) == BST_CHECKED;
00470 
00471     EndDialog(hwndDlg, IDOK);
00472 }
00473 
00474 static INT_PTR CALLBACK CredDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
00475                                        LPARAM lParam)
00476 {
00477     switch (uMsg)
00478     {
00479         case WM_INITDIALOG:
00480         {
00481             struct cred_dialog_params *params = (struct cred_dialog_params *)lParam;
00482 
00483             return CredDialogInit(hwndDlg, params);
00484         }
00485         case WM_COMMAND:
00486             switch (wParam)
00487             {
00488                 case MAKELONG(IDOK, BN_CLICKED):
00489                 {
00490                     struct cred_dialog_params *params =
00491                         (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00492                     CredDialogCommandOk(hwndDlg, params);
00493                     return TRUE;
00494                 }
00495                 case MAKELONG(IDCANCEL, BN_CLICKED):
00496                     EndDialog(hwndDlg, IDCANCEL);
00497                     return TRUE;
00498                 case MAKELONG(IDC_PASSWORD, EN_SETFOCUS):
00499                     if (CredDialogCapsLockOn())
00500                     {
00501                         struct cred_dialog_params *params =
00502                             (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00503                         CredDialogShowCapsLockBalloon(hwndDlg, params);
00504                     }
00505                     /* don't allow another window to steal focus while the
00506                      * user is typing their password */
00507                     LockSetForegroundWindow(LSFW_LOCK);
00508                     return TRUE;
00509                 case MAKELONG(IDC_PASSWORD, EN_KILLFOCUS):
00510                 {
00511                     struct cred_dialog_params *params =
00512                         (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00513                     /* the user is no longer typing their password, so allow
00514                      * other windows to become foreground ones */
00515                     LockSetForegroundWindow(LSFW_UNLOCK);
00516                     CredDialogHideBalloonTip(hwndDlg, params);
00517                     return TRUE;
00518                 }
00519                 case MAKELONG(IDC_PASSWORD, EN_CHANGE):
00520                 {
00521                     struct cred_dialog_params *params =
00522                         (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00523                     CredDialogHideBalloonTip(hwndDlg, params);
00524                     return TRUE;
00525                 }
00526             }
00527             return FALSE;
00528         case WM_TIMER:
00529             if (wParam == ID_CAPSLOCKPOP)
00530             {
00531                 struct cred_dialog_params *params =
00532                     (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00533                 CredDialogHideBalloonTip(hwndDlg, params);
00534                 return TRUE;
00535             }
00536             return FALSE;
00537         case WM_DESTROY:
00538         {
00539             struct cred_dialog_params *params =
00540                 (struct cred_dialog_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
00541             if (params->hwndBalloonTip) DestroyWindow(params->hwndBalloonTip);
00542             return TRUE;
00543         }
00544         default:
00545             return FALSE;
00546     }
00547 }
00548 
00549 /******************************************************************************
00550  *           CredUIPromptForCredentialsW [CREDUI.@]
00551  */
00552 DWORD WINAPI CredUIPromptForCredentialsW(PCREDUI_INFOW pUIInfo,
00553                                          PCWSTR pszTargetName,
00554                                          PCtxtHandle Reserved,
00555                                          DWORD dwAuthError,
00556                                          PWSTR pszUsername,
00557                                          ULONG ulUsernameMaxChars,
00558                                          PWSTR pszPassword,
00559                                          ULONG ulPasswordMaxChars, PBOOL pfSave,
00560                                          DWORD dwFlags)
00561 {
00562     INT_PTR ret;
00563     struct cred_dialog_params params;
00564     DWORD result = ERROR_SUCCESS;
00565 
00566     TRACE("(%p, %s, %p, %d, %s, %d, %p, %d, %p, 0x%08x)\n", pUIInfo,
00567           debugstr_w(pszTargetName), Reserved, dwAuthError, debugstr_w(pszUsername),
00568           ulUsernameMaxChars, pszPassword, ulPasswordMaxChars, pfSave, dwFlags);
00569 
00570     if ((dwFlags & (CREDUI_FLAGS_ALWAYS_SHOW_UI|CREDUI_FLAGS_GENERIC_CREDENTIALS)) == CREDUI_FLAGS_ALWAYS_SHOW_UI)
00571         return ERROR_INVALID_FLAGS;
00572 
00573     if (!pszTargetName)
00574         return ERROR_INVALID_PARAMETER;
00575 
00576     if ((dwFlags & CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX) && !pfSave)
00577         return ERROR_INVALID_PARAMETER;
00578 
00579     params.pszTargetName = pszTargetName;
00580     if (pUIInfo)
00581     {
00582         params.pszMessageText = pUIInfo->pszMessageText;
00583         params.pszCaptionText = pUIInfo->pszCaptionText;
00584         params.hbmBanner  = pUIInfo->hbmBanner;
00585     }
00586     else
00587     {
00588         params.pszMessageText = NULL;
00589         params.pszCaptionText = NULL;
00590         params.hbmBanner = NULL;
00591     }
00592     params.pszUsername = pszUsername;
00593     params.ulUsernameMaxChars = ulUsernameMaxChars;
00594     params.pszPassword = pszPassword;
00595     params.ulPasswordMaxChars = ulPasswordMaxChars;
00596     params.fSave = pfSave ? *pfSave : FALSE;
00597     params.dwFlags = dwFlags;
00598     params.hwndBalloonTip = NULL;
00599     params.fBalloonTipActive = FALSE;
00600 
00601     ret = DialogBoxParamW(hinstCredUI, MAKEINTRESOURCEW(IDD_CREDDIALOG),
00602                           pUIInfo ? pUIInfo->hwndParent : NULL,
00603                           CredDialogProc, (LPARAM)&params);
00604     if (ret <= 0)
00605         return GetLastError();
00606 
00607     if (ret == IDCANCEL)
00608     {
00609         TRACE("dialog cancelled\n");
00610         return ERROR_CANCELLED;
00611     }
00612 
00613     if (pfSave)
00614         *pfSave = params.fSave;
00615 
00616     if (params.fSave)
00617     {
00618         if (dwFlags & CREDUI_FLAGS_EXPECT_CONFIRMATION)
00619         {
00620             BOOL found = FALSE;
00621             struct pending_credentials *entry;
00622             int len;
00623 
00624             EnterCriticalSection(&csPendingCredentials);
00625 
00626             /* find existing pending credentials for the same target and overwrite */
00627             /* FIXME: is this correct? */
00628             LIST_FOR_EACH_ENTRY(entry, &pending_credentials_list, struct pending_credentials, entry)
00629                 if (!strcmpW(pszTargetName, entry->pszTargetName))
00630                 {
00631                     found = TRUE;
00632                     HeapFree(GetProcessHeap(), 0, entry->pszUsername);
00633                     ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
00634                     HeapFree(GetProcessHeap(), 0, entry->pszPassword);
00635                 }
00636 
00637             if (!found)
00638             {
00639                 entry = HeapAlloc(GetProcessHeap(), 0, sizeof(*entry));
00640                 len = strlenW(pszTargetName);
00641                 entry->pszTargetName = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
00642                 memcpy(entry->pszTargetName, pszTargetName, (len + 1)*sizeof(WCHAR));
00643                 list_add_tail(&pending_credentials_list, &entry->entry);
00644             }
00645 
00646             len = strlenW(params.pszUsername);
00647             entry->pszUsername = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
00648             memcpy(entry->pszUsername, params.pszUsername, (len + 1)*sizeof(WCHAR));
00649             len = strlenW(params.pszPassword);
00650             entry->pszPassword = HeapAlloc(GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR));
00651             memcpy(entry->pszPassword, params.pszPassword, (len + 1)*sizeof(WCHAR));
00652             entry->generic = dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS ? TRUE : FALSE;
00653 
00654             LeaveCriticalSection(&csPendingCredentials);
00655         }
00656         else
00657             result = save_credentials(pszTargetName, pszUsername, pszPassword,
00658                                       dwFlags & CREDUI_FLAGS_GENERIC_CREDENTIALS ? TRUE : FALSE);
00659     }
00660 
00661     return result;
00662 }
00663 
00664 /******************************************************************************
00665  *           CredUIConfirmCredentialsW [CREDUI.@]
00666  */
00667 DWORD WINAPI CredUIConfirmCredentialsW(PCWSTR pszTargetName, BOOL bConfirm)
00668 {
00669     struct pending_credentials *entry;
00670     DWORD result = ERROR_NOT_FOUND;
00671 
00672     TRACE("(%s, %s)\n", debugstr_w(pszTargetName), bConfirm ? "TRUE" : "FALSE");
00673 
00674     if (!pszTargetName)
00675         return ERROR_INVALID_PARAMETER;
00676 
00677     EnterCriticalSection(&csPendingCredentials);
00678 
00679     LIST_FOR_EACH_ENTRY(entry, &pending_credentials_list, struct pending_credentials, entry)
00680     {
00681         if (!strcmpW(pszTargetName, entry->pszTargetName))
00682         {
00683             if (bConfirm)
00684                 result = save_credentials(entry->pszTargetName, entry->pszUsername,
00685                                           entry->pszPassword, entry->generic);
00686             else
00687                 result = ERROR_SUCCESS;
00688 
00689             list_remove(&entry->entry);
00690 
00691             HeapFree(GetProcessHeap(), 0, entry->pszTargetName);
00692             HeapFree(GetProcessHeap(), 0, entry->pszUsername);
00693             ZeroMemory(entry->pszPassword, (strlenW(entry->pszPassword) + 1) * sizeof(WCHAR));
00694             HeapFree(GetProcessHeap(), 0, entry->pszPassword);
00695             HeapFree(GetProcessHeap(), 0, entry);
00696 
00697             break;
00698         }
00699     }
00700 
00701     LeaveCriticalSection(&csPendingCredentials);
00702 
00703     return result;
00704 }
00705 
00706 /******************************************************************************
00707  *           CredUIParseUserNameW [CREDUI.@]
00708  */
00709 DWORD WINAPI CredUIParseUserNameW(PCWSTR pszUserName, PWSTR pszUser,
00710                                   ULONG ulMaxUserChars, PWSTR pszDomain,
00711                                   ULONG ulMaxDomainChars)
00712 {
00713     PWSTR p;
00714 
00715     TRACE("(%s, %p, %d, %p, %d)\n", debugstr_w(pszUserName), pszUser,
00716           ulMaxUserChars, pszDomain, ulMaxDomainChars);
00717 
00718     if (!pszUserName || !pszUser || !ulMaxUserChars || !pszDomain ||
00719         !ulMaxDomainChars)
00720         return ERROR_INVALID_PARAMETER;
00721 
00722     /* FIXME: handle marshaled credentials */
00723 
00724     p = strchrW(pszUserName, '\\');
00725     if (p)
00726     {
00727         if (p - pszUserName > ulMaxDomainChars - 1)
00728             return ERROR_INSUFFICIENT_BUFFER;
00729         if (strlenW(p + 1) > ulMaxUserChars - 1)
00730             return ERROR_INSUFFICIENT_BUFFER;
00731         strcpyW(pszUser, p + 1);
00732         memcpy(pszDomain, pszUserName, (p - pszUserName)*sizeof(WCHAR));
00733         pszDomain[p - pszUserName] = '\0';
00734 
00735         return ERROR_SUCCESS;
00736     }
00737 
00738     p = strrchrW(pszUserName, '@');
00739     if (p)
00740     {
00741         if (p + 1 - pszUserName > ulMaxUserChars - 1)
00742             return ERROR_INSUFFICIENT_BUFFER;
00743         if (strlenW(p + 1) > ulMaxDomainChars - 1)
00744             return ERROR_INSUFFICIENT_BUFFER;
00745         strcpyW(pszDomain, p + 1);
00746         memcpy(pszUser, pszUserName, (p - pszUserName)*sizeof(WCHAR));
00747         pszUser[p - pszUserName] = '\0';
00748 
00749         return ERROR_SUCCESS;
00750     }
00751 
00752     if (strlenW(pszUserName) > ulMaxUserChars - 1)
00753         return ERROR_INSUFFICIENT_BUFFER;
00754     strcpyW(pszUser, pszUserName);
00755     pszDomain[0] = '\0';
00756 
00757     return ERROR_SUCCESS;
00758 }
00759 
00760 /******************************************************************************
00761  *           CredUIStoreSSOCredA [CREDUI.@]
00762  */
00763 DWORD WINAPI CredUIStoreSSOCredA(PCSTR pszRealm, PCSTR pszUsername,
00764                                  PCSTR pszPassword, BOOL bPersist)
00765 {
00766     FIXME("(%s, %s, %p, %d)\n", debugstr_a(pszRealm), debugstr_a(pszUsername),
00767           pszPassword, bPersist);
00768     return ERROR_SUCCESS;
00769 }
00770 
00771 /******************************************************************************
00772  *           CredUIStoreSSOCredW [CREDUI.@]
00773  */
00774 DWORD WINAPI CredUIStoreSSOCredW(PCWSTR pszRealm, PCWSTR pszUsername,
00775                                  PCWSTR pszPassword, BOOL bPersist)
00776 {
00777     FIXME("(%s, %s, %p, %d)\n", debugstr_w(pszRealm), debugstr_w(pszUsername),
00778           pszPassword, bPersist);
00779     return ERROR_SUCCESS;
00780 }
00781 
00782 /******************************************************************************
00783  *           CredUIReadSSOCredA [CREDUI.@]
00784  */
00785 DWORD WINAPI CredUIReadSSOCredA(PCSTR pszRealm, PSTR *ppszUsername)
00786 {
00787     FIXME("(%s, %p)\n", debugstr_a(pszRealm), ppszUsername);
00788     if (ppszUsername)
00789         *ppszUsername = NULL;
00790     return ERROR_NOT_FOUND;
00791 }
00792 
00793 /******************************************************************************
00794  *           CredUIReadSSOCredW [CREDUI.@]
00795  */
00796 DWORD WINAPI CredUIReadSSOCredW(PCWSTR pszRealm, PWSTR *ppszUsername)
00797 {
00798     FIXME("(%s, %p)\n", debugstr_w(pszRealm), ppszUsername);
00799     if (ppszUsername)
00800         *ppszUsername = NULL;
00801     return ERROR_NOT_FOUND;
00802 }

Generated on Sat May 26 2012 04:21:45 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.