windows-nt/Source/XPSP1/NT/shell/cpls/inetcpl/content.cpp

2460 lines
75 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//*********************************************************************
//* Microsoft Windows **
//* Copyright(c) Microsoft Corp., 1995 **
//*********************************************************************
//
// content.cpp - "Content" property sheet
//
// HISTORY:
//
// 5/17/97 t-ashlm created
#include "inetcplp.h"
#include <wab.h>
#include <cryptui.h>
#include <msiehost.h>
#include <schannel.h>
#include <mluisupp.h>
//
// Private Functions and Structures
//
// WINTRUST / SOFTPUB
// definition from WINTRUST.H
// extern "C" BOOL WINAPI OpenPersonalTrustDBDialog(HWND hwndParent);
typedef BOOL (WINAPI *WINTRUSTDLGPROC)(HWND hwndParent);
WINTRUSTDLGPROC g_WinTrustDlgProc = (WINTRUSTDLGPROC)NULL;
SSL_EMPTY_CACHE_FN_W g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W)NULL;
#ifdef WALLET
BOOL IsWallet3Installed();
BOOL IsWalletAddressAvailable(VOID);
BOOL IsWalletPaymentAvailable(VOID);
#endif
HRESULT ShowModalDialog(HWND hwndParent, IMoniker *pmk, VARIANT *pvarArgIn, TCHAR* pchOptions, VARIANT *pvArgOut);
HCERTSTORE PFXImportCertStore(CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
BOOL PFXExportCertStore(HCERTSTORE hStore, CRYPT_DATA_BLOB* pPFX, LPCWSTR szPassword, DWORD dwFlags);
BOOL _AorW_GetFileNameFromBrowse(HWND hDlg,
LPWSTR pszFilename,
UINT cchFilename,
LPCWSTR pszWorkingDir,
LPCWSTR pszExt,
LPCWSTR pszFilter,
LPCWSTR pszTitle);
INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
//BUBUG: The following prototype should be rermoved when we have updated our Crypto API to latest version
BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext);
//////////////////////////////////////////////
// stolen from \inet\schannel\sspi\spreg.h
#define REG_SITECERT_BASE TEXT("System\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\CertificationAuthorities")
#define REG_SITECERT_CERT_VAL TEXT("CACert")
#define SITECERTKEYLEN 80 // FEATURE: should probably grab this value somewhere
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
#include <initguid.h>
// Use the wallet "payment" guid for JIT (different for alpha and x86...)
#ifdef _ALPHA_
// {B7FB4D5C-9FBE-11D0-8965-0000F822DEA9}
DEFINE_GUID(CLSID_WalletPayment, 0xb7fb4d5c, 0x9fbe, 0x11d0, 0x89, 0x65, 0x0, 0x0, 0xf8, 0x22, 0xde, 0xa9);
#else
// {87D3CB66-BA2E-11CF-B9D6-00A0C9083362}
DEFINE_GUID(CLSID_WalletPayment, 0x87d3cb66, 0xba2e, 0x11cf, 0xb9, 0xd6, 0x0, 0xa0, 0xc9, 0x08, 0x33, 0x62);
#endif
// WAB GUID for JIT
DEFINE_GUID(CLSID_WAB, 0x32714800, 0x2E5F, 0x11d0, 0x8B, 0x85, 0x00, 0xAA, 0x00, 0x44, 0xF9, 0x41);
#define EKU_CODESIGN_OFF 0
#define EKU_EMAIL_OFF 1
#define EKU_CLIENT_OFF 2
#define EKU_SERVER_OFF 3
#define EKU_DISABLE_OFF 4
const LPSTR g_rgszEnhkeyUsage[] =
{
szOID_PKIX_KP_CODE_SIGNING,
szOID_PKIX_KP_EMAIL_PROTECTION,
szOID_PKIX_KP_CLIENT_AUTH,
szOID_PKIX_KP_SERVER_AUTH,
szOID_YESNO_TRUST_ATTR,
NULL
};
typedef struct {
HWND hDlg; // handle to window
HRESULT hrUseRatings; // error=not installed; S_OK=enabled; S_FALSE=disabled
HINSTANCE hWinTrust; // WINTRUST/SOFTPUB library handle
HINSTANCE hSChannel; // schannel library handle
} CONTENTPAGE, *LPCONTENTPAGE;
BOOL ContentDlgApplyNow( LPCONTENTPAGE pCon );
BOOL ContentDlgEnableControls( IN HWND hDlg );
BOOL ContentDlgInit( IN HWND hDlg );
VOID DisplayWalletPaymentDialog(HWND hWnd);
VOID DisplayWalletAddressDialog(HWND hWnd);
STDAPI ResetProfileSharing(HWND hwnd);
EXTERN_C HRESULT ClearAutoSuggestForForms(DWORD dwClear);
//
// SecurityDlgEnableControls()
//
// Does initalization for Security Dlg.
//
// History:
//
// 6/17/96 t-gpease moved
//
BOOL ContentDlgEnableControls( IN HWND hDlg )
{
HKEY hkey=NULL;
if( g_restrict.fRatings )
{
EnableWindow( GetDlgItem(hDlg, IDC_RATINGS_TURN_ON), FALSE );
EnableWindow( GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), FALSE );
#if 0 // don't diable the text
EnableDlgItem( hDlg, IDC_RATINGS_TEXT, FALSE);
EnableDlgItem( hDlg, IDC_ADVANCED_RATINGS_GROUPBOX, FALSE);
#endif
}
if( g_restrict.fCertif || g_restrict.fCertifPub)
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON), FALSE );
if( g_restrict.fCertif || g_restrict.fCertifPers || g_restrict.fCertifSite)
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_SITES_BUTTON), FALSE );
if( g_restrict.fProfiles )
{
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_PROFILE), FALSE);
}
if (hkey)
RegCloseKey(hkey);
#ifdef WALLET
if (g_restrict.fWallet)
{
EnableWindow(GetDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS), FALSE);
}
#endif
return TRUE;
}
void InitRatingsButton(HWND hDlg, HRESULT hrEnabled)
{
TCHAR szBuf[MAX_RES_LEN+1];
UINT idString;
BOOL fEnableSettingsButton;
if (FAILED(hrEnabled)) {
/* Ratings are not installed. Disable the Settings button and
* set the other button to say "Enable".
*/
idString = IDS_RATINGS_TURN_ON;
fEnableSettingsButton = FALSE;
}
else {
idString = (hrEnabled == S_OK) ? IDS_RATINGS_TURN_OFF : IDS_RATINGS_TURN_ON;
fEnableSettingsButton = TRUE;
}
EnableWindow(GetDlgItem(hDlg, IDC_ADVANCED_RATINGS_BUTTON), fEnableSettingsButton);
if (MLLoadString(
idString,
szBuf, sizeof(szBuf)) > 0) {
SetDlgItemText(hDlg, IDC_RATINGS_TURN_ON, szBuf);
}
}
//
// ContentDlgInit()
//
// Does initalization for Content Dlg.
//
//
BOOL ContentDlgInit( HWND hDlg)
{
LPCONTENTPAGE pCon;
pCon = (LPCONTENTPAGE)LocalAlloc(LPTR, sizeof(*pCon));
if (!pCon)
{
EndDialog(hDlg, 0);
return FALSE; // no memory?
}
// tell dialog where to get info
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pCon);
// save the handle to the page
pCon->hDlg = hDlg;
// Load the Ratings DLL (if possible)
g_hinstRatings = LoadLibrary(c_tszRatingsDLL);
// if not..
if (!g_hinstRatings)
g_restrict.fRatings = TRUE; // disable Ratings section
// set ratings dialog items...
// if MSRATING.DLL not around, then don't do this call. By not
// doing this, it will keep the "Enable Ratings" text on the button
// but greyed off.
if (g_hinstRatings)
pCon->hrUseRatings = RatingEnabledQuery();
InitRatingsButton(hDlg, pCon->hrUseRatings);
// if we can't find WINTRUST or SOFTPUB disable the
// "Publishers" button.
pCon->hWinTrust = LoadLibrary(TEXT("wintrust.dll"));
if ( pCon->hWinTrust )
{
g_WinTrustDlgProc =
(WINTRUSTDLGPROC) GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
// didn't find the procecdure
if (!g_WinTrustDlgProc)
{
// release library and try the other DLL.
FreeLibrary(pCon->hWinTrust);
//
// We can also find the same function on NT machines (and
// possibly future Win95s) in SOFTPUB.DLL so make another
// check there too.
//
pCon->hWinTrust = LoadLibrary(TEXT("softpub.dll"));
}
}
if (pCon->hWinTrust && !g_WinTrustDlgProc)
g_WinTrustDlgProc = (WINTRUSTDLGPROC)
GetProcAddress(pCon->hWinTrust, "OpenPersonalTrustDBDialog");
// if after all this, we can't find the procedure...
if (!g_WinTrustDlgProc)
{
// disable the button
EnableDlgItem(hDlg, IDC_SECURITY_PUBLISHERS_BUTTON, FALSE);
}
// Only present UI for flushing the SSL cache on Whistler or greater
// This is the minimum version which has the default behavior of
// maintaining the SSL cache for all processes in a logon session.
//
// Note: This support was also added for Win2K SP2, but no cache
// clearing functionality was added. It's also not enabled
// by default.
if (IsOS(OS_WHISTLERORGREATER))
{
pCon->hSChannel = LoadLibrary(TEXT("SCHANNEL.DLL"));
if (pCon->hSChannel)
{
g_pfnSslEmptyCacheW = (SSL_EMPTY_CACHE_FN_W) GetProcAddress(pCon->hSChannel, "SslEmptyCacheW");
}
}
if(!g_pfnSslEmptyCacheW)
{
ShowWindow(GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), SW_HIDE);
EnableWindow( GetDlgItem(hDlg, IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON), FALSE );
}
#ifdef WALLET
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_SETTINGS, TRUE);
#endif
ContentDlgEnableControls(hDlg);
return TRUE;
}
//
// ContentOnCommand()
//
// Handles Content Dialog's window messages
//
// History:
//
// 6/17/96 t-gpease created
//
void ContentOnCommand(LPCONTENTPAGE pCon, UINT id, UINT nCmd)
{
switch (id) {
case IDC_ADVANCED_RATINGS_BUTTON:
{
RatingSetupUI(pCon->hDlg, (LPCSTR) NULL);
}
break; // IDC_ADVANCED_RATINGS_BUTTON
case IDC_RATINGS_TURN_ON:
{
if (SUCCEEDED(RatingEnable(pCon->hDlg, (LPCSTR)NULL,
pCon->hrUseRatings != S_OK)))
{
pCon->hrUseRatings = RatingEnabledQuery();
InitRatingsButton(pCon->hDlg, pCon->hrUseRatings);
}
}
break;
case IDC_SECURITY_CLEAR_SSL_CACHE_BUTTON:
{
if (g_pfnSslEmptyCacheW && (*g_pfnSslEmptyCacheW)(NULL, 0))
{
DWORD dwCount;
// Leverage a private cache header data counter
// that was never used to avoid passing a reg value.
if (IncrementUrlCacheHeaderData(CACHE_HEADER_DATA_DOWNLOAD_PARTIAL, &dwCount))
{
// Display message about clearing the cache OK.
TCHAR szText[MAX_PATH], szTitle[80];
MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TEXT, szText, ARRAYSIZE(szText));
MLLoadShellLangString(IDS_CLEAR_SSL_CACHE_TITLE, szTitle, ARRAYSIZE(szTitle));
MessageBox(pCon->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
}
}
}
break;
case IDC_SECURITY_SITES_BUTTON:
{
CRYPTUI_CERT_MGR_STRUCT ccm = {0};
ccm.dwSize = sizeof(ccm);
ccm.hwndParent = pCon->hDlg;
CryptUIDlgCertMgr(&ccm);
// if (!g_hinstCryptui)
// {
// EnableWindow(GetDlgItem(pCon->hDlg, IDC_SECURITY_SITES_BUTTON), FALSE);
// }
}
break;
case IDC_SECURITY_PUBLISHERS_BUTTON:
{
if (g_WinTrustDlgProc)
{
g_WinTrustDlgProc(pCon->hDlg);
}
}
break;
#ifdef WALLET
case IDC_PROGRAMS_WALLET_SETTINGS:
{
HRESULT hr = S_OK;
// See if wallet is installed at all
if (!IsWalletPaymentAvailable())
{
uCLSSPEC clsspec;
clsspec.tyspec = TYSPEC_CLSID;
clsspec.tagged_union.clsid = CLSID_WalletPayment;
// If wallet isn't installed, ask user if they'd like to install it
hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
}
if (SUCCEEDED(hr))
{
// Wallet is installed
if (IsWallet3Installed())
{
// if wallet 3.0 is installed, we want to invoke the wallet UI directly
DisplayWalletPaymentDialog(pCon->hDlg);
}
else
{
// otherwise we need to pop up this intermediate dialog
DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_WALLET_SETTINGS), pCon->hDlg, WalletDlgProc);
}
}
}
break;
#endif
case IDC_AUTOSUGGEST_SETTINGS:
{
DialogBox(MLGetHinst(), MAKEINTRESOURCE(IDD_AUTOSUGGEST_SETTINGS), pCon->hDlg, AutoSuggestDlgProc);
}
break;
case IDC_EDIT_PROFILE:
{
HMODULE hInstWAB = NULL;
LPWABOBJECT lpWABObject = NULL;
LPADRBOOK lpAdrBook = NULL;
HRESULT hr=S_OK;
// Ask user to JIT in WAB if it's not installed
uCLSSPEC clsspec;
clsspec.tyspec = TYSPEC_CLSID;
clsspec.tagged_union.clsid = CLSID_WAB;
// If WAB isn't installed, ask user if they'd like to install it
hr = FaultInIEFeature(NULL, &clsspec, NULL, FIEF_FLAG_FORCE_JITUI);
if (FAILED(hr))
{
break;
}
// Figure out the location of the wab dll and try opening it.
TCHAR szWABDllPath[MAX_PATH];
DWORD dwType = 0;
ULONG cbData = sizeof(szWABDllPath) * sizeof(TCHAR);
HKEY hKey = NULL;
SBinary SBMe = { 0, 0};
*szWABDllPath = '\0';
if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, WAB_DLL_PATH_KEY, 0, KEY_READ, &hKey))
{
RegQueryValueEx( hKey, TEXT(""), NULL, &dwType, (LPBYTE) szWABDllPath, &cbData);
RegCloseKey(hKey);
}
if (lstrlen(szWABDllPath) > 0 )
{
hInstWAB = LoadLibrary(szWABDllPath);
}
if (hInstWAB)
{
LPWABOPEN lpfnWABOpen = (LPWABOPEN) GetProcAddress(hInstWAB, "WABOpen");
if (lpfnWABOpen)
{
hr = lpfnWABOpen(&lpAdrBook, &lpWABObject, NULL, 0);
if (NULL == lpAdrBook || NULL == lpWABObject)
hr = E_UNEXPECTED;
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND); // Not the right dll anyway!!
}
}
else
{
hr = HRESULT_FROM_WIN32(ERROR_DLL_NOT_FOUND);
}
DWORD dwAction = 0;
// Good so far, call GetMe. WAB may create a new entry in this call.
if (SUCCEEDED(hr))
{
hr = lpWABObject->GetMe(lpAdrBook, 0, &dwAction, &SBMe, 0);
if (0 == SBMe.cb || NULL == SBMe.lpb)
hr = E_UNEXPECTED;
}
// This shows the final UI. If WAB created a new entry in GetMe, they
// already showed this UI and we don't need to do it again.
if (SUCCEEDED(hr) && !(dwAction & WABOBJECT_ME_NEW))
{
hr = lpAdrBook->Details( (LPULONG) &pCon->hDlg,
NULL,
NULL,
SBMe.cb,
(LPENTRYID)SBMe.lpb,
NULL,
NULL,
NULL,
0);
}
if (lpWABObject)
{
if (SBMe.lpb != NULL)
lpWABObject->FreeBuffer(SBMe.lpb);
lpWABObject->Release();
}
if (lpAdrBook)
lpAdrBook->Release();
if (hInstWAB)
FreeLibrary(hInstWAB);
}
}
} // ContentOnCommand()
/****************************************************************
Name: ContentDlgProc
SYNOPSIS: Set various security issue settings.
****************************************************************/
INT_PTR CALLBACK ContentDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
LPCONTENTPAGE pCon;
if (uMsg == WM_INITDIALOG)
return ContentDlgInit( hDlg );
else
pCon = (LPCONTENTPAGE) GetWindowLongPtr(hDlg, DWLP_USER);
if (!pCon)
return FALSE;
switch (uMsg)
{
case WM_COMMAND:
ContentOnCommand(pCon, LOWORD(wParam), HIWORD(wParam));
return TRUE;
case WM_NOTIFY:
{
NMHDR *lpnm = (NMHDR *) lParam;
ASSERT(lpnm);
switch (lpnm->code) {
case PSN_QUERYCANCEL:
case PSN_KILLACTIVE:
case PSN_RESET:
SetWindowLongPtr( pCon->hDlg, DWLP_MSGRESULT, FALSE );
return TRUE;
case PSN_APPLY:
break;
}
break;
}
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_DESTROY:
ASSERT(pCon);
if (pCon)
{
if (pCon->hWinTrust)
{
FreeLibrary(pCon->hWinTrust);
g_WinTrustDlgProc = NULL;
}
if (pCon->hSChannel)
{
FreeLibrary(pCon->hSChannel);
g_pfnSslEmptyCacheW = NULL;
}
LocalFree(pCon);
}
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
break;
}
return FALSE;
}
typedef struct tagSITECERTDIALOGINFO {
HWND hDlg;
HWND hwndList;
HWND hwndCombo;
int iSel;
HCERTSTORE hCertStore;
BOOL fInitializing;
} SITECERTDIALOGINFO, *LPSITECERTDIALOGINFO;
BOOL _SearchKeyUsage(CERT_ENHKEY_USAGE *pUsage, LPSTR pszUsageIdentifier)
{
DWORD i;
for (i = 0; i < pUsage->cUsageIdentifier; i++)
{
if (StrCmpA(pUsage->rgpszUsageIdentifier[i], pszUsageIdentifier) == 0)
{
return(TRUE);
}
}
return(FALSE);
}
BOOL _IsKnownUsage(char *pszTest)
{
char **ppszKnown;
ppszKnown = (char **)g_rgszEnhkeyUsage;
while (*ppszKnown)
{
if (StrCmpA(*ppszKnown, pszTest) == 0)
{
return(TRUE);
}
ppszKnown++;
}
return(FALSE);
}
void __AddAllKnownEKU(PCCERT_CONTEXT pCert)
{
char **ppszKnown;
ppszKnown = (char **)g_rgszEnhkeyUsage;
while (*ppszKnown)
{
CertAddEnhancedKeyUsageIdentifier(pCert, *ppszKnown);
ppszKnown++;
}
}
BOOL _AnyKnownUsage(CERT_ENHKEY_USAGE *pUsage)
{
DWORD i;
for (i = 0; i < pUsage->cUsageIdentifier; i++)
{
if (_IsKnownUsage(pUsage->rgpszUsageIdentifier[i]))
{
return(TRUE);
}
}
return(FALSE);
}
BOOL _IsUsageEnabled(PCCERT_CONTEXT pCertContext, LPSTR pszUsageIdentifier, BOOL * pfFound)
{
CERT_ENHKEY_USAGE *pUsage;
DWORD cbUsage;
*pfFound = FALSE;
//
// first, check the Extensions to see if we should even display it!
//
cbUsage = 0;
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
if (cbUsage > 0)
{
//
// we have some... make sure ours is in the list
//
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
{
return(FALSE);
}
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
{
LocalFree((void *)pUsage);
return(FALSE);
}
LocalFree((void *)pUsage);
}
*pfFound = TRUE; // the cert should go in the list!
//
// ethier there where no assertions made by the CA or we found it! continue on...
//
//
// second, check the properties to see if we should check the box
//
cbUsage = 0;
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
if (cbUsage > 0)
{
//
// we have properties... make sure we aren't disabled
//
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
{
return(FALSE);
}
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pUsage, &cbUsage);
if (_SearchKeyUsage(pUsage, g_rgszEnhkeyUsage[EKU_DISABLE_OFF]))
{
//
// the user has disabled the cert... keep it in the list un-checked
//
LocalFree((void *)pUsage);
return(FALSE);
}
if (!(_SearchKeyUsage(pUsage, pszUsageIdentifier)))
{
//
// the user has set some, but, disabled this one... keep in the list un-checked
//
LocalFree((void *)pUsage);
return(FALSE);
}
LocalFree((void *)pUsage);
}
return(TRUE);
}
BOOL SiteCert_InitListView(LPSITECERTDIALOGINFO pscdi)
{
PCCERT_CONTEXT pCertContext = NULL;
// delete all items currently in the listview
// we'll get called back via LVN_DELETEITEM with the lParam so we can free the cert context
ListView_DeleteAllItems(pscdi->hwndList);
pscdi->hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
if (pscdi->hCertStore)
{
LPSTR pszEnhkeyUsage;
INT_PTR iSel;
iSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0,0);
pszEnhkeyUsage = (LPSTR)SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, iSel, 0);
while (pCertContext = CertEnumCertificatesInStore(pscdi->hCertStore, pCertContext))
{
CHAR szCertA[MAX_PATH];
TCHAR szCert[MAX_PATH];
DWORD cbszCert = ARRAYSIZE(szCertA);
DWORD dwEnabled;
BOOL fFound;
dwEnabled = _IsUsageEnabled(pCertContext, (LPSTR)pszEnhkeyUsage, &fFound);
// if not found, then continue with next
if (!fFound)
continue;
//ParseX509EncodedCertificateForListBoxEntry(pCertContext->pbCertEncoded, pCertContext->cbCertEncoded, szCert, &cbszCert);
ParseX509EncodedCertificateForListBoxEntry((BYTE *)pCertContext, -1, szCertA, &cbszCert);
#ifdef UNICODE
SHAnsiToUnicode(szCertA, szCert, ARRAYSIZE(szCert));
#else
StrCpy(szCert, szCertA);
#endif
LV_ITEM lvi = { 0 };
lvi.mask = LVIF_TEXT | LVIF_STATE | LVIF_PARAM;
lvi.iItem = -1;
lvi.pszText = szCert; // (LPSTR)pCertContext->pCertInfo->Subject.pbData;
lvi.cchTextMax = ARRAYSIZE(szCert); // pCertContext->pCertInfo->Subject.cbData;
lvi.stateMask = LVIS_STATEIMAGEMASK;
lvi.state = dwEnabled ? 0x00002000 : 0x00001000;
lvi.lParam = (LPARAM)CertDuplicateCertificateContext(pCertContext);
// insert and set state
ListView_SetItemState(pscdi->hwndList,
ListView_InsertItem(pscdi->hwndList, &lvi),
dwEnabled ? 0x00002000 : 0x00001000,
LVIS_STATEIMAGEMASK);
}
// show the items
ListView_RedrawItems(pscdi->hwndList, 0, ListView_GetItemCount(pscdi->hwndList));
}
return TRUE;
}
//////////////////////////////////////////////////////////////////////////
////
//// 08-Sep-1997: pberkman
////
//// PRIVATE function: _SiteCertAdjustProperties
////
//// based on what the user just checked/unchecked, set the
//// appropriate OID usage or remove it.
////
void _SiteCertAdjustProperties(LPSITECERTDIALOGINFO pscdi, NM_LISTVIEW *pListView)
{
DWORD_PTR dwSel;
char *pszOID;
DWORD cbUsage;
CERT_ENHKEY_USAGE *pUsage;
//
// if we are in the initdialog get out!
//
if (pscdi->fInitializing)
{
return;
}
//
// make sure we have the property set
//
dwSel = SendMessage(pscdi->hwndCombo, CB_GETCURSEL, 0, 0);
if (dwSel == CB_ERR)
{
return;
}
pszOID = (char*) SendMessage(pscdi->hwndCombo, CB_GETITEMDATA, (WPARAM)dwSel, 0);
if (!(pszOID) || ((DWORD_PTR)pszOID == CB_ERR))
{
return;
}
if (pListView->uNewState & 0x00001000) // unchecked
{
//
// the user unchecked one of the certs.
//
// 1. if there are no properties, add all others -- HACKHACK!
//
cbUsage = 0;
CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
NULL, &cbUsage);
if (cbUsage == 0)
{
// add all
__AddAllKnownEKU((PCCERT_CONTEXT)pListView->lParam);
// remove this one
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
}
else
{
if (!(pUsage = (CERT_ENHKEY_USAGE *)LocalAlloc(LPTR, cbUsage)))
{
return;
}
CertGetEnhancedKeyUsage((PCCERT_CONTEXT)pListView->lParam, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG,
pUsage, &cbUsage);
//
// 2. if there are properties.
// a. if this is the last known one, and it matches this, delete it and add the "disable"
//
if (pUsage->cUsageIdentifier == 1)
{
if (StrCmpA(pUsage->rgpszUsageIdentifier[0], pszOID) == 0)
{
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
}
}
else
{
//
// b. if there are more than one, just try to remove this one
//
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
}
LocalFree((void *)pUsage);
}
return;
}
if (pListView->uNewState & 0x00002000) // checked
{
CertAddEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam, pszOID);
//
// just in case, remove the disable!
//
CertRemoveEnhancedKeyUsageIdentifier((PCCERT_CONTEXT)pListView->lParam,
g_rgszEnhkeyUsage[EKU_DISABLE_OFF]);
}
}
BOOL SiteCert_OnNotify(LPSITECERTDIALOGINFO pscdi, WPARAM wParam, LPARAM lParam)
{
NM_LISTVIEW *pnmlv = (NM_LISTVIEW *)lParam;
switch (pnmlv->hdr.code) {
case LVN_ITEMCHANGED:
{
// check the current state of selection
int iSel = ListView_GetNextItem(pscdi->hwndList, -1, LVNI_SELECTED);
// check to see if we need to enable/disable the "DELETE" and "VIEW" buttons
EnableWindow(GetDlgItem(pscdi->hDlg, IDC_DELETECERT), iSel != -1);
EnableWindow(GetDlgItem(pscdi->hDlg, IDC_VIEWCERT), iSel != -1);
if ((pnmlv->uChanged & LVIF_STATE) && (GetFocus() == pscdi->hwndList))
{
_SiteCertAdjustProperties(pscdi, pnmlv);
}
break;
}
case LVN_DELETEITEM:
CertFreeCertificateContext((PCCERT_CONTEXT)pnmlv->lParam);
break;
}
return TRUE;
}
typedef struct tagNEWSITECERTINFO
{
LPVOID lpvCertData;
DWORD cbCert;
BOOL fCertEnabled;
BOOL fNetworkClient;
BOOL fNetworkServer;
BOOL fSecureEmail;
BOOL fSoftwarePublishing;
} NEWSITECERTINFO, *LPNEWSITECERTINFO;
BOOL NewSiteCert_AddCert(LPNEWSITECERTINFO pnsci)
{
HCERTSTORE hCertStore = NULL;
PCCERT_CONTEXT pCertContext;
BOOL fRet = FALSE;
hCertStore = CertOpenSystemStoreA(NULL, "ROOT");
if (hCertStore)
{
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
(LPBYTE)(pnsci->lpvCertData),
pnsci->cbCert);
if (pCertContext)
{
if (CertCompareCertificateName(X509_ASN_ENCODING,
&pCertContext->pCertInfo->Subject,
&pCertContext->pCertInfo->Issuer))
{
CertFreeCertificateContext(pCertContext);
fRet = CertAddEncodedCertificateToStore(hCertStore,
X509_ASN_ENCODING,
(LPBYTE)(pnsci->lpvCertData),
pnsci->cbCert,
CERT_STORE_ADD_REPLACE_EXISTING,
&pCertContext);
if (fRet)
{
# define l_USAGE_MAX 24
CERT_ENHKEY_USAGE ceku = {0};
LPSTR rgpszUsageIdentifier[l_USAGE_MAX];
if (pnsci->fNetworkClient)
{
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CLIENT_OFF];
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
ceku.cUsageIdentifier++;
}
if (pnsci->fNetworkServer)
{
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_SERVER_OFF];
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
ceku.cUsageIdentifier++;
}
if (pnsci->fSecureEmail)
{
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_EMAIL_OFF];
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
ceku.cUsageIdentifier++;
}
if (pnsci->fSoftwarePublishing)
{
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_CODESIGN_OFF];
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
ceku.cUsageIdentifier++;
}
if (!(pnsci->fCertEnabled))
{
// turn everything off!!!
rgpszUsageIdentifier[ceku.cUsageIdentifier] = g_rgszEnhkeyUsage[EKU_DISABLE_OFF];
if (rgpszUsageIdentifier[ceku.cUsageIdentifier])
ceku.cUsageIdentifier++;
}
//
// now, add any "unknown" extensions that the CA may have put on just
// so verification will succeed!
//
CERT_ENHKEY_USAGE *pUsage;
DWORD cbUsage;
DWORD i;
pUsage = NULL;
cbUsage = 0;
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbUsage);
if (cbUsage > 0)
{
if (pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage))
{
CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG,
pUsage, &cbUsage);
for (i = 0; i < pUsage->cUsageIdentifier; i++)
{
if (ceku.cUsageIdentifier >= l_USAGE_MAX)
{
break;
}
if (pUsage->rgpszUsageIdentifier[i])
{
if (!(_IsKnownUsage(pUsage->rgpszUsageIdentifier[i])))
{
rgpszUsageIdentifier[ceku.cUsageIdentifier] = pUsage->rgpszUsageIdentifier[i];
ceku.cUsageIdentifier++;
}
}
}
}
}
ceku.rgpszUsageIdentifier = (LPSTR *)rgpszUsageIdentifier;
fRet = CertSetEnhancedKeyUsage(pCertContext, &ceku);
if (pUsage)
{
LocalFree((void *)pUsage);
}
CertFreeCertificateContext(pCertContext);
}
}
}
CertCloseStore(hCertStore, CERT_CLOSE_STORE_CHECK_FLAG);
}
return fRet;
}
//////////////////////////////////////////////////////////////////////////
////
//// 15-Aug-1997: pberkman
////
//// PRIVATE function: NewSiteCert_SetAvailableAuthorityCheckboxes
////
//// set the check boxes in the "New Site Certificate" dialog box
//// based on the Authority Extensions and Properties.
////
//// if there are no Authority Ext or Prop's, then the certificate
//// has the potential for the user to enable for all. Otherwise,
//// the user can ONLY select the ones that the issuer (or MS) has
//// entrusted the certificate for.
////
typedef struct l_CERTUSAGES_
{
char *pszOID;
DWORD dwControlId;
BOOL fEnabled;
} l_CERTUSAGES;
BOOL NewSiteCert_SetAvailableAuthorityCheckboxes(HWND hDlg, LPNEWSITECERTINFO pnsci,
BOOL fInitialize)
{
l_CERTUSAGES asUsages[] =
{
szOID_PKIX_KP_CLIENT_AUTH, IDC_CHECK_NETWORK_CLIENT, FALSE,
szOID_PKIX_KP_SERVER_AUTH, IDC_CHECK_NETWORK_SERVER, FALSE,
szOID_PKIX_KP_EMAIL_PROTECTION, IDC_CHECK_SECURE_EMAIL, FALSE,
szOID_PKIX_KP_CODE_SIGNING, IDC_CHECK_SOFTWARE_PUBLISHING, FALSE,
NULL, 0, FALSE
};
l_CERTUSAGES *psUsages;
PCCERT_CONTEXT pCertContext;
DWORD cbUsage;
PCERT_ENHKEY_USAGE pUsage;
if (fInitialize)
{
CheckDlgButton(hDlg, IDC_CHECK_ENABLE_CERT, BST_CHECKED);
CheckDlgButton(hDlg, IDC_CHECK_NETWORK_CLIENT, BST_CHECKED);
CheckDlgButton(hDlg, IDC_CHECK_NETWORK_SERVER, BST_CHECKED);
CheckDlgButton(hDlg, IDC_CHECK_SECURE_EMAIL, BST_CHECKED);
CheckDlgButton(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING, BST_CHECKED);
}
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
(LPBYTE)(pnsci->lpvCertData),
pnsci->cbCert);
if (!(pCertContext))
{
psUsages = &asUsages[0];
while (psUsages->pszOID)
{
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
psUsages++;
}
return(FALSE);
}
cbUsage = 0;
CertGetEnhancedKeyUsage(pCertContext, 0, NULL, &cbUsage);
if (cbUsage < 1)
{
// none defined... leave all enabled.
CertFreeCertificateContext(pCertContext);
psUsages = &asUsages[0];
while (psUsages->pszOID)
{
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), TRUE);
psUsages++;
}
return(TRUE);
}
if (!(pUsage = (PCERT_ENHKEY_USAGE)LocalAlloc(LMEM_FIXED, cbUsage)))
{
CertFreeCertificateContext(pCertContext);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return(FALSE);
}
if (!(CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &cbUsage)))
{
CertFreeCertificateContext(pCertContext);
LocalFree(pUsage);
return(FALSE);
}
if (pUsage->cUsageIdentifier == 0)
{
CertFreeCertificateContext(pCertContext);
LocalFree(pUsage);
// none defined... leave all enabled.
return(TRUE);
}
CertFreeCertificateContext(pCertContext);
for (int i = 0; i < (int)pUsage->cUsageIdentifier; i++)
{
psUsages = &asUsages[0];
while (psUsages->pszOID)
{
if (StrCmpA(pUsage->rgpszUsageIdentifier[i], psUsages->pszOID) == 0)
{
psUsages->fEnabled = TRUE;
}
psUsages++;
}
}
LocalFree(pUsage);
psUsages = &asUsages[0];
while (psUsages->pszOID)
{
if (fInitialize)
{
CheckDlgButton(hDlg, psUsages->dwControlId,
(psUsages->fEnabled) ? BST_CHECKED : BST_UNCHECKED);
}
EnableWindow(GetDlgItem(hDlg, psUsages->dwControlId), psUsages->fEnabled);
psUsages++;
}
return(TRUE);
}
void NewSiteCert_CenterDialog(HWND hDlg)
{
RECT rcDlg;
RECT rcArea;
RECT rcCenter;
HWND hWndParent;
HWND hWndCenter;
DWORD dwStyle;
int w_Dlg;
int h_Dlg;
int xLeft;
int yTop;
GetWindowRect(hDlg, &rcDlg);
dwStyle = (DWORD)GetWindowLong(hDlg, GWL_STYLE);
if (dwStyle & WS_CHILD)
{
hWndCenter = GetParent(hDlg);
hWndParent = GetParent(hDlg);
GetClientRect(hWndParent, &rcArea);
GetClientRect(hWndCenter, &rcCenter);
MapWindowPoints(hWndCenter, hWndParent, (POINT *)&rcCenter, 2);
}
else
{
hWndCenter = GetWindow(hDlg, GW_OWNER);
if (hWndCenter)
{
dwStyle = (DWORD)GetWindowLong(hWndCenter, GWL_STYLE);
if (!(dwStyle & WS_VISIBLE) || (dwStyle & WS_MINIMIZE))
{
hWndCenter = NULL;
}
}
SystemParametersInfo(SPI_GETWORKAREA, NULL, &rcArea, NULL);
if (hWndCenter)
{
GetWindowRect(hWndCenter, &rcCenter);
}
else
{
rcCenter = rcArea;
}
}
w_Dlg = rcDlg.right - rcDlg.left;
h_Dlg = rcDlg.bottom - rcDlg.top;
xLeft = (rcCenter.left + rcCenter.right) / 2 - w_Dlg / 2;
yTop = (rcCenter.top + rcCenter.bottom) / 2 - h_Dlg / 2;
if (xLeft < rcArea.left)
{
xLeft = rcArea.left;
}
else if ((xLeft + w_Dlg) > rcArea.right)
{
xLeft = rcArea.right - w_Dlg;
}
if (yTop < rcArea.top)
{
yTop = rcArea.top;
}
else if ((yTop + h_Dlg) > rcArea.bottom)
{
yTop = rcArea.bottom - h_Dlg;
}
SetWindowPos(hDlg, NULL, xLeft, yTop, -1, -1, SWP_NOZORDER | SWP_NOSIZE | SWP_NOACTIVATE);
}
INT_PTR CALLBACK NewSiteCert_DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
LPNEWSITECERTINFO pnsci = (LPNEWSITECERTINFO)GetWindowLongPtr(hDlg, DWLP_USER);
switch (uMsg) {
case WM_INITDIALOG:
{
DWORD dwFileSize;
DWORD cbRead;
HANDLE hf;
LPTSTR lpszCmdLine = (LPTSTR)lParam;
DWORD dwError;
hf = CreateFile(lpszCmdLine, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hf == INVALID_HANDLE_VALUE)
{
dwError = GetLastError();
goto initError;
}
dwFileSize = GetFileSize(hf, NULL);
if (dwFileSize == (unsigned)-1)
goto initError;
pnsci = (LPNEWSITECERTINFO)LocalAlloc(LPTR, sizeof(*pnsci));
if (!pnsci)
goto initError;
pnsci->lpvCertData = LocalAlloc(LPTR, dwFileSize);
if (!pnsci->lpvCertData)
goto initError;
pnsci->cbCert = dwFileSize;
if (!ReadFile(hf, pnsci->lpvCertData, dwFileSize, &cbRead, NULL) || cbRead != dwFileSize)
goto initError;
SetWindowLongPtr(hDlg, DWLP_USER, (LPARAM)pnsci); // save pointer to cert
//
// ok check to make sure that 1) it's a cert file and 2) it's a root!
//
PCCERT_CONTEXT pCertContext;
dwError = S_FALSE;
pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING,
(LPBYTE)(pnsci->lpvCertData),
pnsci->cbCert);
if (pCertContext)
{
if (CertCompareCertificateName(X509_ASN_ENCODING,
&pCertContext->pCertInfo->Subject,
&pCertContext->pCertInfo->Issuer))
{
dwError = S_OK;
}
CertFreeCertificateContext(pCertContext);
}
if (dwError != S_OK)
{
goto initError;
}
NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, TRUE);
NewSiteCert_CenterDialog(hDlg);
break;
initError:
TCHAR szTitle[MAX_PATH + 1];
TCHAR szError[MAX_PATH + 1];
MLLoadShellLangString(IDS_CERT_FILE_INVALID, &szError[0], MAX_PATH);
MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
EndDialog(hDlg, IDCANCEL);
return FALSE;
}
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDOK:
{
pnsci->fCertEnabled = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
pnsci->fNetworkClient = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_CLIENT);
pnsci->fNetworkServer = IsDlgButtonChecked(hDlg, IDC_CHECK_NETWORK_SERVER);
pnsci->fSecureEmail = IsDlgButtonChecked(hDlg, IDC_CHECK_SECURE_EMAIL);
pnsci->fSoftwarePublishing = IsDlgButtonChecked(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING);
NewSiteCert_AddCert(pnsci);
EndDialog(hDlg, IDOK);
break;
}
case IDCANCEL:
EndDialog(hDlg, IDCANCEL);
break;
case IDC_VIEWCERT:
ShowX509EncodedCertificate(hDlg, (LPBYTE)pnsci->lpvCertData, pnsci->cbCert);
break;
case IDC_CHECK_ENABLE_CERT:
if (HIWORD(wParam) == BN_CLICKED)
{
BOOL fEnableCert;
fEnableCert = IsDlgButtonChecked(hDlg, IDC_CHECK_ENABLE_CERT);
if (!(fEnableCert))
{
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_CLIENT), fEnableCert);
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_NETWORK_SERVER), fEnableCert);
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SECURE_EMAIL), fEnableCert);
EnableWindow(GetDlgItem(hDlg, IDC_CHECK_SOFTWARE_PUBLISHING), fEnableCert);
}
else
{
NewSiteCert_SetAvailableAuthorityCheckboxes(hDlg, pnsci, FALSE);
}
}
return(FALSE);
default:
return FALSE;
}
return TRUE;
break;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_DESTROY:
if (pnsci)
{
if (pnsci->lpvCertData)
LocalFree(pnsci->lpvCertData);
LocalFree(pnsci);
}
break;
}
return FALSE;
}
STDAPI SiteCert_RunFromCmdLine(HINSTANCE hinst, HINSTANCE hPrevInstance, LPTSTR lpszCmdLine, int nCmdShow)
{
if ((!lpszCmdLine) || (*lpszCmdLine == TEXT('\0')))
return -1;
DialogBoxParam(MLGetHinst(), MAKEINTRESOURCE(IDD_NEWSITECERT),
NULL, NewSiteCert_DlgProc, (LPARAM)lpszCmdLine);
return 0;
}
// Helper function for ExportPFX
#define NUM_KNOWN_STORES 5
BOOL OpenAndAllocKnownStores(DWORD *pchStores, HCERTSTORE **ppahStores)
{
HCERTSTORE hStore;
int i;
static const LPCTSTR rszStoreNames[NUM_KNOWN_STORES] = {
TEXT("ROOT"),
TEXT("TRUST"),
TEXT("CA"),
TEXT("MY"),
TEXT("SPC")
};
*pchStores = 0;
if (NULL == ((*ppahStores) = (HCERTSTORE *) LocalAlloc(LPTR, sizeof(HCERTSTORE) * NUM_KNOWN_STORES)))
{
return (FALSE);
}
for (i=0; i< NUM_KNOWN_STORES; i++)
{
(*ppahStores)[i] = NULL;
if (hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
0,
0,
CERT_SYSTEM_STORE_CURRENT_USER |
CERT_STORE_READONLY_FLAG |
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
rszStoreNames[i]))
(*ppahStores)[(*pchStores)++] = hStore;
}
return(TRUE);
}
// Helper function for ExportPFX
void CloseAndFreeKnownStores(HCERTSTORE *pahStores)
{
int i;
for (i=0; i<NUM_KNOWN_STORES; i++)
{
if (pahStores[i] != NULL)
{
CertCloseStore(pahStores[i], 0);
}
}
LocalFree(pahStores);
}
enum {PFX_IMPORT, PFX_EXPORT};
typedef struct
{
HWND hDlg; // handle to window
DWORD dwImportExport; // import or export?
BOOL fUseExisting; // use existing cert if collision on import
PCCERT_CONTEXT pCertContext; // context to export or NULL
LPWSTR pwszPassword; // password for import/export
LPWSTR pwszPassword2; // prompt user twice on exports!
LPTSTR pszPath; // file for import/export
} IMPORTEXPORT, *LPIMPORTEXPORT;
#define MAX_PASSWORD 32
// CreateCertFile: change working directory to "MyDocs", do CreateFile, restore old working directory
HANDLE CreateCertFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
TCHAR szOldDir[MAX_PATH];
TCHAR szCertDir[MAX_PATH];
HANDLE hFile;
LPITEMIDLIST pidl;
GetCurrentDirectory(ARRAYSIZE(szOldDir), szOldDir);
if (SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &pidl) == NOERROR)
{
SHGetPathFromIDList(pidl, szCertDir);
SetCurrentDirectory(szCertDir);
ILFree(pidl);
}
hFile = CreateFile(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDistribution, dwFlagsAndAttributes, hTemplateFile);
SetCurrentDirectory(szOldDir);
return hFile;
}
//////////////////////////////////////////////////////////////////////////
//
// 09-Sep-1997 pberkman:
// determine if the exact cert is in the passed store
//
BOOL __IsCertInStore(PCCERT_CONTEXT pCertContext, HCERTSTORE hStore)
{
//
// can't do it the fast way -- do it the slow way!
//
BYTE *pbHash;
DWORD cbHash;
CRYPT_HASH_BLOB sBlob;
PCCERT_CONTEXT pWorkContext;
cbHash = 0;
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
{
return(FALSE);
}
if (cbHash < 1)
{
return(FALSE);
}
if (!(pbHash = new BYTE[cbHash]))
{
return(FALSE);
}
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
{
delete pbHash;
return(FALSE);
}
sBlob.cbData = cbHash;
sBlob.pbData = pbHash;
pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
CERT_FIND_SHA1_HASH, &sBlob, NULL);
delete pbHash;
if (pWorkContext)
{
CertFreeCertificateContext(pWorkContext);
return(TRUE);
}
return(FALSE);
}
//////////////////////////////////////////////////////////////////////////
//
// 09-Sep-1997 pberkman:
// importing a cert from a file.
//
BOOL ImportPFX(LPIMPORTEXPORT pImp)
{
# define MY_STORE 0
# define CA_STORE 1
# define ROOT_STORE 2
# define MAX_STORE 3
HCERTSTORE pahStores[MAX_STORE];
HCERTSTORE hCertStore;
BOOL fAdded;
DWORD dwAddFlags;
HANDLE hFile;
CRYPT_DATA_BLOB sData;
BOOL fRet;
PCCERT_CONTEXT pCertCtxt;
DWORD cbRead;
DWORD dwImportFlags;
int i;
fRet = FALSE;
dwImportFlags = CRYPT_EXPORTABLE;
pCertCtxt = NULL;
hCertStore = NULL;
for (i = 0; i < MAX_STORE; i++)
{
pahStores[i] = NULL;
}
ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
hFile = CreateCertFile(pImp->pszPath, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
goto Cleanup;
}
dwAddFlags = (pImp->fUseExisting) ? CERT_STORE_ADD_USE_EXISTING :
CERT_STORE_ADD_REPLACE_EXISTING;
sData.cbData = GetFileSize(hFile, NULL);
sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
if (!(sData.pbData))
{
goto Cleanup;
}
if (!(ReadFile(hFile, sData.pbData, sData.cbData, &cbRead, NULL)))
{
goto Cleanup;
}
if ((pImp->pwszPassword) && (!(*pImp->pwszPassword))) // if no password, use null.
{
pImp->pwszPassword = NULL;
}
if (!(hCertStore = PFXImportCertStore(&sData, pImp->pwszPassword, dwImportFlags)))
{
goto Cleanup;
}
//
// now we have in memory hStore enumerate the cert contexts
// and drop them into destination store
//
if (!(pahStores[MY_STORE] = CertOpenSystemStoreA(NULL, "MY")) ||
!(pahStores[CA_STORE] = CertOpenSystemStoreA(NULL, "CA")) ||
!(pahStores[ROOT_STORE] = CertOpenSystemStoreA(NULL, "ROOT")))
{
goto Cleanup;
}
while (pCertCtxt = CertEnumCertificatesInStore(hCertStore, pCertCtxt))
{
fAdded = FALSE;
cbRead = 0;
CertGetCertificateContextProperty(pCertCtxt, CERT_KEY_PROV_INFO_PROP_ID, NULL, &cbRead);
if (cbRead > 0) // pfx added a public key prop
{
CertAddCertificateContextToStore(pahStores[MY_STORE], pCertCtxt, dwAddFlags, NULL);
continue;
}
//
// first, check if we already have this cert in one of our stores
//
for (i = 0; i < MAX_STORE; i++)
{
if (__IsCertInStore(pCertCtxt, pahStores[i]))
{
//
// the same cert, exactly, is already in one of our stores!
//
fAdded = TRUE;
break;
}
}
if (!(fAdded))
{
CertAddCertificateContextToStore(pahStores[CA_STORE], pCertCtxt, dwAddFlags, NULL);
}
}
fRet = TRUE;
Cleanup:
if (sData.pbData)
{
LocalFree(sData.pbData);
}
if (hFile != INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
if (hCertStore)
{
CertCloseStore(hCertStore, 0);
}
for (i = 0; i < MAX_STORE; i++)
{
if (pahStores[i])
{
CertCloseStore(pahStores[i], 0);
}
}
return(fRet);
}
typedef PCCERT_CONTEXT (* PFNWTHELPER) (PCCERT_CONTEXT /* pChildContext */,
DWORD /* chStores */,
HCERTSTORE * /* pahStores */,
FILETIME * /* psftVerifyAsOf*/,
DWORD /* dwEncoding */,
DWORD * /* pdwConfidence */,
DWORD * /* pdwError */ );
BOOL ExportPFX(LPIMPORTEXPORT pImp)
{
BOOL fRet = FALSE;
HANDLE hFile = NULL;
CRYPT_DATA_BLOB sData;
DWORD cbRead;
HCERTSTORE hSrcCertStore;
DWORD dwExportFlags = 4; // 4 == EXPORT_PRIVATE_KEYS;
TCHAR szText[MAX_PATH], szTitle[80];
PCCERT_CONTEXT pTempCertContext;
HCERTSTORE *phCertStores = NULL;
DWORD chCertStores = 0;
DWORD dwConfidence;
DWORD dwError;
HINSTANCE hiWintrust = NULL;
PFNWTHELPER WTHelperCertFindIssuerCertificate;
if (!pImp->pCertContext)
return FALSE;
ZeroMemory(&sData, sizeof(CRYPT_DATA_BLOB));
// create an in memory store
hSrcCertStore = CertOpenStore(CERT_STORE_PROV_MEMORY,
PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
0,
0,
NULL);
if (!CertAddCertificateContextToStore(hSrcCertStore, pImp->pCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL))
goto Cleanup;
// Load helper function from wintrust.dll
hiWintrust = LoadLibrary(TEXT("WINTRUST.DLL"));
WTHelperCertFindIssuerCertificate = (PFNWTHELPER) GetProcAddress(hiWintrust,"WTHelperCertFindIssuerCertificate");
if (WTHelperCertFindIssuerCertificate)
{
// Load all the top level stores, so we can export from them if necessary
if (OpenAndAllocKnownStores(&chCertStores, &phCertStores))
{
// Find the intermediate certifcates, and add them to the store that we will be exporting
pTempCertContext = pImp->pCertContext;
while (NULL != ( pTempCertContext = WTHelperCertFindIssuerCertificate(pTempCertContext,
chCertStores,
phCertStores,
NULL,
X509_ASN_ENCODING,
&dwConfidence,
&dwError)))
{
CertAddCertificateContextToStore(hSrcCertStore, pTempCertContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
// Break out if we find a root (self-signed) cert
if (CertCompareCertificateName(X509_ASN_ENCODING,
&pTempCertContext->pCertInfo->Subject,
&pTempCertContext->pCertInfo->Issuer))
break;
}
CloseAndFreeKnownStores(phCertStores);
}
}
//
// This first call simply gets the size of the crypt blob
//
if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
{
goto Cleanup;
}
// Alloc based on cbData
sData.pbData = (PBYTE)LocalAlloc(LMEM_FIXED, sData.cbData);
//
// Now actually get the data
//
if (!(*pImp->pwszPassword)) // no password use null
pImp->pwszPassword = NULL;
if (!PFXExportCertStore(hSrcCertStore, &sData, pImp->pwszPassword, dwExportFlags))
{
goto Cleanup;
}
// Open the PFX file
hFile = CreateCertFile(pImp->pszPath,
GENERIC_WRITE,
FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
goto Cleanup;
}
// Write to it
if (!WriteFile(hFile,
sData.pbData,
sData.cbData,
&cbRead,
NULL)) {
goto Cleanup;
}
// Display message about certs exporting OK.
MLLoadShellLangString(IDS_CERT_EXPORTOKTEXT, szText, ARRAYSIZE(szText));
MLLoadShellLangString(IDS_CERT_EXPORTOKTITLE, szTitle, ARRAYSIZE(szTitle));
MessageBox(pImp->hDlg, szText, szTitle, MB_ICONINFORMATION | MB_OK);
fRet = TRUE;
Cleanup:
if (hiWintrust)
FreeLibrary(hiWintrust);
if (hSrcCertStore)
CertCloseStore(hSrcCertStore, 0);
if (hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
if (sData.pbData)
LocalFree(sData.pbData);
return fRet;
}
INT_PTR CALLBACK ImportExportDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
{
LPIMPORTEXPORT pImp;
if (uMsg == WM_INITDIALOG)
{
pImp = (LPIMPORTEXPORT)lParam; // this is passed in to us
if (!pImp)
{
EndDialog(hDlg, 0);
return FALSE;
}
// tell dialog where to get info
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)pImp);
// save handle to the page
pImp->hDlg = hDlg;
// limit the password to 32 chars
SendMessage(GetDlgItem(hDlg, IDC_PASSWORD), EM_LIMITTEXT, MAX_PASSWORD, 0);
//
// 03-Oct-1997 pberkman: always verify password!
//
if (pImp->dwImportExport == PFX_EXPORT)
{
SendMessage(GetDlgItem(hDlg, IDC_PASSWORD2), EM_LIMITTEXT, MAX_PASSWORD, 0);
}
SHAutoComplete(GetDlgItem(hDlg, IDC_FILENAME), SHACF_DEFAULT); // This control exists in both IDD_PFX_IMPORT and IDD_PFX_EXPORT
// only set these on import, since they don't exist on export =)
// =========================================================================
// 03-Oct-1997 pberkman: no user decisions!
//
// if (pImp->dwImportExport == PFX_IMPORT)
// {
// CheckRadioButton(hDlg, IDC_USE_EXISTING, IDC_USE_FILE, IDC_USE_EXISTING);
// }
// ==========================================================================
SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
} // WM_INITDIALOG
else
pImp = (LPIMPORTEXPORT)GetWindowLongPtr(hDlg, DWLP_USER);
if (!pImp)
return FALSE;
switch (uMsg)
{
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_CERT_BROWSE:
{
TCHAR szFilenameBrowse[MAX_PATH];
TCHAR szExt[MAX_PATH];
TCHAR szFilter[MAX_PATH];
int ret;
LPITEMIDLIST pidl;
TCHAR szWorkingDir[MAX_PATH];
szFilenameBrowse[0] = 0;
MLLoadString(IDS_PFX_EXT, szExt, ARRAYSIZE(szExt));
int cchFilter = MLLoadString(IDS_PFX_FILTER, szFilter, ARRAYSIZE(szFilter)-1);
// Make sure we have a double null termination on the filter
szFilter[cchFilter + 1] = 0;
if (SHGetSpecialFolderLocation(hDlg, CSIDL_PERSONAL, &pidl) == NOERROR)
{
SHGetPathFromIDList(pidl, szWorkingDir);
ILFree(pidl);
}
ret = _AorW_GetFileNameFromBrowse(hDlg, szFilenameBrowse, ARRAYSIZE(szFilenameBrowse), szWorkingDir,
szExt, szFilter, NULL);
if (ret > 0)
{
SetDlgItemText(hDlg, IDC_FILENAME, szFilenameBrowse);
}
break;
}
case IDOK:
{
TCHAR szPassword[MAX_PASSWORD];
TCHAR szPassword2[MAX_PASSWORD];
TCHAR szPath[MAX_PATH];
BOOL bRet;
szPassword[0] = NULL;
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD), szPassword, ARRAYSIZE(szPassword));
GetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath, ARRAYSIZE(szPath));
//
// 03-Oct-1997 pberkman: always double check password!
//
if (pImp->dwImportExport == PFX_EXPORT)
{
szPassword2[0] = NULL;
GetWindowText(GetDlgItem(hDlg, IDC_PASSWORD2), szPassword2, ARRAYSIZE(szPassword2));
if (StrCmp(szPassword, szPassword2) != 0)
{
TCHAR szTitle[MAX_PATH + 1];
TCHAR szError[MAX_PATH + 1];
MLLoadShellLangString(IDS_PASSWORDS_NOMATCH, &szError[0], MAX_PATH);
MLLoadShellLangString(IDS_ERROR, &szTitle[0], MAX_PATH);
MessageBox(GetFocus(), &szError[0], &szTitle[0], MB_OK | MB_ICONERROR);
SetFocus(GetDlgItem(hDlg, IDC_PASSWORD));
break;
}
}
// Add a default extension on export
if (pImp->dwImportExport == PFX_EXPORT)
if (szPath[0] != TEXT('\0') && PathAddExtension(szPath, TEXT(".PFX")))
SetWindowText(GetDlgItem(hDlg, IDC_FILENAME), szPath);
#ifndef UNICODE
WCHAR wszPassword[MAX_PASSWORD];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, szPassword, -1, wszPassword, ARRAYSIZE(wszPassword));
pImp->pwszPassword = wszPassword;
#else
pImp->pwszPassword = szPassword;
#endif
pImp->pszPath = szPath;
if (pImp->dwImportExport == PFX_IMPORT)
{
// =========================================================================
// 03-Oct-1997 pberkman: no user decisions!
//
// pImp->fUseExisting = IsDlgButtonChecked(hDlg, IDC_USE_EXISTING);
// =========================================================================
pImp->fUseExisting = FALSE;
bRet = ImportPFX(pImp);
if (!(bRet) && (GetLastError() == NTE_BAD_DATA))
{
// message....
}
}
else
{
bRet = ExportPFX(pImp);
}
EndDialog(hDlg, bRet);
break;
}
case IDCANCEL:
EndDialog(hDlg, TRUE); // Cancel is not an error
break;
}
break;
case WM_NOTIFY:
break;
// No context sensitive help yet...
#if 0
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
#endif
case WM_DESTROY:
SetWindowLongPtr(hDlg, DWLP_USER, (LONG_PTR)NULL);
break;
}
return FALSE;
}
#ifdef UNIX
EXTERN_C
#endif
INT_PTR ImportExportPFX(HWND hwndParent, DWORD dwImportExport, LPBYTE pbCert, DWORD cbCert)
{
IMPORTEXPORT imp;
if (pbCert)
{
CRYPT_HASH_BLOB hashBlob;
HCERTSTORE hMy = CertOpenSystemStoreA(NULL, "MY");
DWORD cbSHA1Hash;
LPBYTE pbSHA1Hash;
if (!hMy)
return FALSE;
if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, NULL, &cbSHA1Hash))
{
pbSHA1Hash = (LPBYTE)LocalAlloc(LPTR, cbSHA1Hash);
if (!pbSHA1Hash)
return FALSE;
if (CryptHashCertificate(NULL, 0, 0, pbCert, cbCert, pbSHA1Hash, &cbSHA1Hash))
{
hashBlob.cbData = cbSHA1Hash;
hashBlob.pbData = pbSHA1Hash;
imp.pCertContext = CertFindCertificateInStore(hMy, X509_ASN_ENCODING, 0, CERT_FIND_HASH, &hashBlob, NULL);
if (!(imp.pCertContext))
return FALSE;
}
LocalFree(pbSHA1Hash);
}
CertCloseStore(hMy, 0);
}
imp.dwImportExport = dwImportExport;
return DialogBoxParam(MLGetHinst(),
dwImportExport == PFX_IMPORT ? MAKEINTRESOURCE(IDD_PFX_IMPORT) : MAKEINTRESOURCE(IDD_PFX_EXPORT),
hwndParent, ImportExportDlgProc, (LPARAM)&imp);
}
//BUBUG: The following function should be rermoved when we have updated our Crypto API to latest
BOOL WINAPI WTHelperIsInRootStore(PCCERT_CONTEXT pCertContext)
{
HCERTSTORE hStore;
if (!(hStore = CertOpenStore( CERT_STORE_PROV_SYSTEM_A,
0,
NULL,
CERT_SYSTEM_STORE_CURRENT_USER |
CERT_STORE_READONLY_FLAG |
CERT_STORE_NO_CRYPT_RELEASE_FLAG,
"ROOT")))
{
return(FALSE);
}
//
// can't do it the fast way -- do it the slow way!
//
BYTE *pbHash;
DWORD cbHash;
CRYPT_HASH_BLOB sBlob;
PCCERT_CONTEXT pWorkContext;
cbHash = 0;
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, NULL, &cbHash)))
{
CertCloseStore(hStore, 0);
return(FALSE);
}
if (cbHash < 1)
{
CertCloseStore(hStore, 0);
return(FALSE);
}
if (!(pbHash = new BYTE[cbHash]))
{
CertCloseStore(hStore, 0);
return(FALSE);
}
if (!(CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, pbHash, &cbHash)))
{
delete pbHash;
CertCloseStore(hStore, 0);
return(FALSE);
}
sBlob.cbData = cbHash;
sBlob.pbData = pbHash;
pWorkContext = CertFindCertificateInStore(hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0,
CERT_FIND_SHA1_HASH, &sBlob, NULL);
delete pbHash;
if (pWorkContext)
{
CertFreeCertificateContext(pWorkContext);
CertCloseStore(hStore, 0);
return(TRUE);
}
CertCloseStore(hStore, 0);
return(FALSE);
}
//============================================================================
const TCHAR c_szRegKeySMIEM[] = TEXT("Software\\Microsoft\\Internet Explorer\\Main");
const TCHAR c_szRegValFormSuggest[] = TEXT("Use FormSuggest");
const TCHAR c_szRegValFormSuggestPW[] = TEXT("FormSuggest Passwords");
const TCHAR c_szRegValFormSuggestPWAsk[] = TEXT("FormSuggest PW Ask");
const TCHAR c_szYes[] = TEXT("yes");
const TCHAR c_szNo[] = TEXT("no");
inline void SetValueHelper(HWND hDlg, int id, LPTSTR *ppszData, DWORD *pcbData)
{
if (IsDlgButtonChecked(hDlg, id))
{
*ppszData = (LPTSTR)c_szYes;
*pcbData = sizeof(c_szYes);
}
else
{
*ppszData = (LPTSTR)c_szNo;
*pcbData = sizeof(c_szNo);
}
}
INT_PTR CALLBACK AutoSuggestDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEADDR,
(SHRegGetBoolUSValue(REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST, FALSE, /*default:*/TRUE)) ?
BST_CHECKED : BST_UNCHECKED);
if (g_restrict.fFormSuggest)
{
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, FALSE);
}
else
{
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_ENABLEFORM,
(SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggest, FALSE, /*default:*/FALSE)) ?
BST_CHECKED : BST_UNCHECKED);
}
if (g_restrict.fFormPasswords)
{
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, FALSE);
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
}
else
{
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
(SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk, FALSE, /*default:*/TRUE)) ?
BST_CHECKED : BST_UNCHECKED);
if (SHRegGetBoolUSValue(c_szRegKeySMIEM, c_szRegValFormSuggestPW, FALSE, /*default:*/TRUE))
{
CheckDlgButton(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, BST_CHECKED);
}
else
{
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, FALSE);
}
}
}
return TRUE;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_AUTOSUGGEST_SAVEPASSWORDS:
EnableDlgItem(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS,
IsDlgButtonChecked(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS));
break;
case IDC_AUTOSUGGEST_CLEARFORM:
case IDC_AUTOSUGGEST_CLEARPASSWORDS:
{
BOOL fPasswords = (LOWORD(wParam) == IDC_AUTOSUGGEST_CLEARPASSWORDS);
DWORD dwClear = (fPasswords) ?
IECMDID_ARG_CLEAR_FORMS_PASSWORDS_ONLY : IECMDID_ARG_CLEAR_FORMS_ALL_BUT_PASSWORDS;
if (IDOK == MsgBox(hDlg, ((fPasswords) ? IDS_CLEAR_FORMPASSWORDS : IDS_CLEAR_FORMSUGGEST), MB_ICONQUESTION, MB_OKCANCEL))
{
HCURSOR hOldCursor = NULL;
HCURSOR hNewCursor = NULL;
#ifndef UNIX
hNewCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_WAIT));
#else
// IEUNIX - Getting rid of redundant MAKEINTRESOURCE
hNewCursor = LoadCursor(NULL, IDC_WAIT);
#endif
if (hNewCursor)
hOldCursor = SetCursor(hNewCursor);
// Clear all strings
ClearAutoSuggestForForms(dwClear);
// Also reset profile assistant sharing (very discoverable here)
if (!g_restrict.fProfiles)
{
ResetProfileSharing(hDlg);
}
if(hOldCursor)
SetCursor(hOldCursor);
}
}
break;
case IDOK:
{
DWORD cbData; LPTSTR pszData;
SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEADDR, &pszData, &cbData);
SHSetValue(HKEY_CURRENT_USER, REGSTR_PATH_AUTOCOMPLETE, REGSTR_VAL_USEAUTOSUGGEST,
REG_SZ, pszData, cbData);
if (!g_restrict.fFormSuggest)
{
SetValueHelper(hDlg, IDC_AUTOSUGGEST_ENABLEFORM, &pszData, &cbData);
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggest,
REG_SZ, pszData, cbData);
}
if (!g_restrict.fFormPasswords)
{
SetValueHelper(hDlg, IDC_AUTOSUGGEST_SAVEPASSWORDS, &pszData, &cbData);
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPW,
REG_SZ, pszData, cbData);
SetValueHelper(hDlg, IDC_AUTOSUGGEST_PROMPTPASSWORDS, &pszData, &cbData);
SHSetValue(HKEY_CURRENT_USER, c_szRegKeySMIEM, c_szRegValFormSuggestPWAsk,
REG_SZ, pszData, cbData);
}
}
// fall through
case IDCANCEL:
{
EndDialog(hDlg, LOWORD(wParam));
}
break;
}
}
return TRUE;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_DESTROY:
break;
}
return FALSE;
}
#ifdef WALLET
// This intermediate dialog is only displayed for wallet 2.x users
INT_PTR CALLBACK WalletDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
{
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_PAYBUTTON, IsWalletPaymentAvailable());
EnableDlgItem(hDlg, IDC_PROGRAMS_WALLET_ADDRBUTTON, IsWalletAddressAvailable());
}
return TRUE;
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_PROGRAMS_WALLET_PAYBUTTON:
DisplayWalletPaymentDialog(hDlg);
break;
case IDC_PROGRAMS_WALLET_ADDRBUTTON:
DisplayWalletAddressDialog(hDlg);
break;
case IDOK:
case IDCANCEL:
{
EndDialog(hDlg, LOWORD(wParam));
}
break;
}
}
return TRUE;
case WM_HELP: // F1
ResWinHelp( (HWND)((LPHELPINFO)lParam)->hItemHandle, IDS_HELPFILE,
HELP_WM_HELP, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_CONTEXTMENU: // right mouse click
ResWinHelp( (HWND) wParam, IDS_HELPFILE,
HELP_CONTEXTMENU, (DWORD_PTR)(LPSTR)mapIDCsToIDHs);
break;
case WM_DESTROY:
break;
}
return FALSE;
}
#endif