|
|
//*********************************************************************
//* 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
|