vkd3d: Disable printf format checks.
[wine.git] / dlls / wininet / dialogs.c
blobbd9b877d5d692ab7f9431530bd98723a417f0310
1 /*
2 * Wininet
4 * Copyright 2003 Mike McCormack for CodeWeavers Inc.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "ws2tcpip.h"
23 #include <stdarg.h>
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winuser.h"
28 #include "winreg.h"
29 #include "wininet.h"
30 #include "winnetwk.h"
31 #include "wine/debug.h"
32 #include "winerror.h"
33 #define NO_SHLWAPI_STREAM
34 #include "shlwapi.h"
35 #include "cryptuiapi.h"
37 #include "internet.h"
38 #include "resource.h"
40 #define MAX_STRING_LEN 1024
42 WINE_DEFAULT_DEBUG_CHANNEL(wininet);
44 struct WININET_ErrorDlgParams
46 http_request_t *req;
47 HWND hWnd;
48 DWORD dwError;
49 DWORD dwFlags;
50 LPVOID* lppvData;
53 /***********************************************************************
54 * WININET_GetAuthRealm
56 * Determine the name of the (basic) Authentication realm
58 static BOOL WININET_GetAuthRealm( HINTERNET hRequest, LPWSTR szBuf, DWORD sz, BOOL proxy )
60 LPWSTR p, q;
61 DWORD index, query;
63 if (proxy)
64 query = HTTP_QUERY_PROXY_AUTHENTICATE;
65 else
66 query = HTTP_QUERY_WWW_AUTHENTICATE;
68 /* extract the Realm from the response and show it */
69 index = 0;
70 if( !HttpQueryInfoW( hRequest, query, szBuf, &sz, &index) )
71 return FALSE;
74 * FIXME: maybe we should check that we're
75 * dealing with 'Basic' Authentication
77 p = wcschr( szBuf, ' ' );
78 if( !p || wcsncmp( p+1, L"realm=", lstrlenW(L"realm=") ) )
80 ERR("response wrong? (%s)\n", debugstr_w(szBuf));
81 return FALSE;
84 /* remove quotes */
85 p += 7;
86 if( *p == '"' )
88 p++;
89 q = wcsrchr( p, '"' );
90 if( q )
91 *q = 0;
93 lstrcpyW( szBuf, p );
95 return TRUE;
98 /* These two are not defined in the public headers */
99 extern DWORD WINAPI WNetCachePassword(LPSTR,WORD,LPSTR,WORD,BYTE,WORD);
100 extern DWORD WINAPI WNetGetCachedPassword(LPSTR,WORD,LPSTR,LPWORD,BYTE);
102 /***********************************************************************
103 * WININET_GetSetPassword
105 static BOOL WININET_GetSetPassword( HWND hdlg, LPCWSTR szServer,
106 LPCWSTR szRealm, BOOL bSet )
108 WCHAR szResource[0x80], szUserPass[0x40];
109 LPWSTR p;
110 HWND hUserItem, hPassItem;
111 DWORD r, dwMagic = 19;
112 UINT r_len, u_len;
113 WORD sz;
115 hUserItem = GetDlgItem( hdlg, IDC_USERNAME );
116 hPassItem = GetDlgItem( hdlg, IDC_PASSWORD );
118 /* now try fetch the username and password */
119 lstrcpyW( szResource, szServer);
120 lstrcatW( szResource, L"/");
121 lstrcatW( szResource, szRealm);
124 * WNetCachePassword is only concerned with the length
125 * of the data stored (which we tell it) and it does
126 * not use strlen() internally so we can add WCHAR data
127 * instead of ASCII data and get it back the same way.
129 if( bSet )
131 szUserPass[0] = 0;
132 GetWindowTextW( hUserItem, szUserPass, ARRAY_SIZE( szUserPass ) - 1 );
133 lstrcatW(szUserPass, L":");
134 u_len = lstrlenW( szUserPass );
135 GetWindowTextW( hPassItem, szUserPass+u_len, ARRAY_SIZE( szUserPass ) - u_len );
137 r_len = (lstrlenW( szResource ) + 1)*sizeof(WCHAR);
138 u_len = (lstrlenW( szUserPass ) + 1)*sizeof(WCHAR);
139 r = WNetCachePassword( (CHAR*)szResource, r_len,
140 (CHAR*)szUserPass, u_len, dwMagic, 0 );
142 return ( r == WN_SUCCESS );
145 sz = sizeof szUserPass;
146 r_len = (lstrlenW( szResource ) + 1)*sizeof(WCHAR);
147 r = WNetGetCachedPassword( (CHAR*)szResource, r_len,
148 (CHAR*)szUserPass, &sz, dwMagic );
149 if( r != WN_SUCCESS )
150 return FALSE;
152 p = wcschr( szUserPass, ':' );
153 if( p )
155 struct WININET_ErrorDlgParams *params;
156 HWND hwnd;
158 params = (struct WININET_ErrorDlgParams*)
159 GetWindowLongPtrW( hdlg, GWLP_USERDATA );
161 *p = 0;
162 SetWindowTextW( hUserItem, szUserPass );
164 if (!params->req->clear_auth)
166 SetWindowTextW( hPassItem, p+1 );
168 hwnd = GetDlgItem( hdlg, IDC_SAVEPASSWORD );
169 if (hwnd)
170 SendMessageW(hwnd, BM_SETCHECK, BST_CHECKED, 0);
172 else
173 WININET_GetSetPassword( hdlg, szServer, szRealm, TRUE );
176 return TRUE;
179 /***********************************************************************
180 * WININET_SetAuthorization
182 static BOOL WININET_SetAuthorization( http_request_t *request, LPWSTR username,
183 LPWSTR password, BOOL proxy )
185 http_session_t *session = request->session;
186 LPWSTR p, q;
188 p = wcsdup(username);
189 if( !p )
190 return FALSE;
192 q = wcsdup(password);
193 if( !q )
195 free(p);
196 return FALSE;
199 if (proxy)
201 appinfo_t *hIC = session->appInfo;
203 free(hIC->proxyUsername);
204 hIC->proxyUsername = p;
206 free(hIC->proxyPassword);
207 hIC->proxyPassword = q;
209 else
211 free(session->userName);
212 session->userName = p;
214 free(session->password);
215 session->password = q;
218 return TRUE;
221 /***********************************************************************
222 * WININET_ProxyPasswordDialog
224 static INT_PTR WINAPI WININET_ProxyPasswordDialog(
225 HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
227 HWND hitem;
228 struct WININET_ErrorDlgParams *params;
229 WCHAR szRealm[0x80];
231 if( uMsg == WM_INITDIALOG )
233 TRACE("WM_INITDIALOG (%08Ix)\n", lParam);
235 /* save the parameter list */
236 params = (struct WININET_ErrorDlgParams*) lParam;
237 SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam );
239 /* extract the Realm from the proxy response and show it */
240 if( WININET_GetAuthRealm( params->req->hdr.hInternet,
241 szRealm, ARRAY_SIZE( szRealm ), TRUE ) )
243 hitem = GetDlgItem( hdlg, IDC_REALM );
244 SetWindowTextW( hitem, szRealm );
247 hitem = GetDlgItem( hdlg, IDC_PROXY );
248 SetWindowTextW( hitem, params->req->session->appInfo->proxy );
250 WININET_GetSetPassword( hdlg, params->req->session->appInfo->proxy, szRealm, FALSE );
252 return TRUE;
255 params = (struct WININET_ErrorDlgParams*)
256 GetWindowLongPtrW( hdlg, GWLP_USERDATA );
258 switch( uMsg )
260 case WM_COMMAND:
261 if( wParam == IDOK )
263 WCHAR username[0x20], password[0x20];
265 username[0] = 0;
266 hitem = GetDlgItem( hdlg, IDC_USERNAME );
267 if( hitem )
268 GetWindowTextW( hitem, username, ARRAY_SIZE( username ));
270 password[0] = 0;
271 hitem = GetDlgItem( hdlg, IDC_PASSWORD );
272 if( hitem )
273 GetWindowTextW( hitem, password, ARRAY_SIZE( password ));
275 hitem = GetDlgItem( hdlg, IDC_SAVEPASSWORD );
276 if( hitem &&
277 SendMessageW( hitem, BM_GETSTATE, 0, 0 ) &&
278 WININET_GetAuthRealm( params->req->hdr.hInternet,
279 szRealm, ARRAY_SIZE( szRealm ), TRUE) )
280 WININET_GetSetPassword( hdlg, params->req->session->appInfo->proxy, szRealm, TRUE );
281 WININET_SetAuthorization( params->req, username, password, TRUE );
283 params->req->clear_auth = TRUE;
285 EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
286 return TRUE;
288 if( wParam == IDCANCEL )
290 EndDialog( hdlg, 0 );
291 return TRUE;
293 break;
295 return FALSE;
298 /***********************************************************************
299 * WININET_PasswordDialog
301 static INT_PTR WINAPI WININET_PasswordDialog(
302 HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
304 HWND hitem;
305 struct WININET_ErrorDlgParams *params;
306 WCHAR szRealm[0x80];
308 if( uMsg == WM_INITDIALOG )
310 TRACE("WM_INITDIALOG (%08Ix)\n", lParam);
312 /* save the parameter list */
313 params = (struct WININET_ErrorDlgParams*) lParam;
314 SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam );
316 /* extract the Realm from the response and show it */
317 if( WININET_GetAuthRealm( params->req->hdr.hInternet,
318 szRealm, ARRAY_SIZE( szRealm ), FALSE ) )
320 hitem = GetDlgItem( hdlg, IDC_REALM );
321 SetWindowTextW( hitem, szRealm );
324 hitem = GetDlgItem( hdlg, IDC_SERVER );
325 SetWindowTextW( hitem, params->req->session->hostName );
327 WININET_GetSetPassword( hdlg, params->req->session->hostName, szRealm, FALSE );
329 return TRUE;
332 params = (struct WININET_ErrorDlgParams*)
333 GetWindowLongPtrW( hdlg, GWLP_USERDATA );
335 switch( uMsg )
337 case WM_COMMAND:
338 if( wParam == IDOK )
340 WCHAR username[0x20], password[0x20];
342 username[0] = 0;
343 hitem = GetDlgItem( hdlg, IDC_USERNAME );
344 if( hitem )
345 GetWindowTextW( hitem, username, ARRAY_SIZE( username ));
347 password[0] = 0;
348 hitem = GetDlgItem( hdlg, IDC_PASSWORD );
349 if( hitem )
350 GetWindowTextW( hitem, password, ARRAY_SIZE( password ));
352 hitem = GetDlgItem( hdlg, IDC_SAVEPASSWORD );
353 if( hitem &&
354 SendMessageW( hitem, BM_GETSTATE, 0, 0 ) &&
355 WININET_GetAuthRealm( params->req->hdr.hInternet,
356 szRealm, ARRAY_SIZE( szRealm ), FALSE ))
358 WININET_GetSetPassword( hdlg, params->req->session->hostName, szRealm, TRUE );
360 WININET_SetAuthorization( params->req, username, password, FALSE );
361 params->req->clear_auth = TRUE;
363 EndDialog( hdlg, ERROR_INTERNET_FORCE_RETRY );
364 return TRUE;
366 if( wParam == IDCANCEL )
368 EndDialog( hdlg, 0 );
369 return TRUE;
371 break;
373 return FALSE;
376 /***********************************************************************
377 * WININET_InvalidCertificateDialog
379 static INT_PTR WINAPI WININET_InvalidCertificateDialog(
380 HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
382 struct WININET_ErrorDlgParams *params;
383 HWND hitem;
384 WCHAR buf[1024];
386 if( uMsg == WM_INITDIALOG )
388 TRACE("WM_INITDIALOG (%08Ix)\n", lParam);
390 /* save the parameter list */
391 params = (struct WININET_ErrorDlgParams*) lParam;
392 SetWindowLongPtrW( hdlg, GWLP_USERDATA, lParam );
394 switch( params->dwError )
396 case ERROR_INTERNET_INVALID_CA:
397 LoadStringW( WININET_hModule, IDS_CERT_CA_INVALID, buf, 1024 );
398 break;
399 case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
400 LoadStringW( WININET_hModule, IDS_CERT_DATE_INVALID, buf, 1024 );
401 break;
402 case ERROR_INTERNET_SEC_CERT_CN_INVALID:
403 LoadStringW( WININET_hModule, IDS_CERT_CN_INVALID, buf, 1024 );
404 break;
405 case ERROR_INTERNET_SEC_CERT_ERRORS:
406 /* FIXME: We should fetch information about the
407 * certificate here and show all the relevant errors.
409 LoadStringW( WININET_hModule, IDS_CERT_ERRORS, buf, 1024 );
410 break;
411 default:
412 FIXME( "No message for error %ld\n", params->dwError );
413 buf[0] = '\0';
416 hitem = GetDlgItem( hdlg, IDC_CERT_ERROR );
417 SetWindowTextW( hitem, buf );
419 return TRUE;
422 params = (struct WININET_ErrorDlgParams*)
423 GetWindowLongPtrW( hdlg, GWLP_USERDATA );
425 switch( uMsg )
427 case WM_COMMAND:
428 if( wParam == IDOK )
430 if( params->dwFlags & FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS )
432 http_request_t *req = params->req;
433 DWORD flags, size = sizeof(flags);
435 InternetQueryOptionW( req->hdr.hInternet, INTERNET_OPTION_SECURITY_FLAGS, &flags, &size );
436 switch( params->dwError )
438 case ERROR_INTERNET_INVALID_CA:
439 flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
440 break;
441 case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
442 flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
443 break;
444 case ERROR_INTERNET_SEC_CERT_CN_INVALID:
445 flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
446 break;
447 case ERROR_INTERNET_SEC_CERT_REV_FAILED:
448 flags |= SECURITY_FLAG_IGNORE_REVOCATION;
449 break;
450 case ERROR_INTERNET_SEC_CERT_ERRORS:
451 if(flags & _SECURITY_FLAG_CERT_REV_FAILED)
452 flags |= SECURITY_FLAG_IGNORE_REVOCATION;
453 if(flags & _SECURITY_FLAG_CERT_INVALID_CA)
454 flags |= SECURITY_FLAG_IGNORE_UNKNOWN_CA;
455 if(flags & _SECURITY_FLAG_CERT_INVALID_CN)
456 flags |= SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
457 if(flags & _SECURITY_FLAG_CERT_INVALID_DATE)
458 flags |= SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
459 break;
461 /* FIXME: Use helper function */
462 flags |= SECURITY_FLAG_SECURE;
463 req->security_flags |= flags;
464 if(is_valid_netconn(req->netconn))
465 req->netconn->security_flags |= flags;
468 EndDialog( hdlg, ERROR_SUCCESS );
469 return TRUE;
471 if( wParam == IDCANCEL )
473 TRACE("Pressed cancel.\n");
475 EndDialog( hdlg, ERROR_CANCELLED );
476 return TRUE;
478 break;
481 return FALSE;
484 /***********************************************************************
485 * InternetErrorDlg
487 DWORD WINAPI InternetErrorDlg(HWND hWnd, HINTERNET hRequest,
488 DWORD dwError, DWORD dwFlags, LPVOID* lppvData)
490 struct WININET_ErrorDlgParams params;
491 http_request_t *req = NULL;
492 DWORD res = ERROR_SUCCESS;
494 TRACE("%p %p %ld %08lx %p\n", hWnd, hRequest, dwError, dwFlags, lppvData);
496 if( !hWnd && !(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI) )
497 return ERROR_INVALID_HANDLE;
499 if(hRequest) {
500 req = (http_request_t*)get_handle_object(hRequest);
501 if(!req)
502 return ERROR_INVALID_HANDLE;
503 if(req->hdr.htype != WH_HHTTPREQ)
504 return ERROR_SUCCESS; /* Yes, that was tested */
507 params.req = req;
508 params.hWnd = hWnd;
509 params.dwError = dwError;
510 params.dwFlags = dwFlags;
511 params.lppvData = lppvData;
513 switch( dwError )
515 case ERROR_SUCCESS:
516 case ERROR_INTERNET_INCORRECT_PASSWORD: {
517 if( !dwError && !(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS ) )
518 break;
519 if(!req)
520 return ERROR_INVALID_PARAMETER;
522 switch(req->status_code) {
523 case HTTP_STATUS_PROXY_AUTH_REQ:
524 res = DialogBoxParamW( WININET_hModule, MAKEINTRESOURCEW( IDD_PROXYDLG ),
525 hWnd, WININET_ProxyPasswordDialog, (LPARAM) &params );
526 break;
527 case HTTP_STATUS_DENIED:
528 res = DialogBoxParamW( WININET_hModule, MAKEINTRESOURCEW( IDD_AUTHDLG ),
529 hWnd, WININET_PasswordDialog, (LPARAM) &params );
530 break;
531 case HTTP_STATUS_OK:
532 req->clear_auth = FALSE;
533 break;
534 default:
535 WARN("unhandled status %lu\n", req->status_code);
537 break;
540 case ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED:
541 if(!req)
542 return ERROR_INVALID_PARAMETER;
543 /* fall through */
544 case ERROR_INTERNET_SEC_CERT_ERRORS:
545 case ERROR_INTERNET_SEC_CERT_CN_INVALID:
546 case ERROR_INTERNET_SEC_CERT_DATE_INVALID:
547 case ERROR_INTERNET_INVALID_CA:
548 case ERROR_INTERNET_SEC_CERT_REV_FAILED:
549 case ERROR_INTERNET_SEC_CERT_WEAK_SIGNATURE:
550 if( dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI ) {
551 res = ERROR_CANCELLED;
552 break;
555 if( dwFlags & ~FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS )
556 FIXME("%08lx contains unsupported flags.\n", dwFlags);
558 res = DialogBoxParamW( WININET_hModule, MAKEINTRESOURCEW( IDD_INVCERTDLG ),
559 hWnd, WININET_InvalidCertificateDialog, (LPARAM) &params );
560 break;
562 case ERROR_HTTP_COOKIE_NEEDS_CONFIRMATION:
563 if(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI) {
564 res = ERROR_HTTP_COOKIE_DECLINED;
565 break;
567 FIXME("Need to display dialog for error %ld\n", dwError);
568 res = ERROR_CANCELLED;
569 break;
571 case ERROR_INTERNET_INSERT_CDROM:
572 if(!req)
573 return ERROR_INVALID_PARAMETER;
574 /* fall through */
575 case ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION:
576 case ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT:
577 case ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT:
578 case ERROR_INTERNET_MIXED_SECURITY:
579 case ERROR_INTERNET_HTTPS_HTTP_SUBMIT_REDIR:
580 if(!(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI))
581 FIXME("Need to display dialog for error %ld\n", dwError);
582 res = ERROR_CANCELLED;
583 break;
585 case ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR:
586 case ERROR_INTERNET_CHG_POST_IS_NON_SECURE:
587 if(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI) {
588 res = ERROR_SUCCESS;
589 break;
591 FIXME("Need to display dialog for error %ld\n", dwError);
592 res = ERROR_CANCELLED;
593 break;
595 case ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR:
596 case ERROR_INTERNET_POST_IS_NON_SECURE:
597 if (!(dwFlags & FLAGS_ERROR_UI_FLAGS_NO_UI))
598 FIXME("Need to display dialog for error %ld\n", dwError);
599 res = ERROR_SUCCESS;
600 break;
602 default:
603 if(!(dwFlags & FLAGS_ERROR_UI_FILTER_FOR_ERRORS))
604 res = ERROR_CANCELLED;
605 break;
608 if(req)
609 WININET_Release(&req->hdr);
610 return res;
613 /***********************************************************************
614 * InternetShowSecurityInfoByURLA (@)
616 BOOL WINAPI InternetShowSecurityInfoByURLA(LPCSTR url, HWND window)
618 FIXME("stub: %s %p\n", url, window);
619 return FALSE;
622 /***********************************************************************
623 * InternetShowSecurityInfoByURLW (@)
625 BOOL WINAPI InternetShowSecurityInfoByURLW(LPCWSTR url, HWND window)
627 FIXME("stub: %s %p\n", debugstr_w(url), window);
628 return FALSE;
631 /***********************************************************************
632 * ParseX509EncodedCertificateForListBoxEntry (@)
634 DWORD WINAPI ParseX509EncodedCertificateForListBoxEntry(LPBYTE cert, DWORD len, LPSTR szlistbox, LPDWORD listbox)
636 FIXME("stub: %p %ld %s %p\n", cert, len, debugstr_a(szlistbox), listbox);
637 return ERROR_CALL_NOT_IMPLEMENTED;
640 /***********************************************************************
641 * ShowX509EncodedCertificate (@)
643 DWORD WINAPI ShowX509EncodedCertificate(HWND parent, LPBYTE cert, DWORD len)
645 PCCERT_CONTEXT certContext = CertCreateCertificateContext(X509_ASN_ENCODING,
646 cert, len);
647 DWORD ret;
649 if (certContext)
651 CRYPTUI_VIEWCERTIFICATE_STRUCTW view;
653 memset(&view, 0, sizeof(view));
654 view.hwndParent = parent;
655 view.pCertContext = certContext;
656 if (CryptUIDlgViewCertificateW(&view, NULL))
657 ret = ERROR_SUCCESS;
658 else
659 ret = GetLastError();
660 CertFreeCertificateContext(certContext);
662 else
663 ret = GetLastError();
664 return ret;