Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencredui_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)¶ms); 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
1.7.6.1
|