Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2162 lines
71 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. ierrdlg.cxx
  5. Abstract:
  6. Contains immplimentation of generic Windows Dialog
  7. Manipulation Code. This Code will support several
  8. basic operations for putting up dialog UI.
  9. Contents:
  10. LaunchDlg
  11. LaunchAuthPlugInDlg
  12. MapWininetErrorToDlgId
  13. (AuthDialogProc)
  14. (OkCancelDialogProc)
  15. (CertPickDialogProc)
  16. Author:
  17. Arthur L Bierer (arthurbi) 04-Apr-1996
  18. Revision History:
  19. 04-Apr-1996 arthurbi
  20. Created
  21. --*/
  22. #include <wininetp.h>
  23. #include "ierrui.hxx"
  24. #include "iehelpid.h"
  25. #include <persist.h>
  26. #ifdef UNIX
  27. #include <unixui.h>
  28. #endif /* UNIX */
  29. #include <wincred.h>
  30. #include <ntverp.h>
  31. // NOTE- This is not a path delmiter. It is used
  32. // to separate NT DOMAIN\USERNAME fields.
  33. #define DOMAIN_DELIMITER '\\'
  34. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  35. //
  36. // private prototypes
  37. //
  38. INT_PTR
  39. CALLBACK
  40. AuthDialogProc(
  41. HWND hwnd,
  42. UINT msg,
  43. WPARAM wparam,
  44. LPARAM lparam
  45. );
  46. INT_PTR
  47. CALLBACK
  48. OkCancelDialogProc(
  49. HWND hwnd,
  50. UINT msg,
  51. WPARAM wparam,
  52. LPARAM lparam
  53. );
  54. INT_PTR
  55. CALLBACK
  56. InsertCDDialogProc(
  57. HWND hwnd,
  58. UINT msg,
  59. WPARAM wparam,
  60. LPARAM lparam
  61. );
  62. VOID
  63. UpdateGlobalSecuritySettings(
  64. IN DWORD dwCtlId,
  65. IN DWORD dwFlags
  66. );
  67. //
  68. // public functions
  69. //
  70. DWORD
  71. LaunchAuthPlugInDlg(
  72. HTTP_REQUEST_HANDLE_OBJECT *pRequest,
  73. AUTHCTX * pAuthCtx,
  74. HWND hWnd,
  75. DWORD dwError,
  76. DWORD dwFlags,
  77. InvalidPassType *pipAuthUIInfo
  78. )
  79. /*++
  80. Routine Description:
  81. Creates and Launches a Security Plug-In supported Dialog.
  82. The PlugIn will register a callback function that can be called
  83. by WININET to put up a custom authentication Dialog.
  84. The PlugIn is expected to make a "DialogBox" call and return
  85. its results using WININET error code conventions.
  86. Arguments:
  87. lppvContext - pointer to context pointer
  88. hWnd - Parent Window handle to show the dialog from.
  89. dwError - Error code that caused this authentication to come up,
  90. should always be ERROR_INTERNET_PASSWORD_INVALID.
  91. dwFlags - A special flags assoicated with this authentication.
  92. pPwdCacheEntry - A Password cache entry structure.
  93. pipAuthUIInfo - Username/Password structure to return the result.
  94. Return Value:
  95. DWORD
  96. ERROR_SUCCESS - Success.
  97. ERROR_CANCELLED - User clicked "Cancel" or "No" in the dialog.
  98. ERROR_BAD_FORMAT - We faulted while trying to calldown to the plugin.
  99. --*/
  100. {
  101. DEBUG_ENTER((DBG_INET,
  102. Dword,
  103. "LaunchAuthPlugInDlg",
  104. "%#x, %#x, %d (%s), %#x, %#x",
  105. pAuthCtx->_pvContext,
  106. hWnd,
  107. dwError,
  108. InternetMapError(dwError),
  109. dwFlags,
  110. pAuthCtx->_pPWC
  111. ));
  112. DWORD error = ERROR_SUCCESS;
  113. //
  114. // If this Authentication Scheme Handles Its Own UI, then we need
  115. // to Defer to Its Own Dialog Code.
  116. //
  117. if (pAuthCtx->GetFlags() & PLUGIN_AUTH_FLAGS_CAN_HANDLE_UI)
  118. {
  119. // Digest context handles its own ui.
  120. if (pAuthCtx->GetSchemeType() == AUTHCTX::SCHEME_DIGEST)
  121. {
  122. error = ((DIGEST_CTX*) pAuthCtx)->PromptForCreds(hWnd);
  123. }
  124. else
  125. {
  126. __try
  127. {
  128. // The package handles it's own UI, possibly generating an auth
  129. // header.
  130. // Since AuthenticateUserUI calls into GetSecAuthMsg which
  131. // calls into InitializeSecurityPackage we use the same method
  132. // embbeded in PLUG_CTX methods of checking the return code of the
  133. // SSPI call against SEC_E_OK to know if the auth context can transit
  134. // to AUTHSTATE_CHALLENGE.
  135. SECURITY_STATUS ssResult;
  136. ssResult = SEC_E_INTERNAL_ERROR;
  137. error = AuthenticateUserUI
  138. (&pAuthCtx->_pvContext, hWnd, dwError, dwFlags, pipAuthUIInfo,
  139. pAuthCtx->GetScheme(), ((PLUG_CTX*)pAuthCtx)->GetUrl(), &ssResult);
  140. // Transit to the correct auth state.
  141. if (ssResult == SEC_E_OK || ssResult == SEC_I_CONTINUE_NEEDED)
  142. {
  143. if (pAuthCtx->GetSchemeType() == AUTHCTX::SCHEME_NEGOTIATE)
  144. ((PLUG_CTX*)pAuthCtx)->ResolveProtocol();
  145. // Kerberos + SEC_E_OK or SEC_I_CONTINUE_NEEDED transits to challenge.
  146. // Negotiate does not transit to challenge.
  147. // Any other protocol + SEC_E_OK only transits to challenge.
  148. if ((pAuthCtx->GetSchemeType() == AUTHCTX::SCHEME_KERBEROS
  149. && (ssResult == SEC_E_OK || ssResult == SEC_I_CONTINUE_NEEDED))
  150. || (pAuthCtx->GetSchemeType() != AUTHCTX::SCHEME_NEGOTIATE && ssResult == SEC_E_OK))
  151. {
  152. /*pAuthCtx->_pRequest*/pRequest->SetAuthState(AUTHSTATE_CHALLENGE);
  153. }
  154. }
  155. }
  156. __except (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION
  157. ? EXCEPTION_EXECUTE_HANDLER
  158. : EXCEPTION_CONTINUE_SEARCH )
  159. {
  160. DEBUG_PRINT(HTTP,
  161. ERROR,
  162. ("AuthenticateUserUI call down Faulted, return failure\n"));
  163. error = ERROR_BAD_FORMAT;
  164. goto quit;
  165. }
  166. ENDEXCEPT
  167. }
  168. }
  169. else
  170. {
  171. //
  172. // I don't expect to be called in this case
  173. //
  174. INET_ASSERT(FALSE);
  175. }
  176. quit:
  177. DEBUG_LEAVE(error);
  178. return error;
  179. }
  180. DWORD
  181. LaunchDlg(
  182. IN HWND hWnd,
  183. IN LPVOID lpParam,
  184. IN DWORD dwDlgResource,
  185. IN DLGPROC pDlgProc
  186. )
  187. /*++
  188. Routine Description:
  189. Creates and Launches the appropriate dialog based on
  190. the dialog resource passed in.
  191. Arguments:
  192. hWnd - Parent Window handle to show the dialog from.
  193. lpParam - Void pointer which will become the lParam value passed
  194. the dialog box proc.
  195. dwDlgResource - the dialog resource id.
  196. pDlgProc - Pointer to Function to use for this dialog.
  197. Return Value:
  198. DWORD
  199. ERROR_SUCCESS - Success.
  200. ERROR_CANCELLED - User clicked "Cancel" or "No" in the dialog.
  201. --*/
  202. {
  203. DEBUG_ENTER((DBG_INET,
  204. Dword,
  205. "LaunchDlg",
  206. "%#x, %#x, %d %x",
  207. hWnd,
  208. lpParam,
  209. dwDlgResource,
  210. pDlgProc
  211. ));
  212. DWORD error = ERROR_SUCCESS;
  213. INT_PTR result = 0;
  214. if ((dwDlgResource == IDD_NTLM_AUTH) ||
  215. (dwDlgResource == IDD_REALM_AUTH) ||
  216. (dwDlgResource == 0 /*Passport Auth*/) )
  217. {
  218. DWORD DisableCredMgr = 0;
  219. InternetReadRegistryDwordKey(HKEY_LOCAL_MACHINE,
  220. "DisableCredManager",
  221. (LPDWORD) &DisableCredMgr
  222. );
  223. if (GlobalPlatformWhistler && !DisableCredMgr)
  224. {
  225. CREDINFODLGTYPE *pDlgInfo = (CREDINFODLGTYPE *) lpParam;
  226. pDlgInfo->pAuthCtx->InitCredUI();
  227. HMODULE hCredUI = pDlgInfo->pAuthCtx->_hCredUI;
  228. PFN_CREDUI_PROMPTFORCREDENTIALS pfnCredUIPromptForCredentials = pDlgInfo->pAuthCtx->_pfnCredUIPromptForCredentials;
  229. PFN_CREDUI_PROMPTFORCREDENTIALS_W pfnCredUIPromptForCredentialsW = pDlgInfo->pAuthCtx->_pfnCredUIPromptForCredentialsW;
  230. if ( hCredUI != NULL)
  231. {
  232. DWORD dwCredFlags = 0;
  233. if (dwDlgResource == 0 /*Passport Auth*/)
  234. {
  235. PASSPORT_CTX* pPPCtx = (PASSPORT_CTX*)pDlgInfo->pAuthCtx;
  236. HTTP_REQUEST_HANDLE_OBJECT *pRequest = pDlgInfo->pRequest;
  237. HBITMAP hBitmap = NULL;
  238. PWSTR pszCbtxtW = NULL;
  239. PSTR pszCbtxtA = NULL;
  240. DWORD dwszCbChars = 0;
  241. WCHAR szUserNameW[CREDUI_MAX_USERNAME_LENGTH];
  242. szUserNameW[0] = L'\0';
  243. if (pPPCtx->PromptForCreds(&hBitmap, NULL, &dwszCbChars, NULL, NULL) == TRUE) // need to prompt user
  244. {
  245. // alloc the text and get it.
  246. if ( dwszCbChars > 0 )
  247. {
  248. pszCbtxtW = (PWSTR)HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwszCbChars + 1)*sizeof(WCHAR));
  249. pszCbtxtA = (PSTR)HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, (dwszCbChars + 1)*sizeof(CHAR));
  250. if ( pszCbtxtW != NULL && pszCbtxtA != NULL )
  251. {
  252. if ( pPPCtx->PromptForCreds(NULL, pszCbtxtW, &dwszCbChars, NULL, NULL ) == TRUE )
  253. {
  254. // convert WtoA
  255. if ( ::WideCharToMultiByte(CP_ACP, 0,
  256. pszCbtxtW, -1,
  257. pszCbtxtA, dwszCbChars + 1,
  258. NULL, NULL) == 0 )
  259. {
  260. // failed, don't send
  261. HeapFree ( GetProcessHeap(), 0, pszCbtxtW );
  262. HeapFree ( GetProcessHeap(), 0, pszCbtxtA );
  263. pszCbtxtW = NULL;
  264. pszCbtxtA = NULL;
  265. }
  266. else
  267. {
  268. UrlUnescapeA(pszCbtxtA, NULL, NULL, URL_UNESCAPE_INPLACE);
  269. if (::MultiByteToWideChar(CP_UTF8, 0, pszCbtxtA, -1, pszCbtxtW, dwszCbChars + 1) == 0)
  270. {
  271. // failed, don't send
  272. HeapFree ( GetProcessHeap(), 0, pszCbtxtW );
  273. HeapFree ( GetProcessHeap(), 0, pszCbtxtA );
  274. pszCbtxtW = NULL;
  275. pszCbtxtA = NULL;
  276. }
  277. }
  278. }
  279. }
  280. }
  281. CREDUI_INFOW CredUIInfo;
  282. CredUIInfo.cbSize = sizeof(CredUIInfo);
  283. CredUIInfo.hbmBanner = hBitmap;
  284. CredUIInfo.hwndParent = hWnd;
  285. CredUIInfo.pszCaptionText = NULL;
  286. CredUIInfo.pszMessageText = pszCbtxtW;
  287. WCHAR szPasswordW[CREDUI_MAX_PASSWORD_LENGTH];
  288. szPasswordW[0] = L'\0';
  289. dwCredFlags = 0;
  290. if (pPPCtx->_pPWC && pPPCtx->_pPWC->lpszUser)
  291. {
  292. ::MultiByteToWideChar(CP_ACP, 0, pPPCtx->_pPWC->lpszUser, -1, szUserNameW, strlen(pPPCtx->_pPWC->lpszUser) + 1);
  293. }
  294. if (szUserNameW[0] != L'\0')
  295. {
  296. dwCredFlags |= CREDUI_FLAGS_KEEP_USERNAME;
  297. }
  298. WCHAR wServerName[128];
  299. ::MultiByteToWideChar(CP_ACP, 0, pRequest->GetServerName(), -1, wServerName, 128);
  300. DWORD dwRet = (*pfnCredUIPromptForCredentialsW) ( &CredUIInfo,
  301. wServerName,
  302. NULL,
  303. ERROR_LOGON_FAILURE,
  304. szUserNameW,
  305. CREDUI_MAX_USERNAME_LENGTH,
  306. szPasswordW,
  307. CREDUI_MAX_PASSWORD_LENGTH,
  308. NULL,
  309. dwCredFlags );
  310. if ( dwRet == ERROR_SUCCESS)
  311. {
  312. CHAR szUserNameA[CREDUI_MAX_USERNAME_LENGTH];
  313. CHAR szPasswordA[CREDUI_MAX_PASSWORD_LENGTH];
  314. ::WideCharToMultiByte(CP_ACP, 0,
  315. szUserNameW, -1,
  316. szUserNameA, CREDUI_MAX_USERNAME_LENGTH,
  317. NULL, NULL);
  318. ::WideCharToMultiByte(CP_ACP, 0,
  319. szPasswordW, -1,
  320. szPasswordA, CREDUI_MAX_PASSWORD_LENGTH,
  321. NULL, NULL);
  322. AuthLock();
  323. //pRequest = (INTERNET_CONNECT_HANDLE_OBJECT *)hInternet;
  324. pRequest->SetUserOrPass ((LPSTR)szUserNameA, TRUE, FALSE);
  325. pRequest->SetUserOrPass ((LPSTR)szPasswordA, FALSE, FALSE);
  326. pRequest->TimeStampCreds();
  327. AuthUnlock();
  328. ZeroMemory ( szPasswordW, CREDUI_MAX_PASSWORD_LENGTH * sizeof(WCHAR) );
  329. ZeroMemory ( szPasswordA, CREDUI_MAX_PASSWORD_LENGTH * sizeof(CHAR) );
  330. }
  331. if ( pszCbtxtW != NULL )
  332. HeapFree ( GetProcessHeap(), 0, pszCbtxtW );
  333. if ( pszCbtxtA != NULL )
  334. HeapFree ( GetProcessHeap(), 0, pszCbtxtA );
  335. switch ( dwRet )
  336. {
  337. case ERROR_SUCCESS:
  338. g_fIgnoreCachedCredsForPassport = FALSE;
  339. // user entered information, try CredReadDomainCredentials again, the
  340. // Credentials entered by the user should be found by that call now.
  341. break;
  342. case ERROR_CANCELLED:
  343. // user cancelled from the dialog, fail authentication attempt.
  344. error = ERROR_CANCELLED;
  345. goto quit;
  346. // comment: double-check return code
  347. }
  348. }
  349. }
  350. else
  351. {
  352. InvalidPassType *ipt = pDlgInfo->pipt;
  353. CREDUI_INFO uiInfo;
  354. dwCredFlags = 0;
  355. uiInfo.cbSize = sizeof(uiInfo);
  356. uiInfo.hwndParent = hWnd;
  357. uiInfo.pszCaptionText = NULL;
  358. uiInfo.hbmBanner = NULL;
  359. if (dwDlgResource == IDD_NTLM_AUTH)
  360. {
  361. PLUG_CTX* pAuthCtx = (PLUG_CTX*) (pDlgInfo->pAuthCtx);
  362. uiInfo.pszMessageText = NULL;
  363. // dwCredFlags = CREDUI_FLAGS_EXPECT_CONFIRMATION;
  364. // If we're always prompting in this zone, write a server
  365. // specific credential because we may or may not have
  366. // target info and need to provide a consistent experience
  367. // in either case:
  368. if (GetCredPolicy(pDlgInfo->pRequest->GetURL()) ==
  369. URLPOLICY_CREDENTIALS_MUST_PROMPT_USER)
  370. {
  371. dwCredFlags |= CREDUI_FLAGS_SERVER_CREDENTIAL;
  372. }
  373. // need to check if credential persistence is available
  374. // borrowed from AuthDlgProc
  375. if (g_dwCredPersistAvail == CRED_PERSIST_UNKNOWN)
  376. g_dwCredPersistAvail = InetInitCredentialPersist();
  377. if (g_dwCredPersistAvail == CRED_PERSIST_NOT_AVAIL)
  378. dwCredFlags |= CREDUI_FLAGS_DO_NOT_PERSIST;
  379. error = (*pfnCredUIPromptForCredentials) ( &uiInfo,
  380. ipt->lpszHost,
  381. NULL,
  382. pAuthCtx->_SecStatus,
  383. // ERROR_LOGON_FAILURE,
  384. ipt->lpszUsername,
  385. min(CREDUI_MAX_USERNAME_LENGTH, ipt->ulMaxField - 1),
  386. ipt->lpszPassword,
  387. min(CREDUI_MAX_PASSWORD_LENGTH, ipt->ulMaxField - 1),
  388. NULL,
  389. dwCredFlags );
  390. }
  391. if ((error == ERROR_NO_SUCH_LOGON_SESSION) ||
  392. (dwDlgResource == IDD_REALM_AUTH))
  393. {
  394. dwCredFlags = CREDUI_FLAGS_EXCLUDE_CERTIFICATES |
  395. CREDUI_FLAGS_DO_NOT_PERSIST |
  396. CREDUI_FLAGS_GENERIC_CREDENTIALS;
  397. BOOL fSave = FALSE;
  398. BOOL fLastCredentialsFromStore = FALSE;
  399. PSTR pszMessageText = NULL;
  400. // If we have a realm name, use it for the message text.
  401. // If the name is too long, truncate it by copying to a
  402. // new buffer. If out of memory, just pass NULL to get the
  403. // default message text:
  404. if (ipt->lpszRealm != NULL)
  405. {
  406. DWORD cbMessageText = lstrlenA(ipt->lpszRealm);
  407. if (cbMessageText <= CREDUI_MAX_MESSAGE_LENGTH)
  408. {
  409. uiInfo.pszMessageText = ipt->lpszRealm;
  410. }
  411. else
  412. {
  413. pszMessageText = new CHAR[cbMessageText + 1];
  414. if (pszMessageText != NULL)
  415. {
  416. if (lstrcpyn(pszMessageText,
  417. ipt->lpszRealm,
  418. CREDUI_MAX_MESSAGE_LENGTH) == NULL)
  419. {
  420. delete [] pszMessageText;
  421. pszMessageText = NULL;
  422. }
  423. }
  424. uiInfo.pszMessageText = pszMessageText;
  425. }
  426. }
  427. else
  428. {
  429. uiInfo.pszMessageText = NULL;
  430. }
  431. // First, determine if credential persistence is available:
  432. if (g_dwCredPersistAvail == CRED_PERSIST_UNKNOWN)
  433. {
  434. g_dwCredPersistAvail = InetInitCredentialPersist();
  435. }
  436. if (g_dwCredPersistAvail != CRED_PERSIST_NOT_AVAIL)
  437. {
  438. dwCredFlags |= CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX;
  439. }
  440. // If any credentials are passed in, use them:
  441. if (ipt->lpszUsername[0] && ipt->lpszPassword[0])
  442. {
  443. fLastCredentialsFromStore = FALSE;
  444. ipt->lpszPassword[0] = '\0';
  445. }
  446. else
  447. {
  448. ipt->lpszUsername[0] = '\0';
  449. ipt->lpszPassword[0] = '\0';
  450. // Attempt to get credentials from persisted store:
  451. if (g_dwCredPersistAvail != CRED_PERSIST_NOT_AVAIL)
  452. {
  453. if (InetGetCachedCredentials(
  454. ipt->lpszHost,
  455. ipt->lpszRealm,
  456. ipt->lpszUsername,
  457. ipt->lpszPassword) == ERROR_SUCCESS)
  458. {
  459. fSave = TRUE;
  460. fLastCredentialsFromStore = TRUE;
  461. }
  462. else
  463. {
  464. fSave = FALSE;
  465. fLastCredentialsFromStore = FALSE;
  466. }
  467. }
  468. }
  469. error =
  470. pfnCredUIPromptForCredentials(
  471. &uiInfo,
  472. ipt->lpszHost,
  473. NULL,
  474. // pAuthCtx->_SecStatus,
  475. ERROR_LOGON_FAILURE,
  476. ipt->lpszUsername,
  477. min(CREDUI_MAX_USERNAME_LENGTH, ipt->ulMaxField - 1),
  478. ipt->lpszPassword,
  479. min(CREDUI_MAX_PASSWORD_LENGTH, ipt->ulMaxField - 1),
  480. g_dwCredPersistAvail ? &fSave : NULL,
  481. dwCredFlags);
  482. if (fSave)
  483. {
  484. InetSetCachedCredentials(
  485. ipt->lpszHost,
  486. ipt->lpszRealm,
  487. ipt->lpszUsername,
  488. ipt->lpszPassword);
  489. }
  490. else if (fLastCredentialsFromStore)
  491. {
  492. InetRemoveCachedCredentials(
  493. ipt->lpszHost,
  494. ipt->lpszRealm);
  495. }
  496. // Free our temporary message buffer, if necessary:
  497. if (pszMessageText != NULL)
  498. {
  499. delete [] pszMessageText;
  500. }
  501. }
  502. // Translate all failure cases into ERROR_CANCELLED for now:
  503. if (error != ERROR_SUCCESS)
  504. {
  505. error = ERROR_CANCELLED;
  506. }
  507. }
  508. }
  509. else
  510. {
  511. error = ERROR_CANCELLED;
  512. }
  513. goto quit;
  514. }
  515. else
  516. {
  517. // we are not using the Whistler CredUI
  518. if (dwDlgResource == 0 /*Passport Auth*/)
  519. {
  520. // biaow-todo: we don't know how to handle Passport-CredUI for downlevel yet;
  521. // panic in checked build
  522. INET_ASSERT(TRUE);
  523. // consider this "Cancelled" in retail...
  524. error = ERROR_CANCELLED;
  525. goto quit;
  526. }
  527. pDlgProc = AuthDialogProc;
  528. INET_ASSERT(pDlgProc);
  529. }
  530. }
  531. //
  532. // Launch the Dialog Box, and wait for it to complete
  533. //
  534. // Should actually cast lpParam as CREDINFODLGTYPE* and pass
  535. // pipt element instead of just lpParam.
  536. ULONG_PTR uCookie = 0;
  537. SHActivateContext(&uCookie);
  538. result = DialogBoxParamWrapW(GlobalResHandle,
  539. MAKEINTRESOURCEW(dwDlgResource),
  540. hWnd,
  541. pDlgProc,
  542. (LPARAM) lpParam);
  543. if (uCookie)
  544. {
  545. SHDeactivateContext(uCookie);
  546. }
  547. if ( result == FALSE || result == -1)
  548. {
  549. error = ERROR_CANCELLED;
  550. goto quit;
  551. }
  552. quit:
  553. DEBUG_LEAVE(error);
  554. return error;
  555. }
  556. DWORD
  557. MapWininetErrorToDlgId(
  558. IN DWORD dwError,
  559. OUT LPDWORD lpdwDlgId,
  560. OUT LPDWORD lpdwDlgFlags,
  561. OUT DLGPROC *ppDlgProc
  562. )
  563. /*++
  564. Routine Description:
  565. Maps a Wininet Error Code to an internal Dlg Resource Id.
  566. Arguments:
  567. dwError - A Wininet defined error code with an expected
  568. assoicated dlg.
  569. lpdwDlgId - Pointer to location where Dlg Id result will be returend.
  570. This ID can be used for creating a Dlg Resource.
  571. lpdwDlgFlags - Pointer to DWORD flags used to store various capiblites
  572. for Dialog.
  573. Return Value:
  574. DWORD
  575. Success - ERROR_SUCCESS
  576. Failure - ERROR_INVALID_PARAMETER
  577. Comments:
  578. none.
  579. --*/
  580. {
  581. typedef struct {
  582. DWORD dwWininetError;
  583. DWORD dwDlgId;
  584. DLGPROC pDlgProc;
  585. DWORD dwDlgFlags;
  586. } ErrorToDlgIdMappingType;
  587. ErrorToDlgIdMappingType MapErrorToDlg[] = {
  588. { ERROR_INTERNET_SEC_CERT_CN_INVALID, IDD_BAD_CN, OkCancelDialogProc, (DLG_FLAGS_CAN_HAVE_CERT_INFO | DLG_FLAGS_IGNORE_CERT_CN_INVALID) },
  589. { ERROR_INTERNET_SEC_CERT_DATE_INVALID, IDD_CERT_EXPIRED, OkCancelDialogProc, (DLG_FLAGS_CAN_HAVE_CERT_INFO | DLG_FLAGS_IGNORE_CERT_DATE_INVALID) },
  590. { ERROR_INTERNET_MIXED_SECURITY, IDD_MIXED_SECURITY, OkCancelDialogProc, 0 },
  591. { ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR, IDD_HTTP_TO_HTTPS_ZONE_CROSSING, OkCancelDialogProc, 0 },
  592. { ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR, IDD_HTTPS_TO_HTTP_ZONE_CROSSING, OkCancelDialogProc, 0 },
  593. { ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION, IDD_HTTP_POST_REDIRECT, OkCancelDialogProc, 0 },
  594. { ERROR_INTERNET_CHG_POST_IS_NON_SECURE, IDD_WARN_ON_POST, OkCancelDialogProc, 0 },
  595. { ERROR_INTERNET_POST_IS_NON_SECURE, IDD_WARN_ON_POST, OkCancelDialogProc, 0 },
  596. { ERROR_INTERNET_INVALID_CA, IDD_INVALID_CA, OkCancelDialogProc, (DLG_FLAGS_CAN_HAVE_CERT_INFO | DLG_FLAGS_IGNORE_INVALID_CA)},
  597. { ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED, IDD_CERTPICKER, CertPickDialogProc, 0 },
  598. { ERROR_INTERNET_BAD_AUTO_PROXY_SCRIPT, IDD_SCRIPT_ERROR, OkCancelDialogProc, 0 },
  599. { ERROR_INTERNET_UNABLE_TO_DOWNLOAD_SCRIPT, IDD_FAILED_DOWNLOAD, OkCancelDialogProc, (DLG_FLAGS_BRING_TO_FOREGROUND)},
  600. { ERROR_INTERNET_HTTPS_HTTP_SUBMIT_REDIR, IDD_HTTPS_TO_HTTP_SUBMIT_REDIRECT,OkCancelDialogProc, 0 },
  601. { ERROR_INTERNET_INSERT_CDROM, IDD_INSERT_CDROM, InsertCDDialogProc, 0 },
  602. { ERROR_INTERNET_SEC_CERT_ERRORS, IDD_SEC_CERT_ERRORS, OkCancelDialogProc, DLG_FLAGS_CAN_HAVE_CERT_INFO },
  603. { ERROR_INTERNET_SEC_CERT_REV_FAILED, IDD_REVOCATION_PROBLEM, OkCancelDialogProc, DLG_FLAGS_CAN_HAVE_CERT_INFO },
  604. };
  605. INET_ASSERT(lpdwDlgId);
  606. INET_ASSERT(lpdwDlgFlags);
  607. *lpdwDlgId = 0;
  608. *lpdwDlgFlags = 0;
  609. *ppDlgProc = 0;
  610. for ( DWORD i = 0; i < ARRAY_ELEMENTS(MapErrorToDlg); i++ )
  611. {
  612. if ( dwError == MapErrorToDlg[i].dwWininetError )
  613. {
  614. *lpdwDlgId = MapErrorToDlg[i].dwDlgId;
  615. *lpdwDlgFlags = MapErrorToDlg[i].dwDlgFlags;
  616. *ppDlgProc = MapErrorToDlg[i].pDlgProc;
  617. return ERROR_SUCCESS;
  618. }
  619. }
  620. INET_ASSERT(FALSE);
  621. return ERROR_INVALID_PARAMETER;
  622. }
  623. //
  624. // private functions.
  625. //
  626. BOOL
  627. CALLBACK
  628. ResizeAuthDialogProc(
  629. HWND hwnd,
  630. LPARAM lparam
  631. )
  632. {
  633. // passed lpRect contains top and bottom for inserted region, move all elements
  634. // below the top down by bottom-top
  635. LPRECT lpInsertRect = (LPRECT) lparam;
  636. RECT ChildRect;
  637. HWND hwndParent;
  638. hwndParent = GetParent(hwnd);
  639. if(!hwndParent)
  640. return FALSE;
  641. GetWindowRect(hwnd, &ChildRect);
  642. if(ChildRect.top >= lpInsertRect->top) {
  643. ScreenToClient(hwndParent, (LPPOINT) &ChildRect.left);
  644. SetWindowPos(hwnd, 0, ChildRect.left, ChildRect.top + (lpInsertRect->bottom - lpInsertRect->top), 0, 0, SWP_NOZORDER|SWP_NOSIZE);
  645. }
  646. return TRUE;
  647. }
  648. INT_PTR
  649. CALLBACK
  650. AuthDialogProc(
  651. HWND hwnd,
  652. UINT msg,
  653. WPARAM wparam,
  654. LPARAM lparam
  655. )
  656. /*++
  657. Routine Description:
  658. Handles authentication dialog
  659. Arguments:
  660. hwnd - standard dialog params
  661. msg - "
  662. wparam - "
  663. lparam - "
  664. Return Value:
  665. BOOL
  666. TRUE - we handled message
  667. FALSE - Windows should handle message
  668. --*/
  669. {
  670. const static DWORD mapIDCsToIDHs[] =
  671. {
  672. IDC_SITE_OR_FIREWALL, IDH_AUTH_SERVER_FIREWALL,
  673. IDC_SERVER_OR_PROXY, IDH_AUTH_SERVER_FIREWALL,
  674. IDC_USERNAME_TAG, IDH_SUBPROPS_RECTAB_LOGINOPTS_USER_ID,
  675. IDC_USERNAME, IDH_SUBPROPS_RECTAB_LOGINOPTS_USER_ID,
  676. IDC_PASSWORD_TAG, IDH_SUBPROPS_RECTAB_LOGINOPTS_PASSWORD,
  677. IDC_PASSWORD, IDH_SUBPROPS_RECTAB_LOGINOPTS_PASSWORD,
  678. IDC_DOMAIN_TAG, IDH_AUTH_DOMAIN,
  679. IDC_DOMAIN_FIELD, IDH_AUTH_DOMAIN,
  680. IDC_SAVE_PASSWORD, IDH_AUTH_SAVE_PASSWORD,
  681. IDC_REALM_TAG, IDH_AUTH_REALM,
  682. IDC_REALM_FIELD, IDH_AUTH_REALM,
  683. 0,0
  684. };
  685. static BOOL fLastCredentialsFromStore = FALSE;
  686. WCHAR wszTmp[MAX_FIELD_LENGTH];
  687. CREDINFODLGTYPE *pDlgInfo;
  688. InvalidPassType *ipt;
  689. PLOCAL_STRINGS plszStrings = FetchLocalStrings();
  690. switch (msg)
  691. {
  692. case WM_INITDIALOG:
  693. INET_ASSERT(lparam);
  694. CHAR szUsername[MAX_FIELD_LENGTH],
  695. szPassword[MAX_FIELD_LENGTH];
  696. CHAR *pUsr, *pDmn, *ptr;
  697. pDlgInfo = (CREDINFODLGTYPE *) lparam;
  698. ipt = pDlgInfo->pipt;
  699. SetForegroundWindow(hwnd);
  700. (void)SetWindowLongPtr(hwnd,
  701. DWLP_USER,
  702. (LONG_PTR)ipt);
  703. // First determine if credential persistence is available.
  704. if (g_dwCredPersistAvail == CRED_PERSIST_UNKNOWN)
  705. g_dwCredPersistAvail = InetInitCredentialPersist();
  706. if (g_dwCredPersistAvail == CRED_PERSIST_NOT_AVAIL)
  707. ShowWindow(GetDlgItem(hwnd, IDC_SAVE_PASSWORD), SW_HIDE);
  708. // If any credentials are passed in, use them.
  709. if (*ipt->lpszUsername && *ipt->lpszPassword)
  710. {
  711. // Flag that credentials did not come from
  712. // persistent store and copy values.
  713. fLastCredentialsFromStore = FALSE;
  714. memcpy(szUsername, ipt->lpszUsername, ipt->ulMaxField-1);
  715. // memcpy(szPassword, ipt->lpszPassword, ipt->ulMaxField-1);
  716. *szPassword = '\0';
  717. }
  718. else
  719. {
  720. // Otherwise, get any persisted credentials for this domain or realm.
  721. // Current credentials are originally blank.
  722. *szUsername = '\0';
  723. *szPassword = '\0';
  724. // Attempt to get credentials from persisted store.
  725. if (g_dwCredPersistAvail)
  726. {
  727. if (InetGetCachedCredentials(ipt->lpszHost, ipt->lpszRealm,
  728. szUsername, szPassword) == ERROR_SUCCESS)
  729. {
  730. #ifdef UNIX
  731. /* If the user had not selected to store the password,
  732. * we will save the password as NULL, but still save the
  733. * username and domain. So, if the password is null, we
  734. * don't check the button (this is ok because if somebody
  735. * wants to save a null password, it will come out as
  736. * null, but the button is not checked. Do you really
  737. * want ie to tell you that you saved a null password ?)
  738. */
  739. if (!*szPassword) {
  740. fLastCredentialsFromStore = FALSE;
  741. CheckDlgButton(hwnd, IDC_SAVE_PASSWORD, BST_UNCHECKED);
  742. }
  743. else
  744. #endif /* UNIX */
  745. {
  746. // Record that credentials were retrieved.
  747. CheckDlgButton(hwnd, IDC_SAVE_PASSWORD, BST_CHECKED);
  748. fLastCredentialsFromStore = TRUE;
  749. }
  750. }
  751. else
  752. {
  753. // Credentials were not retrieved.
  754. fLastCredentialsFromStore = FALSE;
  755. CheckDlgButton(hwnd, IDC_SAVE_PASSWORD, BST_UNCHECKED);
  756. }
  757. }
  758. }
  759. // If credential persistence is available, the save checkbox
  760. // is now visible. If credentials were retrieved from persistent
  761. // store then fLastCredentialsFromStore will now be set to TRUE
  762. // and the save check box will be checked. Otherwise,
  763. // fLastCredentialsFromStore will now be set to FALSE.
  764. // If the authentication type is NTLM, crack the domain\username stored
  765. // in ipt->lpszUsername into its constituent parts (domain and username).
  766. if (ipt->eAuthType == NTLM_AUTH)
  767. {
  768. // Scan Domain\Username for backslash.
  769. pUsr = strchr(szUsername, DOMAIN_DELIMITER);
  770. // Found backslash - replace with '\0'.
  771. if (pUsr)
  772. {
  773. *pUsr = '\0';
  774. pUsr++;
  775. pDmn = szUsername;
  776. }
  777. // No backslash found - take as username.
  778. else
  779. {
  780. pUsr = szUsername;
  781. pDmn = NULL;
  782. }
  783. // Set user and domain fields.
  784. SetWindowTextWrapW(GetDlgItem(hwnd,
  785. IDC_DOMAIN_OR_REALM), plszStrings->szDomain);
  786. // Blindly convert to unicode even tho' we don't know
  787. // the code page
  788. wszTmp[0] = TEXT('\0');
  789. SHAnsiToUnicode (pUsr, wszTmp, ARRAYSIZE(wszTmp));
  790. SetWindowTextWrapW (GetDlgItem(hwnd,IDC_USERNAME), wszTmp);
  791. // Indicate field is domain.
  792. // Blindly convert to unicode even tho' we don't know
  793. // the code page
  794. wszTmp[0] = TEXT('\0');
  795. if (pDmn)
  796. SHAnsiToUnicode (pDmn, wszTmp, ARRAYSIZE(wszTmp));
  797. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_DOMAIN_FIELD), wszTmp);
  798. // Hide IDC_REALM_FIELD which overlays IDC_DOMAIN_FIELD
  799. ShowWindow(GetDlgItem(hwnd,IDC_REALM_FIELD), SW_HIDE);
  800. }
  801. // Otherwise if auth type is basic or digest, simply display username.
  802. else if (ipt->eAuthType == REALM_AUTH)
  803. {
  804. // Set user and realm fields.
  805. // Blindly convert to unicode even tho' we don't know
  806. // the code page
  807. wszTmp[0] = TEXT('\0');
  808. SHAnsiToUnicode (szUsername, wszTmp, ARRAYSIZE(wszTmp));
  809. SetWindowTextWrapW(GetDlgItem(hwnd,IDC_USERNAME),
  810. wszTmp);
  811. // Blindly convert to unicode even tho' we don't know
  812. // the code page
  813. wszTmp[0] = TEXT('\0');
  814. SHAnsiToUnicode (ipt->lpszRealm, wszTmp, ARRAYSIZE(wszTmp));
  815. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_REALM_FIELD),
  816. wszTmp);
  817. // Indicate field is realm.
  818. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_REALM),
  819. plszStrings->szRealm);
  820. // qfe 4857 - long realm names are truncated
  821. if(ipt->lpszRealm && lstrlen(ipt->lpszRealm) > 20) {
  822. RECT WndRect;
  823. RECT RealmRect;
  824. // about 20 chars will fit per line, but bound it at 6 lines
  825. int cy = min(6, (lstrlen(ipt->lpszRealm) / 20));
  826. //resize window, text box, reposition all lower elements in callback
  827. GetWindowRect(GetDlgItem(hwnd,IDC_REALM_FIELD), &RealmRect);
  828. cy *= RealmRect.bottom - RealmRect.top; // Scale box taller
  829. SetWindowPos(GetDlgItem(hwnd,IDC_REALM_FIELD), 0, 0, 0, RealmRect.right- RealmRect.left, RealmRect.bottom- RealmRect.top + cy, SWP_NOZORDER|SWP_NOMOVE);
  830. GetWindowRect(hwnd, &WndRect);
  831. SetWindowPos(hwnd, 0, 0, 0, WndRect.right - WndRect.left, WndRect.bottom - WndRect.top + cy, SWP_NOZORDER|SWP_NOMOVE);
  832. RealmRect.top = RealmRect.bottom;
  833. RealmRect.bottom +=cy; // RealmRect contains the inserted region
  834. EnumChildWindows(hwnd, ResizeAuthDialogProc, (LPARAM) &RealmRect);
  835. }
  836. }
  837. // Set password field.
  838. SetWindowText (GetDlgItem(hwnd,IDC_PASSWORD), szPassword);
  839. // Indicate Site or Firewall as appropriate.
  840. if (ipt->fIsProxy)
  841. {
  842. SetWindowTextWrapW (GetDlgItem(hwnd,IDC_SITE_OR_FIREWALL),
  843. plszStrings->szFirewall);
  844. }
  845. else
  846. {
  847. SetWindowTextWrapW (GetDlgItem(hwnd,IDC_SITE_OR_FIREWALL),
  848. plszStrings->szSite);
  849. }
  850. // Finally indicate site/proxy.
  851. SetWindowText (GetDlgItem(hwnd,IDC_SERVER_OR_PROXY),
  852. ipt->lpszHost);
  853. (void)SendMessage(GetDlgItem(hwnd,IDC_USERNAME),
  854. EM_LIMITTEXT,
  855. (WPARAM)ipt->ulMaxField-1,
  856. 0L);
  857. (void)SendMessage(GetDlgItem(hwnd,IDC_PASSWORD),
  858. EM_LIMITTEXT,
  859. (WPARAM)ipt->ulMaxField-1,
  860. 0L);
  861. // If we already have a username, select
  862. // current password and put caret at end.
  863. if (*szUsername)
  864. {
  865. SendMessage(GetDlgItem(hwnd, IDC_PASSWORD),
  866. EM_SETSEL, 0, -1);
  867. SetFocus(GetDlgItem(hwnd, IDC_PASSWORD));
  868. }
  869. // Otherwise, select username
  870. else
  871. {
  872. SendMessage(GetDlgItem(hwnd, IDC_USERNAME),
  873. EM_SETSEL, 0, -1);
  874. SetFocus(GetDlgItem(hwnd, IDC_USERNAME));
  875. }
  876. // Return FALSE since we are always setting the keyboard focus.
  877. return FALSE;
  878. case WM_COMMAND:
  879. {
  880. WORD wID = LOWORD(wparam);
  881. WORD wNotificationCode = HIWORD(wparam);
  882. HWND hWndCtrl = (HWND) lparam;
  883. DWORD cbUsr, cbPass, cbDmn;
  884. ipt =
  885. (InvalidPassType *) GetWindowLongPtr(hwnd,DWLP_USER);
  886. switch (wID)
  887. {
  888. case IDOK:
  889. INET_ASSERT(ipt);
  890. INET_ASSERT(ipt->ulMaxField > 0 );
  891. INET_ASSERT(ipt->lpszUsername);
  892. INET_ASSERT(ipt->lpszPassword);
  893. if (ipt->eAuthType == REALM_AUTH)
  894. {
  895. // Basic or digest auth - not much to do.
  896. cbDmn = 0;
  897. // Does not include null.
  898. cbUsr = GetWindowTextWrapW(GetDlgItem(hwnd,IDC_USERNAME),
  899. wszTmp,
  900. ARRAYSIZE(wszTmp));
  901. INET_ASSERT(MAX_FIELD_LENGTH >= ipt->ulMaxField);
  902. // Convert this blindly to ANSI
  903. SHUnicodeToAnsi(wszTmp, ipt->lpszUsername, ipt->ulMaxField);
  904. }
  905. // NTLM auth - separate domain and username if necessary.
  906. else if (ipt->eAuthType == NTLM_AUTH)
  907. {
  908. // Does not include null.
  909. cbDmn = GetWindowTextWrapW(GetDlgItem(hwnd,IDC_DOMAIN_FIELD),
  910. wszTmp,
  911. ARRAYSIZE(wszTmp));
  912. // Convert this blindly to ANSI
  913. SHUnicodeToAnsi(wszTmp, ipt->lpszUsername, ipt->ulMaxField);
  914. // Domain was typed in.
  915. if (cbDmn)
  916. {
  917. // Check for backslash.
  918. ptr = strchr(ipt->lpszUsername, DOMAIN_DELIMITER);
  919. if (!ptr)
  920. {
  921. // No backslash - append one.
  922. *(ipt->lpszUsername + cbDmn) = DOMAIN_DELIMITER;
  923. *(ipt->lpszUsername + cbDmn + 1) = '\0';
  924. }
  925. // Found a backslash.
  926. else
  927. {
  928. // Strip after backslash.
  929. cbDmn = (DWORD)(ptr - ipt->lpszUsername);
  930. *(ptr+1) = '\0';
  931. }
  932. cbDmn++;
  933. }
  934. // Get the username and append to domain.
  935. cbUsr = GetWindowTextWrapW(GetDlgItem(hwnd,IDC_USERNAME),
  936. wszTmp,
  937. ARRAYSIZE(wszTmp));
  938. // Convert this blindly to ANSI
  939. // BUGBUG - should i
  940. SHUnicodeToAnsi(wszTmp, ipt->lpszUsername + cbDmn, (ipt->ulMaxField - cbDmn));
  941. }
  942. // Get the password.
  943. cbPass = GetWindowTextWrapW(GetDlgItem(hwnd,IDC_PASSWORD),
  944. wszTmp,
  945. ARRAYSIZE(wszTmp));
  946. SHUnicodeToAnsi(wszTmp, ipt->lpszPassword, ipt->ulMaxField);
  947. // If save box checked, persist credentials.
  948. if (IsDlgButtonChecked(hwnd, IDC_SAVE_PASSWORD) == BST_CHECKED)
  949. {
  950. InetSetCachedCredentials(ipt->lpszHost, ipt->lpszRealm,
  951. ipt->lpszUsername, ipt->lpszPassword);
  952. }
  953. else
  954. {
  955. #ifndef UNIX
  956. // Otherwise remove the credentials from persisted
  957. // store, but only if necessary.
  958. if (fLastCredentialsFromStore)
  959. {
  960. // Current and original credentials are same. Remove
  961. // credentials.
  962. InetRemoveCachedCredentials(ipt->lpszHost, ipt->lpszRealm);
  963. }
  964. #else
  965. /*
  966. * On Unix, we need to save the username/domain and not
  967. * the password in this case
  968. */
  969. {
  970. InetSetCachedCredentials(ipt->lpszHost, ipt->lpszRealm,
  971. ipt->lpszUsername, NULL);
  972. }
  973. #endif /* UNIX */
  974. }
  975. EndDialog(hwnd, TRUE);
  976. break;
  977. case IDCANCEL:
  978. EndDialog(hwnd, FALSE);
  979. break;
  980. }
  981. return TRUE;
  982. }
  983. case WM_HELP: // F1
  984. WinHelp((HWND) ((LPHELPINFO) lparam)->hItemHandle,
  985. "iexplore.hlp",
  986. HELP_WM_HELP,
  987. (ULONG_PTR)(LPSTR)mapIDCsToIDHs);
  988. break;
  989. case WM_CONTEXTMENU: // right mouse click
  990. WinHelp( hwnd,
  991. "iexplore.hlp",
  992. HELP_CONTEXTMENU,
  993. (ULONG_PTR)(LPSTR)mapIDCsToIDHs);
  994. break;
  995. }
  996. return FALSE;
  997. }
  998. VOID
  999. UpdateGlobalSecuritySettings(
  1000. IN DWORD dwCtlId,
  1001. IN DWORD dwFlags
  1002. )
  1003. /*++
  1004. Routine Description:
  1005. Updates several Global flags, and writes the update to the registry.
  1006. The update is based on dwCtlId which is a dialog resource id.
  1007. The update ALWAYS turns OFF the flag, since the only of turning
  1008. it back on is to use the Ctl Pannel/Internet/Security PropSheet.
  1009. Arguments:
  1010. dwCtlId - Dialog ID to base update on.
  1011. dwFlags - Flags assoicated with the dialog.
  1012. Return Value:
  1013. VOID
  1014. none.
  1015. --*/
  1016. {
  1017. #ifndef WININET6
  1018. switch ( dwCtlId )
  1019. {
  1020. case IDD_BAD_CN:
  1021. // case IDD_BAD_CN_SENDING:
  1022. //
  1023. // BUGBUG [arthurbi] these are grouped together,
  1024. // they should be seperate.
  1025. //
  1026. GlobalWarnOnBadCertRecving = FALSE;
  1027. GlobalWarnOnBadCertSending = FALSE;
  1028. InternetWriteRegistryDword("WarnOnBadCertSending",
  1029. (DWORD)GlobalWarnOnBadCertSending);
  1030. InternetWriteRegistryDword("WarnOnBadCertRecving",
  1031. (DWORD)GlobalWarnOnBadCertRecving);
  1032. break;
  1033. case IDD_HTTP_TO_HTTPS_ZONE_CROSSING:
  1034. case IDD_HTTPS_TO_HTTP_ZONE_CROSSING:
  1035. GlobalWarnOnZoneCrossing = FALSE;
  1036. InternetWriteRegistryDword("WarnOnZoneCrossing",
  1037. (DWORD)GlobalWarnOnZoneCrossing);
  1038. break;
  1039. case IDD_WARN_ON_POST:
  1040. GlobalWarnOnPost = FALSE;
  1041. InternetWriteRegistryDword("WarnOnPost",
  1042. (DWORD)GlobalWarnOnPost);
  1043. break;
  1044. case IDD_HTTP_POST_REDIRECT:
  1045. GlobalWarnOnPostRedirect = FALSE;
  1046. InternetWriteRegistryDword("WarnOnPostRedirect",
  1047. (DWORD)GlobalWarnOnPostRedirect);
  1048. break;
  1049. }
  1050. #else
  1051. switch ( dwCtlId )
  1052. {
  1053. case IDD_BAD_CN:
  1054. // case IDD_BAD_CN_SENDING:
  1055. //
  1056. // BUGBUG [arthurbi] these are grouped together,
  1057. // they should be seperate.
  1058. //
  1059. GlobalWarnOnBadCertRecving = FALSE;
  1060. GlobalWarnOnBadCertSending = FALSE;
  1061. InternetIDEWriteRegistryDword("WarnOnBadCertSending",
  1062. (DWORD)GlobalWarnOnBadCertSending);
  1063. InternetIDEWriteRegistryDword("WarnOnBadCertRecving",
  1064. (DWORD)GlobalWarnOnBadCertRecving);
  1065. break;
  1066. case IDD_HTTP_TO_HTTPS_ZONE_CROSSING:
  1067. case IDD_HTTPS_TO_HTTP_ZONE_CROSSING:
  1068. GlobalWarnOnZoneCrossing = FALSE;
  1069. InternetIDEWriteRegistryDword("WarnOnZoneCrossing",
  1070. (DWORD)GlobalWarnOnZoneCrossing);
  1071. break;
  1072. case IDD_WARN_ON_POST:
  1073. GlobalWarnOnPost = FALSE;
  1074. InternetIDEWriteRegistryDword("WarnOnPost",
  1075. (DWORD)GlobalWarnOnPost);
  1076. break;
  1077. case IDD_HTTP_POST_REDIRECT:
  1078. GlobalWarnOnPostRedirect = FALSE;
  1079. InternetIDEWriteRegistryDword("WarnOnPostRedirect",
  1080. (DWORD)GlobalWarnOnPostRedirect);
  1081. break;
  1082. }
  1083. #endif
  1084. }
  1085. BOOL
  1086. SetCertDlgItem(
  1087. HWND hDlg,
  1088. DWORD dwIconCtl,
  1089. DWORD dwTextCtl,
  1090. DWORD dwString,
  1091. BOOL fError
  1092. )
  1093. /*++
  1094. --*/
  1095. {
  1096. INET_ASSERT(hDlg);
  1097. //
  1098. // The default dialog code always load icons sized 32x32. To get 16x16
  1099. // we have to LoadImage to the correct size and then set the icon via
  1100. // a windows message.
  1101. //
  1102. HICON hicon = (HICON)LoadImage(GlobalResHandle,
  1103. MAKEINTRESOURCE(fError ? IDI_WARN : IDI_SUCCESS),
  1104. IMAGE_ICON, 16, 16, 0);
  1105. if (hicon)
  1106. {
  1107. HICON hiconOld = (HICON)SendDlgItemMessage(hDlg, dwIconCtl,
  1108. STM_SETIMAGE,
  1109. (WPARAM)IMAGE_ICON,
  1110. (LPARAM)hicon);
  1111. if (hiconOld)
  1112. DestroyIcon(hiconOld);
  1113. }
  1114. //
  1115. // The dialog displays the error string by default. Replace this with the
  1116. // success string if an error didn't occur.
  1117. //
  1118. if (!fError)
  1119. {
  1120. WCHAR sz[512];
  1121. if (LoadStringWrapW(GlobalResHandle, dwString, sz, ARRAY_ELEMENTS(sz)))
  1122. SetDlgItemTextWrapW(hDlg, dwTextCtl, sz);
  1123. }
  1124. return TRUE;
  1125. }
  1126. BOOL InitSecCertErrorsDlg(
  1127. HWND hDlg,
  1128. PERRORINFODLGTYPE pDlgInfo
  1129. )
  1130. /*++
  1131. --*/
  1132. {
  1133. INET_ASSERT(pDlgInfo);
  1134. //
  1135. // Get the errors that occured from the hInternetMapped object.
  1136. //
  1137. DWORD dwFlags;
  1138. if (pDlgInfo->hInternetMapped)
  1139. {
  1140. dwFlags = ((HTTP_REQUEST_HANDLE_OBJECT*)pDlgInfo->hInternetMapped)->GetSecureFlags();
  1141. }
  1142. else
  1143. {
  1144. dwFlags = -1; // Display all errors.
  1145. }
  1146. //
  1147. // If an error occured set the ignore flag so if the users selects to bypass
  1148. // this error it gets ignored the next time through. Then initialize the
  1149. // dialog icons and text.
  1150. //
  1151. if (dwFlags & DLG_FLAGS_INVALID_CA)
  1152. {
  1153. pDlgInfo->dwDlgFlags |= DLG_FLAGS_IGNORE_INVALID_CA;
  1154. }
  1155. SetCertDlgItem(hDlg, IDC_CERT_TRUST_ICON, IDC_CERT_TRUST_TEXT,
  1156. IDS_CERT_TRUST, dwFlags & DLG_FLAGS_INVALID_CA);
  1157. if (dwFlags & DLG_FLAGS_SEC_CERT_DATE_INVALID)
  1158. {
  1159. pDlgInfo->dwDlgFlags |= DLG_FLAGS_IGNORE_CERT_DATE_INVALID;
  1160. }
  1161. SetCertDlgItem(hDlg, IDC_CERT_DATE_ICON, IDC_CERT_DATE_TEXT,
  1162. IDS_CERT_DATE, dwFlags & DLG_FLAGS_SEC_CERT_DATE_INVALID);
  1163. if (dwFlags & DLG_FLAGS_SEC_CERT_CN_INVALID)
  1164. {
  1165. pDlgInfo->dwDlgFlags |= DLG_FLAGS_IGNORE_CERT_CN_INVALID;
  1166. }
  1167. SetCertDlgItem(hDlg, IDC_CERT_NAME_ICON, IDC_CERT_NAME_TEXT,
  1168. IDS_CERT_NAME, dwFlags & DLG_FLAGS_SEC_CERT_CN_INVALID);
  1169. //
  1170. // Set the focus to the "No" button and return FALSE so the default dialog
  1171. // code doesn't set the focus to "Yes".
  1172. //
  1173. SetFocus(GetDlgItem(hDlg, IDCANCEL));
  1174. return FALSE;
  1175. }
  1176. INT_PTR
  1177. CALLBACK
  1178. OkCancelDialogProc(
  1179. HWND hwnd,
  1180. UINT msg,
  1181. WPARAM wparam,
  1182. LPARAM lparam
  1183. )
  1184. /*++
  1185. Routine Description:
  1186. Supports Yes/No, Ok/Cancel decisions for the authentication UI.
  1187. Arguments:
  1188. hwnd - standard dialog params
  1189. msg - "
  1190. wparam - "
  1191. lparam - "
  1192. Return Value:
  1193. BOOL
  1194. TRUE - we handled message
  1195. FALSE - Windows should handle message
  1196. --*/
  1197. {
  1198. BOOL fRet = FALSE;
  1199. PERRORINFODLGTYPE pDlgInfo;
  1200. switch (msg)
  1201. {
  1202. case WM_INITDIALOG:
  1203. INET_ASSERT(lparam);
  1204. (void)SetWindowLongPtr(hwnd,
  1205. DWLP_USER,
  1206. lparam);
  1207. pDlgInfo = (PERRORINFODLGTYPE)lparam;
  1208. if (IDD_SEC_CERT_ERRORS == pDlgInfo->dwDlgId)
  1209. {
  1210. fRet = InitSecCertErrorsDlg(hwnd, pDlgInfo);
  1211. }
  1212. else if (IDD_REVOCATION_PROBLEM == pDlgInfo->dwDlgId)
  1213. {
  1214. DWORD dwFlags = 0;
  1215. if (pDlgInfo->hInternetMapped)
  1216. dwFlags = ((HTTP_REQUEST_HANDLE_OBJECT*)pDlgInfo->hInternetMapped)->GetSecureFlags();
  1217. if (dwFlags & DLG_FLAGS_SEC_CERT_REV_FAILED)
  1218. pDlgInfo->dwDlgFlags |= DLG_FLAGS_IGNORE_FAILED_REVOCATION;
  1219. }
  1220. else
  1221. {
  1222. #ifdef UNIX
  1223. /* Unix Does not support Context-sensitive help.
  1224. * Don't show the More Info button
  1225. */
  1226. //UnixAdjustButtonSpacing(hwnd, pDlgInfo->dwDlgId);
  1227. UnixRemoveMoreInfoButton(hwnd, pDlgInfo->dwDlgId);
  1228. #endif /* UNIX */
  1229. fRet = TRUE;
  1230. }
  1231. // set this dialog as foreground if necessary
  1232. if(pDlgInfo->dwDlgFlags & DLG_FLAGS_BRING_TO_FOREGROUND)
  1233. {
  1234. SetForegroundWindow(hwnd);
  1235. }
  1236. break;
  1237. case WM_COMMAND:
  1238. {
  1239. WORD wID = LOWORD(wparam);
  1240. WORD wNotificationCode = HIWORD(wparam);
  1241. HWND hWndCtrl = (HWND) lparam;
  1242. pDlgInfo =
  1243. (PERRORINFODLGTYPE) GetWindowLongPtr(hwnd,DWLP_USER);
  1244. switch (wID)
  1245. {
  1246. case ID_CERT_EDIT:
  1247. //
  1248. // BUGBUG why can't we do this on WM_INITDIALOG?
  1249. //
  1250. if ( wNotificationCode == EN_SETFOCUS)
  1251. {
  1252. //
  1253. // clear any selection, caused by it being the first
  1254. // edit control on the dlg page.
  1255. //
  1256. if ( ! (pDlgInfo->dwDlgFlags & DLG_FLAGS_HAS_DISABLED_SELECTION) )
  1257. {
  1258. SendDlgItemMessage(hwnd,ID_CERT_EDIT,EM_SETSEL,(WPARAM) (INT)-1,0);
  1259. pDlgInfo->dwDlgFlags |= DLG_FLAGS_HAS_DISABLED_SELECTION;
  1260. }
  1261. }
  1262. break;
  1263. case ID_TELL_ME_ABOUT_SECURITY:
  1264. {
  1265. //
  1266. // Launches help for this button.
  1267. //
  1268. //
  1269. // BUGBUG remove the constant "iexplore.hlp"
  1270. //
  1271. UINT uiID = 1;
  1272. switch (pDlgInfo->dwDlgId)
  1273. {
  1274. case IDD_CONFIRM_COOKIE:
  1275. uiID = IDH_SEC_SEND_N_REC_COOKIES;
  1276. break;
  1277. case IDD_HTTP_TO_HTTPS_ZONE_CROSSING:
  1278. uiID = IDH_SEC_ENTER_SSL;
  1279. break;
  1280. case IDD_HTTPS_TO_HTTP_ZONE_CROSSING:
  1281. uiID = IDH_SEC_ENTER_NON_SECURE_SITE;
  1282. break;
  1283. case IDD_INVALID_CA:
  1284. uiID = IDH_SEC_ENTER_SSL_W_INVALIDCERT;
  1285. break;
  1286. case IDD_BAD_CN:
  1287. uiID = IDH_SEC_SIGNED_N_INVALID;
  1288. break;
  1289. case IDD_MIXED_SECURITY:
  1290. uiID = IDH_SEC_MIXED_DOWNLOAD_FROM_SSL;
  1291. break;
  1292. }
  1293. WinHelp(
  1294. hwnd,
  1295. "iexplore.hlp",
  1296. HELP_CONTEXT,
  1297. (ULONG_PTR)uiID
  1298. );
  1299. break;
  1300. }
  1301. case ID_SHOW_CERTIFICATE:
  1302. //
  1303. // If this dialog supports this behavior, then launch
  1304. // a show certficate dlg.
  1305. //
  1306. if ( (pDlgInfo->dwDlgFlags & DLG_FLAGS_CAN_HAVE_CERT_INFO) &&
  1307. wNotificationCode == BN_CLICKED)
  1308. {
  1309. INTERNET_SECURITY_INFO ciSecInfo;
  1310. if (ERROR_SUCCESS == ((HTTP_REQUEST_HANDLE_OBJECT *)pDlgInfo->hInternetMapped)->GetSecurityInfo(
  1311. (LPINTERNET_SECURITY_INFO) &ciSecInfo))
  1312. {
  1313. ShowSecurityInfo(
  1314. hwnd,
  1315. &ciSecInfo
  1316. );
  1317. CertFreeCertificateContext(ciSecInfo.pCertificate);
  1318. }
  1319. }
  1320. break;
  1321. case IDOK:
  1322. case IDYES:
  1323. INET_ASSERT(pDlgInfo);
  1324. INET_ASSERT(pDlgInfo->dwDlgId != 0);
  1325. //
  1326. // Save flags, and change any global vars,
  1327. // and registry values if needed.
  1328. //
  1329. if (pDlgInfo->hInternetMapped)
  1330. {
  1331. HTTP_REQUEST_HANDLE_OBJECT *pHttpRequest;
  1332. pHttpRequest = (HTTP_REQUEST_HANDLE_OBJECT *)
  1333. pDlgInfo->hInternetMapped;
  1334. pHttpRequest->SetSecureFlags(
  1335. pDlgInfo->dwDlgFlags
  1336. );
  1337. }
  1338. //
  1339. // If the user checked the "overide" check-box
  1340. // let us map it, and force a general
  1341. // override of all errors of this type.
  1342. //
  1343. if ( IsDlgButtonChecked(hwnd, IDC_DONT_WANT_WARNING) == BST_CHECKED )
  1344. {
  1345. UpdateGlobalSecuritySettings(
  1346. pDlgInfo->dwDlgId,
  1347. pDlgInfo->dwDlgFlags
  1348. );
  1349. }
  1350. EndDialog(hwnd, TRUE);
  1351. break;
  1352. case IDCANCEL:
  1353. case IDNO:
  1354. EndDialog(hwnd, FALSE);
  1355. break;
  1356. }
  1357. fRet = TRUE;
  1358. break;
  1359. }
  1360. }
  1361. return fRet;
  1362. }
  1363. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  1364. BOOL
  1365. InitCookieDialog(HWND hwnd,PCOOKIE_DLG_INFO pcdi)
  1366. /*++
  1367. Fills in all of the fields and resizes the cookie dialog correctly
  1368. Returns TRUE, unless the pcdi is invalid
  1369. --*/
  1370. {
  1371. RECT rctDlg, rctDetails;
  1372. INT cy;
  1373. SYSTEMTIME st;
  1374. DWORD dwResource;
  1375. BOOL fResult = FALSE;
  1376. INET_ASSERT(pcdi);
  1377. WCHAR wszTemp[INTERNET_MAX_URL_LENGTH];
  1378. WCHAR wszTemp2[INTERNET_MAX_URL_LENGTH];
  1379. if (!pcdi ||
  1380. !pcdi->pszServer)
  1381. goto Cleanup;
  1382. /* Don't necessarily have a pic anymore
  1383. if (!pcdi ||
  1384. !pcdi->pszServer ||
  1385. !pcdi->pic->pszName ||
  1386. !pcdi->pic->pszData ||
  1387. !pcdi->pic->pszDomain ||
  1388. !pcdi->pic->pszPath )
  1389. return FALSE;
  1390. */
  1391. SetWindowLongPtr(hwnd, DWLP_USER, (LONG_PTR) pcdi);
  1392. // do init here. do we need to do a load loadicon??
  1393. // must limit the size of the window
  1394. GetWindowRect(hwnd, &rctDlg);
  1395. GetWindowRect(GetDlgItem(hwnd, IDC_COOKIE_INFO), &rctDetails);
  1396. pcdi->cx = rctDlg.right - rctDlg.left;
  1397. pcdi->cy = rctDlg.bottom - rctDlg.top;
  1398. cy = rctDetails.top - rctDlg.top;
  1399. SetWindowPos(hwnd, HWND_NOTOPMOST, 0, 0,
  1400. pcdi->cx, cy,
  1401. SWP_NOMOVE | SWP_NOZORDER);
  1402. if(pcdi->pic && pcdi->pic->pszDomain)
  1403. {
  1404. LoadStringWrapW(GlobalResHandle, IDS_COOKIE_SAVE, wszTemp, ARRAYSIZE(wszTemp));
  1405. wnsprintfW(wszTemp2, ARRAYSIZE(wszTemp2), wszTemp, pcdi->pic->pszDomain);
  1406. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_QUESTION), wszTemp2);
  1407. }
  1408. else
  1409. {
  1410. INET_ASSERT(FALSE);
  1411. }
  1412. // Convert to W before setting these fields
  1413. if(pcdi->pic)
  1414. {
  1415. //
  1416. // if we have a pic, fill out the members
  1417. //
  1418. if(SHAnsiToUnicode(pcdi->pic->pszData, wszTemp, ARRAYSIZE(wszTemp)))
  1419. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_DATA),wszTemp);
  1420. if(SHAnsiToUnicode(pcdi->pic->pszDomain, wszTemp, ARRAYSIZE(wszTemp)))
  1421. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_DOMAIN),wszTemp);
  1422. if(SHAnsiToUnicode(pcdi->pic->pszPath, wszTemp, ARRAYSIZE(wszTemp)))
  1423. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_PATH),wszTemp);
  1424. if (pcdi->dwOperation & COOKIE_OP_3RD_PARTY)
  1425. LoadStringWrapW(GlobalResHandle, IDS_YES, wszTemp, ARRAYSIZE(wszTemp));
  1426. else
  1427. LoadStringWrapW(GlobalResHandle, IDS_NO, wszTemp, ARRAYSIZE(wszTemp));
  1428. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_3RDPARTY), wszTemp);
  1429. if (pcdi->dwOperation & COOKIE_OP_SESSION)
  1430. LoadStringWrapW(GlobalResHandle, IDS_YES, wszTemp, ARRAYSIZE(wszTemp));
  1431. else
  1432. LoadStringWrapW(GlobalResHandle, IDS_NO, wszTemp, ARRAYSIZE(wszTemp));
  1433. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_SESSION), wszTemp);
  1434. if( pcdi->pic->pszP3PPolicy != NULL)
  1435. if( SHAnsiToUnicode( pcdi->pic->pszP3PPolicy, wszTemp, ARRAYSIZE( wszTemp)))
  1436. SetWindowTextWrapW( GetDlgItem( hwnd, IDC_COOKIE_POLICY), wszTemp);
  1437. if(0 == (pcdi->dwOperation & COOKIE_OP_GET))
  1438. {
  1439. if(SHAnsiToUnicode(pcdi->pic->pszName, wszTemp, ARRAYSIZE(wszTemp)))
  1440. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_NAME),wszTemp);
  1441. if (pcdi->pic->dwFlags & INTERNET_COOKIE_IS_SECURE)
  1442. LoadStringWrapW(GlobalResHandle, IDS_YES, wszTemp, ARRAYSIZE(wszTemp));
  1443. else
  1444. LoadStringWrapW(GlobalResHandle, IDS_NO, wszTemp, ARRAYSIZE(wszTemp));
  1445. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_SECURE),
  1446. wszTemp);
  1447. if(pcdi->pic->pftExpires &&
  1448. FileTimeToSystemTime(pcdi->pic->pftExpires, &st) )
  1449. {
  1450. LCID lcid = GetUserDefaultLCID();
  1451. WCHAR szDate[64];
  1452. WCHAR szTime[64];
  1453. WCHAR szDateFormat[] = L"ddd',' MMM dd yyyy";
  1454. WCHAR szTimeFormat[] = L"HH':'mm':'ss";
  1455. GetDateFormatWrapW(lcid, 0, &st, szDateFormat, szDate, 64);
  1456. GetTimeFormatWrapW(lcid, 0, &st, szTimeFormat, szTime, 64);
  1457. StrCpyNW(wszTemp, szDate, 64);
  1458. StrCatBuffW(wszTemp, L" ", ARRAYSIZE(wszTemp));
  1459. StrCatBuffW(wszTemp, szTime, ARRAYSIZE(wszTemp));
  1460. }
  1461. else
  1462. LoadStringWrapW(GlobalResHandle, IDS_COOKIE_EXPIRES_ENDSESSION, wszTemp, ARRAYSIZE(wszTemp));
  1463. SetWindowTextWrapW(GetDlgItem(hwnd, IDC_COOKIE_EXPIRES),
  1464. wszTemp);
  1465. }
  1466. }
  1467. // BUGBUGHACK - we actually should be called with the clients hwnd as parent -zekel 15MAY97
  1468. // then we wouldnt have to do this. this avoids the window coming up behind a browser window.
  1469. // of course they can still switch out, and close the browser, which will fault.
  1470. SetForegroundWindow(hwnd);
  1471. fResult = TRUE;
  1472. Cleanup:
  1473. return fResult;
  1474. }
  1475. #define COOKIE_DONT_ALLOW 1
  1476. #define COOKIE_ALLOW 2
  1477. #define COOKIE_ALLOW_ALL 4
  1478. #define COOKIE_DONT_ALLOW_ALL 8
  1479. INT_PTR
  1480. CALLBACK
  1481. CookieDialogProc(
  1482. HWND hwnd,
  1483. UINT msg,
  1484. WPARAM wparam,
  1485. LPARAM lparam
  1486. )
  1487. {
  1488. DWORD dwEndDlg = 0;
  1489. BOOL fReturn = FALSE;
  1490. PCOOKIE_DLG_INFO pcdi;
  1491. switch (msg)
  1492. {
  1493. case WM_INITDIALOG:
  1494. INET_ASSERT(lparam);
  1495. if(!InitCookieDialog(hwnd, (PCOOKIE_DLG_INFO) lparam))
  1496. {
  1497. dwEndDlg = COOKIE_DONT_ALLOW;
  1498. }
  1499. if( IsOS(OS_WHISTLERORGREATER))
  1500. {
  1501. HICON hIcon = LoadIcon(GlobalResHandle, MAKEINTRESOURCE(IDI_PRIVACY_XP));
  1502. if( hIcon != NULL)
  1503. SendDlgItemMessage(hwnd, IDC_PRIVACY_ICON, STM_SETICON, (WPARAM)hIcon, 0);
  1504. // icons loaded with LoadIcon never need to be released
  1505. }
  1506. fReturn = TRUE;
  1507. break;
  1508. case WM_COMMAND:
  1509. {
  1510. pcdi = (PCOOKIE_DLG_INFO) GetWindowLongPtr(hwnd,DWLP_USER);
  1511. switch (LOWORD(wparam))
  1512. {
  1513. case IDYES:
  1514. dwEndDlg = COOKIE_ALLOW;
  1515. if(BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_COOKIE_ALLOW_ALL))
  1516. {
  1517. pcdi->dwStopWarning = COOKIE_ALLOW_ALL;
  1518. }
  1519. fReturn = TRUE;
  1520. break;
  1521. case IDNO:
  1522. dwEndDlg = COOKIE_DONT_ALLOW;
  1523. if(BST_CHECKED == IsDlgButtonChecked(hwnd, IDC_COOKIE_ALLOW_ALL))
  1524. {
  1525. pcdi->dwStopWarning = COOKIE_DONT_ALLOW_ALL;
  1526. }
  1527. fReturn = TRUE;
  1528. break;
  1529. case IDC_COOKIE_HELP:
  1530. WinHelp(hwnd,
  1531. "iexplore.hlp",
  1532. HELP_CONTEXT,
  1533. (pcdi->dwOperation & COOKIE_OP_3RD_PARTY) ?
  1534. (ULONG_PTR)IDH_COOKIE_THIRD_PARTY :
  1535. (ULONG_PTR)IDH_COOKIE_FIRST_PARTY
  1536. );
  1537. fReturn = TRUE;
  1538. break;
  1539. case IDC_COOKIE_DETAILS:
  1540. //
  1541. // Fold out the bottom of the dialog
  1542. //
  1543. SetWindowPos(hwnd, HWND_TOP, 0, 0,
  1544. pcdi->cx, pcdi->cy,
  1545. SWP_NOMOVE | SWP_NOZORDER);
  1546. EnableWindow(GetDlgItem(hwnd, IDC_COOKIE_DETAILS), FALSE);
  1547. PostMessage( hwnd, WM_NEXTDLGCTL,
  1548. (WPARAM)GetDlgItem( hwnd, IDC_COOKIE_NAME), TRUE);
  1549. fReturn = TRUE;
  1550. break;
  1551. }
  1552. }
  1553. break;
  1554. }
  1555. if(dwEndDlg)
  1556. {
  1557. EndDialog(hwnd, (dwEndDlg == COOKIE_DONT_ALLOW) ? ERROR_HTTP_COOKIE_DECLINED : ERROR_SUCCESS);
  1558. }
  1559. return fReturn;
  1560. }
  1561. INT_PTR
  1562. CALLBACK
  1563. InsertCDDialogProc(
  1564. HWND hwnd,
  1565. UINT msg,
  1566. WPARAM wparam,
  1567. LPARAM lparam
  1568. )
  1569. {
  1570. PERRORINFODLGTYPE pDlgInfo;
  1571. DWORD dwDlgEnd = 0;
  1572. HTTP_REQUEST_HANDLE_OBJECT* phro;
  1573. CHAR szName[MAX_PATH];
  1574. CHAR szVolumeLabel[MAX_PATH];
  1575. BOOL fCD;
  1576. // Cache container info struct.
  1577. BYTE buf[2048];
  1578. DWORD cbCoI = 2048;
  1579. LPINTERNET_CACHE_CONTAINER_INFO pCoI = (LPINTERNET_CACHE_CONTAINER_INFO) buf;
  1580. LPSTR pszUrl;
  1581. BOOL fReturn = FALSE;
  1582. switch (msg)
  1583. {
  1584. // On dialog initialize.
  1585. case WM_INITDIALOG:
  1586. {
  1587. INET_ASSERT(lparam);
  1588. // Get the http request object.
  1589. pDlgInfo = (PERRORINFODLGTYPE)lparam;
  1590. (void)SetWindowLongPtr(hwnd, DWLP_USER, lparam);
  1591. phro = (HTTP_REQUEST_HANDLE_OBJECT*) pDlgInfo->hInternetMapped;
  1592. // Set the dialog window text with the container name.
  1593. pszUrl = phro->GetURL();
  1594. if (pszUrl && GetUrlCacheContainerInfo(pszUrl, pCoI, &cbCoI, 0))
  1595. SetWindowText(GetDlgItem(hwnd,IDC_CD_NAME), pCoI->lpszVolumeTitle);
  1596. fReturn = TRUE;
  1597. break;
  1598. }
  1599. // User entered info.
  1600. case WM_COMMAND:
  1601. {
  1602. pDlgInfo = (PERRORINFODLGTYPE) GetWindowLongPtr(hwnd,DWLP_USER);
  1603. INET_ASSERT(pDlgInfo);
  1604. switch (LOWORD(wparam))
  1605. {
  1606. case IDC_USE_CDROM:
  1607. dwDlgEnd = ERROR_INTERNET_FORCE_RETRY;
  1608. // Signal that dialog is no longer active.
  1609. fCD = InterlockedExchange((LONG*) &fCdromDialogActive, (LONG) FALSE);
  1610. INET_ASSERT(fCD);
  1611. fReturn = TRUE;
  1612. break;
  1613. case IDC_CONNECT_TO_INTERNET:
  1614. // Delete all containers with the same volume label.
  1615. // Get the http request object.
  1616. phro = (HTTP_REQUEST_HANDLE_OBJECT*) pDlgInfo->hInternetMapped;
  1617. // Set the dialog window text with the container name.
  1618. pszUrl = phro->GetURL();
  1619. // Get the container info for this url.
  1620. if (pszUrl && GetUrlCacheContainerInfo(pszUrl, pCoI, &cbCoI, 0))
  1621. {
  1622. // Found a volume label:
  1623. if (*pCoI->lpszVolumeLabel)
  1624. strcpy(szVolumeLabel, pCoI->lpszVolumeLabel);
  1625. else
  1626. *szVolumeLabel = '\0';
  1627. // Start an enumeration of containers.
  1628. DWORD dwOptions, dwModified;
  1629. dwOptions = dwModified = 0;
  1630. HANDLE hConFind = FindFirstUrlCacheContainer(&dwModified,
  1631. pCoI, &(cbCoI = 2048), dwOptions);
  1632. if (hConFind)
  1633. {
  1634. // If the volume label of the first container found
  1635. // match the volume label of the associated url then
  1636. // delete this container.
  1637. if ((*pCoI->lpszVolumeLabel == '\0')
  1638. || (!strcmp(szVolumeLabel, pCoI->lpszVolumeLabel)))
  1639. {
  1640. DeleteUrlCacheContainer(pCoI->lpszName, 0);
  1641. }
  1642. // Similarly, delete each container which
  1643. // is found to have a matching volume label.
  1644. while (FindNextUrlCacheContainer(hConFind,
  1645. pCoI, &(cbCoI = 2048)))
  1646. {
  1647. if ((*pCoI->lpszVolumeLabel == '\0')
  1648. || (!strcmp(szVolumeLabel, pCoI->lpszVolumeLabel)))
  1649. {
  1650. DeleteUrlCacheContainer(pCoI->lpszName, 0);
  1651. }
  1652. }
  1653. FindCloseUrlCache(hConFind);
  1654. }
  1655. }
  1656. dwDlgEnd = ERROR_CANCELLED;
  1657. // Signal that dialog is no longer active.
  1658. fCD = InterlockedExchange((LONG*) &fCdromDialogActive, (LONG) FALSE);
  1659. INET_ASSERT(fCD);
  1660. fReturn = TRUE;
  1661. break;
  1662. }
  1663. }
  1664. break;
  1665. }
  1666. if (dwDlgEnd)
  1667. EndDialog(hwnd, dwDlgEnd);
  1668. return fReturn;
  1669. }