|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: property.cpp
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
#include <wininet.h>
#include <crypthlp.h> //DSIE: For XCERT_MIN_SYNC_DELTA_TIME and
// XCERT_MIN_SYNC_DELTA_TIME
extern HINSTANCE HinstDll; extern HMODULE HmodRichEdit;
static const HELPMAP helpmapGeneral[] = { {IDC_CERTIFICATE_NAME, IDH_CERTPROPERTIES_CERTIFICATENAME}, {IDC_DESCRIPTION, IDH_CERTPROPERTIES_DESCRIPTION}, {IDC_KEY_USAGE_LIST, IDH_CERTPROPERTIES_USAGE_LIST}, {IDC_PROPERTY_NEWOID, IDH_CERTPROPERTIES_ADDPURPOSE_BUTTON}, {IDC_ENABLE_ALL_RADIO, IDH_CERTPROPERTIES_ENABLE_ALL_RADIO}, {IDC_DISABLE_ALL_RADIO, IDH_CERTPROPERTIES_DISABLE_ALL_RADIO}, {IDC_ENABLE_SELECT_RADIO, IDH_CERTPROPERTIES_ENABLE_CUSTOM_RADIO} };
static const HELPMAP helpmapCrossCert[] = { {IDC_CHECKFORNEWCERTS_CHECK, IDH_CHECKFORNEWCERTS_CHECK}, {IDC_NUMBEROFUNITS_EDIT, IDH_NUMBEROFUNITS_EDIT}, {IDC_UNITS_COMBO, IDH_UNITS_COMBO}, {IDC_USE_DEFAULT_BUTTON, IDH_USE_DEFAULT_BUTTON}, {IDC_ADDURL_BUTTON, IDH_ADDURL_BUTTON}, {IDC_NEWURL_EDIT, IDH_NEWURL_EDIT}, {IDC_URL_LIST, IDH_URL_LIST}, {IDC_REMOVEURL_BUTTON, IDH_REMOVEURL_BUTTON} };
#define MY_CHECK_STATE_CHECKED (INDEXTOSTATEIMAGEMASK(1))
#define MY_CHECK_STATE_UNCHECKED (INDEXTOSTATEIMAGEMASK(2))
#define MY_CHECK_STATE_CHECKED_GRAYED (INDEXTOSTATEIMAGEMASK(3))
#define MY_CHECK_STATE_UNCHECKED_GRAYED (INDEXTOSTATEIMAGEMASK(4))
#define PROPERTY_STATE_ALL_ENABLED 1
#define PROPERTY_STATE_ALL_DISABLED 2
#define PROPERTY_STATE_SELECT 3
typedef struct { LPSTR pszOID; DWORD initialState; } SETPROPERTIES_HELPER_STRUCT, *PSETPROPERTIES_HELPER_STRUCT;
//DSIE: Bug 154609
#define XCERT_DEFAULT_DELTA_HOURS (XCERT_DEFAULT_SYNC_DELTA_TIME / (60 * 60)) // Default interval is 8 hours.
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
INT_PTR APIENTRY NewOIDDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { DWORD i; char szText[256]; WCHAR errorString[CRYPTUI_MAX_STRING_SIZE]; WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE]; LPSTR pszText = NULL;
switch ( msg ) {
case WM_INITDIALOG:
SendDlgItemMessage(hwndDlg, IDC_EDIT1, EM_EXLIMITTEXT, 0, (LPARAM) 255); SetDlgItemTextU(hwndDlg, IDC_EDIT1, L""); SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1)); break;
case WM_COMMAND: switch (LOWORD(wParam)) {
case IDOK: if (GetDlgItemTextA( hwndDlg, IDC_EDIT1, szText, ARRAYSIZE(szText))) { BOOL fError = FALSE; CERT_ENHKEY_USAGE KeyUsage; DWORD cbData = 0; LPSTR pszCheckOID;
//
// make sure there are not weird characters
//
for (i=0; i<(DWORD)strlen(szText); i++) { if (((szText[i] < '0') || (szText[i] > '9')) && (szText[i] != '.')) { fError = TRUE; break; } }
//
// check the first and last chars, and for the empty string
//
if (!fError) { if ((szText[0] == '.') || (szText[strlen(szText)-1] == '.') || (strcmp(szText, "") == 0)) { fError = TRUE; } }
//
// finally, make sure that it encodes properly
//
if (!fError) { pszCheckOID = szText; KeyUsage.rgpszUsageIdentifier = &pszCheckOID; KeyUsage.cUsageIdentifier = 1;
if (!CryptEncodeObject( X509_ASN_ENCODING, szOID_ENHANCED_KEY_USAGE, &KeyUsage, NULL, &cbData)) { fError = TRUE; } }
//
// if an error has occurred then display error
//
if (fError) { LoadStringU(HinstDll, IDS_ERRORINOID, errorString, ARRAYSIZE(errorString)); LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle, ARRAYSIZE(errorTitle)); MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONERROR); SendDlgItemMessage(hwndDlg, IDC_EDIT1, EM_SETSEL, 0, -1); SetFocus(GetDlgItem(hwndDlg, IDC_EDIT1)); return FALSE; }
//
// allocate space for the string and pass the string back
//
pszText = (LPSTR) malloc(strlen(szText)+1); if (pszText != NULL) { strcpy(pszText, szText); } }
EndDialog(hwndDlg, (INT_PTR)pszText); break;
case IDCANCEL: EndDialog(hwndDlg, 0); break; }
break; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
DWORD MyGetCheckState(HWND hWndListView, int listIndex) { LVITEMW lvI;
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_STATE; lvI.iItem = listIndex; lvI.state = 0; lvI.stateMask = LVIS_STATEIMAGEMASK;
ListView_GetItem(hWndListView, &lvI);
return (lvI.state); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
void MySetCheckState(HWND hWndListView, int listIndex, DWORD dwImage) { LVITEMW lvI;
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_STATE; lvI.stateMask = LVIS_STATEIMAGEMASK; lvI.iItem = listIndex; lvI.state = dwImage;
SendMessage(hWndListView, LVM_SETITEM, (WPARAM) 0, (LPARAM) &lvI); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void SetEnableStateForChecks(PCERT_SETPROPERTIES_HELPER pviewhelp, HWND hWndListView, BOOL fEnabled) { int i; DWORD dwState;
pviewhelp->fInserting = TRUE;
for (i=0; i<ListView_GetItemCount(hWndListView); i++) { dwState = MyGetCheckState(hWndListView, i);
if ((dwState == MY_CHECK_STATE_CHECKED_GRAYED) || (dwState == MY_CHECK_STATE_UNCHECKED_GRAYED)) { if (fEnabled) { MySetCheckState( hWndListView, i, (dwState == MY_CHECK_STATE_CHECKED_GRAYED) ? MY_CHECK_STATE_CHECKED : MY_CHECK_STATE_UNCHECKED); } } else { if (!fEnabled) { MySetCheckState( hWndListView, i, (dwState == MY_CHECK_STATE_CHECKED) ? MY_CHECK_STATE_CHECKED_GRAYED : MY_CHECK_STATE_UNCHECKED_GRAYED); } } }
pviewhelp->fInserting = FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void AddUsageToList( HWND hWndListView, LPSTR pszOID, DWORD dwImage, BOOL fDirty) { WCHAR szText[CRYPTUI_MAX_STRING_SIZE]; LV_ITEMW lvI; SETPROPERTIES_HELPER_STRUCT *pHelperStruct;
//
// set up the fields in the list view item struct that don't change from item to item
//
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_TEXT | LVIF_PARAM; lvI.pszText = szText; lvI.iSubItem = 0; lvI.lParam = (LPARAM)NULL; lvI.iItem = ListView_GetItemCount(hWndListView);
// get the display string for the usage
if (!MyGetOIDInfo(szText, ARRAYSIZE(szText), pszOID)) { return; } lvI.cchTextMax = wcslen(szText);
// set the lParam field the helper struct so that we always have access the oid and
// the initial check state
pHelperStruct = NULL; pHelperStruct = (SETPROPERTIES_HELPER_STRUCT *) malloc(sizeof(SETPROPERTIES_HELPER_STRUCT) + (strlen(pszOID)+1));
if (pHelperStruct != NULL) { pHelperStruct->pszOID = (LPSTR) (((LPBYTE)pHelperStruct) + sizeof(SETPROPERTIES_HELPER_STRUCT)); lvI.lParam = (LPARAM) pHelperStruct; strcpy(pHelperStruct->pszOID, pszOID);
//
// if the dirty flag was passed in, then set the initial image to iImage+1
// so that when we are checking to see if anything has changed on shutdown
// we know this is a usage that was added after the dialog was brought up.
//
if (fDirty) { pHelperStruct->initialState = dwImage+1; } else { pHelperStruct->initialState = dwImage; } } else { return; }
ListView_InsertItemU(hWndListView, &lvI);
//
// for some reason you can't set the state image when inserting the
// item, so set the state image after it has been inserted
//
MySetCheckState(hWndListView, lvI.iItem, dwImage); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void DisplayKeyUsages( HWND hWndListView, PCERT_SETPROPERTIES_HELPER pviewhelp) { DWORD i; LPSTR *pszOIDs = NULL; DWORD numOIDs = 0; DWORD cbPropertyUsage = 0; PCERT_ENHKEY_USAGE pPropertyUsage = NULL; DWORD cbEKUExtensionUsage = 0; PCERT_ENHKEY_USAGE pEKUExtensionUsage = NULL; DWORD dwImage; DWORD displayState; int j; PCCERT_CONTEXT pCertContext = pviewhelp->pcsp->pCertContext; LVITEMW lvI;
//
// get the property usages that are currently tagged to this cert
//
if(!CertGetEnhancedKeyUsage ( pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbPropertyUsage ) || (pPropertyUsage = (PCERT_ENHKEY_USAGE) malloc(cbPropertyUsage)) == NULL || !CertGetEnhancedKeyUsage ( pCertContext, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pPropertyUsage, &cbPropertyUsage ) ) {
if (GetLastError() == CRYPT_E_NOT_FOUND) { if (pPropertyUsage != NULL) free(pPropertyUsage); pPropertyUsage = NULL; } else { goto CleanUp; } }
//
// get the EKU usages that are in the cert
//
if(!CertGetEnhancedKeyUsage ( pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbEKUExtensionUsage ) || (pEKUExtensionUsage = (PCERT_ENHKEY_USAGE) malloc(cbEKUExtensionUsage)) == NULL || !CertGetEnhancedKeyUsage ( pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pEKUExtensionUsage, &cbEKUExtensionUsage ) ) {
if (GetLastError() == CRYPT_E_NOT_FOUND) { if (pEKUExtensionUsage != NULL) free(pEKUExtensionUsage); pEKUExtensionUsage = NULL; } else { goto CleanUp; } }
//
// set the property state so the INIT_DIALOG can set the correct state
//
if (pPropertyUsage == NULL) { pviewhelp->EKUPropertyState = PROPERTY_STATE_ALL_ENABLED; } else if (fPropertiesDisabled(pPropertyUsage)) { pviewhelp->EKUPropertyState = PROPERTY_STATE_ALL_DISABLED; } else { pviewhelp->EKUPropertyState = PROPERTY_STATE_SELECT; }
//
// there are four different cases that the cert can be in
// 1) cert has property EKU only
// 2) cert has neither
// 3) cert has extension EKU only
// 4) cert has both property EKU and extension EKU
//
if (pEKUExtensionUsage == NULL) { //
// if we are in case 1 or 2, then all the usage that are valid
// for the chain are entered into the list view, unless the chain
// is good for everything, in which case the current certs valid
// usages are entered
//
if (pviewhelp->cszValidUsages != -1) { for (i=0; i<(DWORD)pviewhelp->cszValidUsages; i++) { if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pviewhelp->rgszValidChainUsages[i])) { dwImage = MY_CHECK_STATE_CHECKED; } else { dwImage = MY_CHECK_STATE_UNCHECKED; } AddUsageToList(hWndListView, pviewhelp->rgszValidChainUsages[i], dwImage, FALSE); } } else { AllocAndReturnEKUList(pCertContext, &pszOIDs, &numOIDs);
for (i=0; i<numOIDs; i++) { //
// if there are no property usages, or if this usage is in the list of
// property usages, then set the state to checked
//
if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pszOIDs[i])) { dwImage = MY_CHECK_STATE_CHECKED;
} else { dwImage = MY_CHECK_STATE_UNCHECKED; }
AddUsageToList(hWndListView, pszOIDs[i], dwImage, FALSE); }
FreeEKUList(pszOIDs, numOIDs); } } else { //
// for cases 3 and 4, the list view is populated with only the EKU extension,
// and is further restricted that the EKU must be in the chain valid usages
//
for (i=0; i<pEKUExtensionUsage->cUsageIdentifier; i++) { //
// if the EKU is not valid up the chain then skip the display
//
if ((pviewhelp->cszValidUsages != -1) && !OIDinArray(pEKUExtensionUsage->rgpszUsageIdentifier[i], pviewhelp->rgszValidChainUsages, pviewhelp->cszValidUsages)) { continue; }
//
// if there are no properties or the usage is in the properties then
// the usage should be checked
//
if ((pPropertyUsage == NULL) || OIDInUsages(pPropertyUsage, pEKUExtensionUsage->rgpszUsageIdentifier[i])) { dwImage = MY_CHECK_STATE_CHECKED; } else { dwImage = MY_CHECK_STATE_UNCHECKED; } AddUsageToList(hWndListView, pEKUExtensionUsage->rgpszUsageIdentifier[i], dwImage, FALSE); } }
CleanUp:
if (pPropertyUsage != NULL) free(pPropertyUsage);
if (pEKUExtensionUsage != NULL) free(pEKUExtensionUsage); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static BOOL StateChanged(HWND hWndListView) { int listIndex; LVITEMW lvI;
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_STATE | LVIF_PARAM; lvI.stateMask = LVIS_STATEIMAGEMASK;
listIndex = ListView_GetItemCount(hWndListView) - 1;
while (listIndex >= 0) { lvI.iItem = listIndex--; lvI.state = 0; lvI.lParam = 0;
ListView_GetItem(hWndListView, &lvI);
if (lvI.state != ((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->initialState) { return TRUE; } }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW AllocAndCopySetPropertiesStruct(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp) { PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pStruct; DWORD i;
if (NULL == (pStruct = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) malloc(sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW)))) { return NULL; } memcpy(pStruct, pcsp, sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW));
if (NULL == (pStruct->rghStores = (HCERTSTORE *) malloc(sizeof(HCERTSTORE)*pcsp->cStores))) { free(pStruct); return NULL; }
pStruct->cPropSheetPages = 0; pStruct->rgPropSheetPages = NULL; pStruct->pCertContext = CertDuplicateCertificateContext(pcsp->pCertContext);
for (i=0; i<pcsp->cStores; i++) { pStruct->rghStores[i] = CertDuplicateStore(pcsp->rghStores[i]); }
return pStruct; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void FreeSetPropertiesStruct(PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp) { DWORD i;
CertFreeCertificateContext(pcsp->pCertContext);
for (i=0; i<pcsp->cStores; i++) { CertCloseStore(pcsp->rghStores[i], 0); }
free(pcsp->rghStores); free(pcsp); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static BOOL OIDAlreadyExist(LPSTR pszNewOID, HWND hWndListView) { LVITEMW lvI; PSETPROPERTIES_HELPER_STRUCT pHelperStruct;
memset(&lvI, 0, sizeof(lvI)); lvI.iItem = ListView_GetItemCount(hWndListView) - 1; lvI.mask = LVIF_PARAM; while (lvI.iItem >= 0) { if (ListView_GetItemU(hWndListView, &lvI)) { pHelperStruct = (PSETPROPERTIES_HELPER_STRUCT) lvI.lParam; if (strcmp(pHelperStruct->pszOID, pszNewOID) == 0) { return TRUE; } } lvI.iItem--; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static BOOL CertHasEKU(PCCERT_CONTEXT pccert) { DWORD i;
i = 0; while (i < pccert->pCertInfo->cExtension) { if (strcmp(pccert->pCertInfo->rgExtension[i].pszObjId, szOID_ENHANCED_KEY_USAGE) == 0) { return TRUE; } i++; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static BOOL BuildChainEKUList(PCERT_SETPROPERTIES_HELPER pviewhelp) { WINTRUST_DATA WTD; WINTRUST_CERT_INFO WTCI; CRYPT_PROVIDER_DATA const * pProvData = NULL; CRYPT_PROVIDER_SGNR * pProvSigner = NULL; PCRYPT_PROVIDER_CERT pProvCert = NULL; PCCERT_CONTEXT *rgpCertContext = NULL; DWORD i; BOOL fRet = TRUE; DWORD cbOIDs = 0; DWORD dwCertsForUsageCheck = 0; GUID defaultProviderGUID = WINTRUST_ACTION_GENERIC_CERT_VERIFY;
pviewhelp->cszValidUsages = 0;
//
// initialize structs that are used with WinVerifyTrust()
//
memset(&WTD, 0x00, sizeof(WINTRUST_DATA)); WTD.cbStruct = sizeof(WINTRUST_DATA); WTD.dwUIChoice = WTD_UI_NONE; WTD.dwUnionChoice = WTD_CHOICE_CERT; WTD.pCert = &WTCI; WTD.dwProvFlags = WTD_NO_POLICY_USAGE_FLAG | WTD_REVOCATION_CHECK_NONE;
memset(&WTCI, 0x00, sizeof(WINTRUST_CERT_INFO)); WTCI.cbStruct = sizeof(WINTRUST_CERT_INFO); WTCI.pcwszDisplayName = L"CryptUI"; WTCI.psCertContext = (CERT_CONTEXT *)pviewhelp->pcsp->pCertContext; WTCI.chStores = pviewhelp->pcsp->cStores; WTCI.pahStores = pviewhelp->pcsp->rghStores; WTCI.dwFlags = 0;
WTD.dwStateAction = WTD_STATEACTION_VERIFY;
//
// the default default provider requires the policycallback data to point
// to the usage oid you are validating for, so set it to the usage passed in
//
WinVerifyTrustEx(NULL, &defaultProviderGUID, &WTD);
pProvData = WTHelperProvDataFromStateData(WTD.hWVTStateData); pProvSigner = WTHelperGetProvSignerFromChain((PCRYPT_PROVIDER_DATA) pProvData, 0, FALSE, 0); if (pProvSigner == NULL) { goto Error; }
//
// build up the array of PCCERT_CONTEXTs
//
rgpCertContext = (PCCERT_CONTEXT *) malloc((pProvSigner->csCertChain-1) * sizeof(PCCERT_CONTEXT)); if (rgpCertContext == NULL) { goto Error; }
for (i=1; i<pProvSigner->csCertChain; i++) { pProvCert = WTHelperGetProvCertFromChain(pProvSigner, i); rgpCertContext[i-1] = pProvCert->pCert; dwCertsForUsageCheck++;
//
// if there is a CTL context that contains this cert, then the usage
// changes for certs above the CTL in the chain, so stop with this
// cert when calculating valid usages
//
if (pProvCert->pCtlContext != NULL) { break; } }
//
// now, get the usages array
//
if (!CertGetValidUsages(dwCertsForUsageCheck, rgpCertContext, &(pviewhelp->cszValidUsages), NULL, &cbOIDs)) { goto Error; }
if (NULL == (pviewhelp->rgszValidChainUsages = (LPSTR *) malloc(cbOIDs))) { goto Error; }
if (!CertGetValidUsages(dwCertsForUsageCheck, rgpCertContext, &(pviewhelp->cszValidUsages), pviewhelp->rgszValidChainUsages, &cbOIDs)) { free(pviewhelp->rgszValidChainUsages); pviewhelp->rgszValidChainUsages = NULL; goto Error; }
CleanUp:
WTD.dwStateAction = WTD_STATEACTION_CLOSE; WinVerifyTrustEx(NULL, &defaultProviderGUID, &WTD); if (rgpCertContext != NULL) { free(rgpCertContext); }
return fRet;
Error: fRet = FALSE; goto CleanUp; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
static void AddExistingPropertiesToUsage( PCCERT_CONTEXT pccert, PCERT_ENHKEY_USAGE pPropertyUsage, HWND hWndListView) { PCERT_ENHKEY_USAGE pExistingPropUsage = NULL; DWORD cbExistingPropUsage = 0; DWORD i; BOOL fSkip = FALSE; LVITEMW lvI; DWORD state; void *pTemp;
//
// get the property usages that are currently tagged to this cert
//
if(!CertGetEnhancedKeyUsage ( pccert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbExistingPropUsage ) || (pExistingPropUsage = (PCERT_ENHKEY_USAGE) malloc(cbExistingPropUsage)) == NULL || !CertGetEnhancedKeyUsage ( pccert, CERT_FIND_PROP_ONLY_ENHKEY_USAGE_FLAG, pExistingPropUsage, &cbExistingPropUsage ) ) { if (pExistingPropUsage != NULL) { free(pExistingPropUsage); }
return; }
//
// loop for each usage, and add it if it does not already exist in the list,
// AND it is not already in the list view unchecked
//
for (i=0; i<pExistingPropUsage->cUsageIdentifier; i++) { if (!OIDInUsages(pPropertyUsage, pExistingPropUsage->rgpszUsageIdentifier[i])) { fSkip = FALSE;
//
// if the property is unchecked in the list view then skip it
//
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_PARAM; lvI.lParam = (LPARAM)NULL; lvI.iItem = ListView_GetItemCount(hWndListView) - 1; lvI.iSubItem = 0;
while (lvI.iItem >= 0) { if (ListView_GetItemU(hWndListView, &lvI)) { if (strcmp(((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->pszOID, pExistingPropUsage->rgpszUsageIdentifier[i]) == 0) { state = MyGetCheckState(hWndListView, lvI.iItem);
if ((state == MY_CHECK_STATE_UNCHECKED) || (state == MY_CHECK_STATE_UNCHECKED_GRAYED)) { fSkip = TRUE; break; } } } lvI.iItem--; }
if (fSkip) { continue; }
//
// allocate space for a pointer to the usage OID string
//
if (pPropertyUsage->cUsageIdentifier++ == 0) { pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) malloc (sizeof(LPSTR)); } else { pTemp = realloc (pPropertyUsage->rgpszUsageIdentifier, sizeof(LPSTR) * pPropertyUsage->cUsageIdentifier); if (pTemp == NULL) { free(pPropertyUsage->rgpszUsageIdentifier); pPropertyUsage->rgpszUsageIdentifier = NULL; } else { pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) pTemp; } }
if (pPropertyUsage->rgpszUsageIdentifier == NULL) { pPropertyUsage->cUsageIdentifier = 0; return; }
pPropertyUsage->rgpszUsageIdentifier[pPropertyUsage->cUsageIdentifier-1] = AllocAndCopyMBStr(pExistingPropUsage->rgpszUsageIdentifier[i]); } }
if (pExistingPropUsage != NULL) { free(pExistingPropUsage); } }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
INT_PTR APIENTRY ViewPageSetPropertiesGeneral(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL f; DWORD cch; PCCERT_CONTEXT pccert; PROPSHEETPAGE * ps; LPWSTR pwsz; WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE]; CRYPT_DATA_BLOB CryptDataBlob; DWORD cbpwsz; HIMAGELIST hIml; HWND hWndListView; HWND hwnd; LV_COLUMNW lvC; LVITEMW lvI; LPNMLISTVIEW pnmv; DWORD state; LPSTR pszNewOID; WCHAR errorString[CRYPTUI_MAX_STRING_SIZE]; WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE]; int j; DWORD i; void *pTemp; PCERT_SETPROPERTIES_HELPER pviewhelp; PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp = NULL;
switch ( msg ) { case WM_INITDIALOG:
//
// save the pviewhelp struct in DWL_USER so it can always be accessed
//
ps = (PROPSHEETPAGE *) lParam; pviewhelp = (PCERT_SETPROPERTIES_HELPER) ps->lParam; pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pviewhelp);
fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT)); ShowWindow(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT), SW_HIDE); //
// Set the Certificate Name (friendly name) and Description fields in the dialog box
//
cbpwsz = 0; if (CertGetCertificateContextProperty( pccert, CERT_FRIENDLY_NAME_PROP_ID, NULL, &cbpwsz)) { //
// The Certificate Name (friendly name) property exists, so display it
//
pviewhelp->pwszInitialCertName = (LPWSTR) malloc(cbpwsz); if (pviewhelp->pwszInitialCertName != NULL) { CertGetCertificateContextProperty( pccert, CERT_FRIENDLY_NAME_PROP_ID, pviewhelp->pwszInitialCertName, &cbpwsz); CryptUISetRicheditTextW(hwndDlg, IDC_CERTIFICATE_NAME, pviewhelp->pwszInitialCertName); } } else { //
// The Certificate Name (friendly name) property did not exist, so display the default
//
//LoadStringU(HinstDll, IDS_DEFAULT_CERTIFICATE_NAME, rgwch, ARRAYSIZE(rgwch));
CryptUISetRicheditTextW(hwndDlg, IDC_CERTIFICATE_NAME, L""); pviewhelp->pwszInitialCertName = AllocAndCopyWStr(L""); }
// DSIE: IE 6 bug #13676.
SendDlgItemMessage(hwndDlg, IDC_CERTIFICATE_NAME, EM_EXLIMITTEXT, 0, (LPARAM) 40);
cbpwsz = 0; if (CertGetCertificateContextProperty( pccert, CERT_DESCRIPTION_PROP_ID, NULL, &cbpwsz)) { //
// The Description property exists, so display it
//
pviewhelp->pwszInitialDescription = (LPWSTR) malloc(cbpwsz); if (pviewhelp->pwszInitialDescription != NULL) { CertGetCertificateContextProperty( pccert, CERT_DESCRIPTION_PROP_ID, pviewhelp->pwszInitialDescription, &cbpwsz); CryptUISetRicheditTextW(hwndDlg, IDC_DESCRIPTION, pviewhelp->pwszInitialDescription); } } else { //
// The Description property did not exist, so display the default
//
//LoadStringU(HinstDll, IDS_DEFAULT_DESCRIPTION, rgwch, ARRAYSIZE(rgwch));
CryptUISetRicheditTextW(hwndDlg, IDC_DESCRIPTION, L""); pviewhelp->pwszInitialDescription = AllocAndCopyWStr(L""); }
// DSIE: IE 6 bug #13676.
SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION, EM_EXLIMITTEXT, 0, (LPARAM) 255);
//
// get the handle of the list view control
//
hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
//
// initialize the image list for the list view, load the icons,
// then add the image list to the list view
//
ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_CHECKBOXES); hIml = ImageList_LoadImage(HinstDll, MAKEINTRESOURCE(IDB_CHECKLIST), 0, 4, RGB(255,0,255), IMAGE_BITMAP, 0); if (hIml != NULL) { ListView_SetImageList(hWndListView, hIml, LVSIL_STATE); }
//
// initialize the columns in the list view
//
lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; // Left-align the column.
lvC.cx = 330; // Width of the column, in pixels.
lvC.pszText = L""; // The text for the column.
if (ListView_InsertColumnU(hWndListView, 0, &lvC) == -1) { // error
}
BuildChainEKUList(pviewhelp);
pviewhelp->fInserting = TRUE; DisplayKeyUsages(hWndListView, pviewhelp); pviewhelp->fInserting = FALSE;
//
// set the flag noting whether the add purposes button can be
// enabled based on wether there are EKU's in the cert, and if
// the chain is NOT valid for all usages
//
if (CertHasEKU(pccert) || (pviewhelp->cszValidUsages != -1)) { pviewhelp->fAddPurposeCanBeEnabled = FALSE; } else { pviewhelp->fAddPurposeCanBeEnabled = TRUE; }
//
// set the state of the property editing controls based on the
// state of the eku PROPERTY
//
if (pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_ENABLED) { SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0); SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); pviewhelp->dwRadioButtonState = IDC_ENABLE_ALL_RADIO; } else if (pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_DISABLED) { SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0); SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); pviewhelp->dwRadioButtonState = IDC_DISABLE_ALL_RADIO; } else if (pviewhelp->EKUPropertyState == PROPERTY_STATE_SELECT) { SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_SETCHECK, BST_CHECKED, (LPARAM) 0); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE); SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE); if (pviewhelp->fAddPurposeCanBeEnabled) { EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), TRUE); } else { EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); } pviewhelp->dwRadioButtonState = IDC_ENABLE_SELECT_RADIO; }
//
// make sure we get change notifications from the richedit controls
//
SendDlgItemMessageA(hwndDlg, IDC_CERTIFICATE_NAME, EM_SETEVENTMASK, 0, (LPARAM) ENM_CHANGE); SendDlgItemMessageA(hwndDlg, IDC_DESCRIPTION, EM_SETEVENTMASK, 0, (LPARAM) ENM_CHANGE);
//DSIE: Bug 465438.
if (pcsp->dwFlags & CRYPTUI_DISABLE_EDITPROPERTIES) { SendMessage(GetDlgItem(hwndDlg, IDC_CERTIFICATE_NAME), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0); SendMessage(GetDlgItem(hwndDlg, IDC_DESCRIPTION), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_ALL_RADIO), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_DISABLE_ALL_RADIO), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ENABLE_SELECT_RADIO), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); }
return TRUE;
case WM_NOTIFY: pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER); pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext;
switch (((NMHDR FAR *) lParam)->code) {
case PSN_SETACTIVE: break;
case PSN_APPLY: { BOOL fAllItemsChecked = TRUE; DWORD cbPropertyUsage = 0; PCERT_ENHKEY_USAGE pPropertyUsage = NULL; GETTEXTEX GetTextStruct;
memset(&GetTextStruct, 0, sizeof(GetTextStruct)); GetTextStruct.flags = GT_DEFAULT; GetTextStruct.codepage = 1200; //UNICODE
//
// Write back the Friendly name
// and description if they have changed
//
//
// Friendly Name
//
cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_CERTIFICATE_NAME, WM_GETTEXTLENGTH, 0, 0); pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR)); if (pwsz != NULL) { memset(pwsz, 0, (cch+1)*sizeof(WCHAR)); if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT))) { GetTextStruct.cb = (cch+1)*sizeof(WCHAR); SendDlgItemMessageA( hwndDlg, IDC_CERTIFICATE_NAME, EM_GETTEXTEX, (WPARAM) &GetTextStruct, (LPARAM) pwsz); } else { GetDlgItemTextU(hwndDlg, IDC_CERTIFICATE_NAME, pwsz, cch+1); }
//
// check for change
//
if (wcscmp(pviewhelp->pwszInitialCertName, pwsz) != 0) { if (wcscmp(pwsz, L"") == 0) { f = CertSetCertificateContextProperty(pccert, CERT_FRIENDLY_NAME_PROP_ID, 0, NULL); } else { CryptDataBlob.pbData = (LPBYTE) pwsz; CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR); f = CertSetCertificateContextProperty(pccert, CERT_FRIENDLY_NAME_PROP_ID, 0, &CryptDataBlob); }
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = TRUE; } pviewhelp->fPropertiesChanged = TRUE; } free(pwsz); }
//
// Description
//
cch = (DWORD)SendDlgItemMessage(hwndDlg, IDC_DESCRIPTION, WM_GETTEXTLENGTH, 0, 0); pwsz = (LPWSTR) malloc((cch+1)*sizeof(WCHAR)); if (pwsz != NULL) { memset(pwsz, 0, (cch+1)*sizeof(WCHAR)); if (fRichedit20Exists && fRichedit20Usable(GetDlgItem(hwndDlg, IDC_HIDDEN_RICHEDIT))) { GetTextStruct.cb = (cch+1)*sizeof(WCHAR); SendDlgItemMessageA( hwndDlg, IDC_DESCRIPTION, EM_GETTEXTEX, (WPARAM) &GetTextStruct, (LPARAM) pwsz); } else { GetDlgItemTextU(hwndDlg, IDC_DESCRIPTION, pwsz, cch+1); }
//
// check for change
//
if (wcscmp(pviewhelp->pwszInitialDescription, pwsz) != 0) { if (wcscmp(pwsz, L"") == 0) { f = CertSetCertificateContextProperty(pccert, CERT_DESCRIPTION_PROP_ID, 0, NULL); } else { CryptDataBlob.pbData = (LPBYTE) pwsz; CryptDataBlob.cbData = (cch+1)*sizeof(WCHAR); f = CertSetCertificateContextProperty(pccert, CERT_DESCRIPTION_PROP_ID, 0, &CryptDataBlob); }
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = TRUE; } pviewhelp->fPropertiesChanged = TRUE; } free(pwsz); }
hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
//
// check the radio buttons and the usages to see if any have changed,
// if so, then set the fPropertiesFlag in the CERT_VIEWCERT_STRUCT so the
// caller knows that something has changed
//
if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_ENABLED) && (SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED)) { //pviewhelp->fPropertiesChanged = FALSE;
} else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_ALL_DISABLED) && (SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED)) { //pviewhelp->fPropertiesChanged = FALSE;
} else if ((pviewhelp->EKUPropertyState == PROPERTY_STATE_SELECT) && (SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) && (!StateChanged(hWndListView))) { //pviewhelp->fPropertiesChanged = FALSE;
} else { pviewhelp->fPropertiesChanged = TRUE; }
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) |= pviewhelp->fPropertiesChanged; }
if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) && pviewhelp->fPropertiesChanged) { CertSetEnhancedKeyUsage(pccert, NULL); } else if ((SendDlgItemMessage(hwndDlg, IDC_DISABLE_ALL_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) && pviewhelp->fPropertiesChanged) { CERT_ENHKEY_USAGE eku;
eku.cUsageIdentifier = 0; eku.rgpszUsageIdentifier = NULL;
CertSetEnhancedKeyUsage(pccert, &eku); } else if ((SendDlgItemMessage(hwndDlg, IDC_ENABLE_SELECT_RADIO, BM_GETCHECK, 0, (LPARAM) 0) == BST_CHECKED) && pviewhelp->fPropertiesChanged) { if (NULL == (pPropertyUsage = (PCERT_ENHKEY_USAGE) malloc(sizeof(CERT_ENHKEY_USAGE)))) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); return FALSE; } pPropertyUsage->cUsageIdentifier = 0; pPropertyUsage->rgpszUsageIdentifier = NULL;
//
// enumerate through all the items and add to the properties
// if checked
//
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_PARAM; lvI.lParam = (LPARAM)NULL; lvI.iItem = ListView_GetItemCount(hWndListView) - 1; lvI.iSubItem = 0;
while (lvI.iItem >= 0) { if (!ListView_GetItemU(hWndListView, &lvI)) { lvI.iItem--; continue; }
state = MyGetCheckState(hWndListView, lvI.iItem);
if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_CHECKED_GRAYED)) { //
// allocate space for a pointer to the usage OID string
//
if (pPropertyUsage->cUsageIdentifier++ == 0) { pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) malloc (sizeof(LPSTR)); } else { pTemp = realloc (pPropertyUsage->rgpszUsageIdentifier, sizeof(LPSTR) * pPropertyUsage->cUsageIdentifier); if (pTemp == NULL) { free(pPropertyUsage->rgpszUsageIdentifier); pPropertyUsage->rgpszUsageIdentifier = NULL; } else { pPropertyUsage->rgpszUsageIdentifier = (LPSTR *) pTemp; } }
if (pPropertyUsage->rgpszUsageIdentifier == NULL) { free(pPropertyUsage); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); return FALSE; }
pPropertyUsage->rgpszUsageIdentifier[pPropertyUsage->cUsageIdentifier-1] = AllocAndCopyMBStr(((PSETPROPERTIES_HELPER_STRUCT)lvI.lParam)->pszOID); }
lvI.iItem--; }
AddExistingPropertiesToUsage(pccert, pPropertyUsage, hWndListView);
CertSetEnhancedKeyUsage(pccert, pPropertyUsage);
for (i=0; i<pPropertyUsage->cUsageIdentifier; i++) { free(pPropertyUsage->rgpszUsageIdentifier[i]); } if (pPropertyUsage->rgpszUsageIdentifier) free(pPropertyUsage->rgpszUsageIdentifier); }
if (pPropertyUsage != NULL) free(pPropertyUsage);
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); break; } case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); return TRUE;
case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); break;
case PSN_QUERYCANCEL: pviewhelp->fCancelled = TRUE; return FALSE;
case PSN_HELP: if (FIsWin95) { //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
// HELP_CONTEXT, pcsp->dwHelpId);
} else { // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
// pcsp->dwHelpId);
} return TRUE; case LVN_ITEMCHANGING:
if (pviewhelp->fInserting) { return TRUE; }
pnmv = (LPNMLISTVIEW) lParam; hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
state = LVIS_STATEIMAGEMASK & pnmv->uOldState;
if ((state == MY_CHECK_STATE_CHECKED_GRAYED) || (state == MY_CHECK_STATE_UNCHECKED_GRAYED)) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); } else if ((state == MY_CHECK_STATE_CHECKED) || (state == MY_CHECK_STATE_UNCHECKED)) { pviewhelp->fInserting = TRUE; if (state == MY_CHECK_STATE_CHECKED) { MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_UNCHECKED); } else { MySetCheckState(hWndListView, pnmv->iItem, MY_CHECK_STATE_CHECKED); } pviewhelp->fInserting = FALSE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); }
return TRUE;
case NM_SETFOCUS:
switch (((NMHDR FAR *) lParam)->idFrom) {
case IDC_KEY_USAGE_LIST: hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
if ((ListView_GetItemCount(hWndListView) != 0) && (ListView_GetNextItem(hWndListView, -1, LVNI_SELECTED) == -1)) { memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_STATE; lvI.iItem = 0; lvI.state = LVIS_FOCUSED | LVIS_SELECTED; lvI.stateMask = LVIS_FOCUSED | LVIS_SELECTED; ListView_SetItem(hWndListView, &lvI); }
break; } break; }
break;
case WM_COMMAND:
pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER); pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext;
switch (LOWORD(wParam)) { case IDHELP: if (FIsWin95) { //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
// HELP_CONTEXT, pcsp->dwHelpId);
} else { //WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
// pcsp->dwHelpId);
} return TRUE;
case IDC_CERTIFICATE_NAME: if (HIWORD(wParam) == EN_SETFOCUS) { SendDlgItemMessageA(hwndDlg, IDC_CERTIFICATE_NAME, EM_SETSEL, 0, -1); return TRUE; } else if (HIWORD(wParam) == EN_CHANGE) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break;
case IDC_DESCRIPTION: if (HIWORD(wParam) == EN_SETFOCUS) { SendDlgItemMessageA(hwndDlg, IDC_DESCRIPTION, EM_SETSEL, 0, -1); return TRUE; } else if (HIWORD(wParam) == EN_CHANGE) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break;
case IDC_ENABLE_ALL_RADIO: if (HIWORD(wParam) == BN_CLICKED) { SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); if (pviewhelp->dwRadioButtonState != IDC_ENABLE_ALL_RADIO) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); pviewhelp->dwRadioButtonState = IDC_ENABLE_ALL_RADIO; } } break;
case IDC_DISABLE_ALL_RADIO: if (HIWORD(wParam) == BN_CLICKED) { SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); if (pviewhelp->dwRadioButtonState != IDC_DISABLE_ALL_RADIO) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); pviewhelp->dwRadioButtonState = IDC_DISABLE_ALL_RADIO; } } break;
case IDC_ENABLE_SELECT_RADIO: if (HIWORD(wParam) == BN_CLICKED) { EnableWindow(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE); SetEnableStateForChecks(pviewhelp, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), TRUE); if (pviewhelp->fAddPurposeCanBeEnabled) { EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), TRUE); } else { EnableWindow(GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID), FALSE); }
if (pviewhelp->dwRadioButtonState != IDC_ENABLE_SELECT_RADIO) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); pviewhelp->dwRadioButtonState = IDC_ENABLE_SELECT_RADIO; } } break;
case IDC_PROPERTY_NEWOID: pszNewOID = (LPSTR) DialogBoxU( HinstDll, (LPWSTR) MAKEINTRESOURCE(IDD_USER_PURPOSE), hwndDlg, NewOIDDialogProc);
if (pszNewOID != NULL) { DWORD chStores = 0; HCERTSTORE *phStores = NULL;
//
// if the OID already existis then put up a message box and return
//
if (OIDAlreadyExist(pszNewOID, GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST))) { WCHAR errorString2[CRYPTUI_MAX_STRING_SIZE]; WCHAR errorTitle2[CRYPTUI_MAX_STRING_SIZE];
LoadStringU(HinstDll, IDS_OID_ALREADY_EXISTS_MESSAGE, errorString2, ARRAYSIZE(errorString2)); LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2)); MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONWARNING); return FALSE; }
//
// if the usage doesn't exist in the chain usages, then put up an error
//
/*if ((pviewhelp->cszValidUsages != -1) && //pviewhelp->cszValidUsages == -1 means all usages are ok
!OIDinArray(pszNewOID, pviewhelp->rgszValidChainUsages, pviewhelp->cszValidUsages)) { LoadStringU(HinstDll, IDS_ERROR_INVALIDOID_CERT, errorString2, ARRAYSIZE(errorString2)); LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle2, ARRAYSIZE(errorTitle2)); MessageBoxU(hwndDlg, errorString2, errorTitle2, MB_OK | MB_ICONERROR); return FALSE; } */
pviewhelp->fInserting = TRUE; AddUsageToList(GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST), pszNewOID, MY_CHECK_STATE_CHECKED, TRUE); pviewhelp->fInserting = FALSE;
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
free(pszNewOID); } break; } break;
case WM_DESTROY:
pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER);
//
// get all the items in the list view and free the lParam
// associated with each of them (lParam is the helper sruct)
//
hWndListView = GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST);
memset(&lvI, 0, sizeof(lvI)); lvI.iItem = ListView_GetItemCount(hWndListView) - 1; lvI.mask = LVIF_PARAM; while (lvI.iItem >= 0) { if (ListView_GetItemU(hWndListView, &lvI)) { free((void *) lvI.lParam); } lvI.iItem--; }
//
// free the name and description if they exist
//
if (pviewhelp->pwszInitialCertName) { free (pviewhelp->pwszInitialCertName); } if (pviewhelp->pwszInitialDescription) { free (pviewhelp->pwszInitialDescription); }
//
// free the usage array
//
if (pviewhelp->rgszValidChainUsages) { free(pviewhelp->rgszValidChainUsages); }
//
// if the properties have changed, and there is a pMMCCallback
// then make the callback to MMC
//
if (pviewhelp->fPropertiesChanged && pviewhelp->fGetPagesCalled && (pviewhelp->pcsp->pMMCCallback != NULL) && (pviewhelp->fMMCCallbackMade != TRUE)) { pviewhelp->fMMCCallbackMade = TRUE;
(*(pviewhelp->pcsp->pMMCCallback->pfnCallback))( pviewhelp->pcsp->pMMCCallback->lNotifyHandle, pviewhelp->pcsp->pMMCCallback->param); }
break;
case WM_HELP: case WM_CONTEXTMENU: if (msg == WM_HELP) { hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId); } else { hwnd = (HWND) wParam; }
if ((hwnd != GetDlgItem(hwndDlg, IDC_CERTIFICATE_NAME)) && (hwnd != GetDlgItem(hwndDlg, IDC_DESCRIPTION)) && (hwnd != GetDlgItem(hwndDlg, IDC_KEY_USAGE_LIST)) && (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_ALL_RADIO)) && (hwnd != GetDlgItem(hwndDlg, IDC_DISABLE_ALL_RADIO)) && (hwnd != GetDlgItem(hwndDlg, IDC_ENABLE_SELECT_RADIO)) && (hwnd != GetDlgItem(hwndDlg, IDC_PROPERTY_NEWOID))) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); return TRUE; } else { return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapGeneral); }
break; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
#define MAX_DWORD_SIZE ((DWORD) 0xffffffff)
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
INT_PTR APIENTRY ViewPageSetPropertiesCrossCerts(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { BOOL f; DWORD cch; PCCERT_CONTEXT pccert; PROPSHEETPAGE * ps; LPWSTR pwsz; WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE]; CRYPT_DATA_BLOB CryptDataBlob; HWND hWndListView; HWND hwnd; LVITEMW lvI; LV_COLUMNW lvC; LPNMLISTVIEW pnmv; WCHAR errorString[CRYPTUI_MAX_STRING_SIZE]; WCHAR errorTitle[CRYPTUI_MAX_STRING_SIZE]; DWORD dw; int i; void *pTemp; PCERT_SETPROPERTIES_HELPER pviewhelp; PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp = NULL; DWORD cb = 0; BYTE *pb = NULL; CROSS_CERT_DIST_POINTS_INFO *pCrossCertInfo = NULL; CROSS_CERT_DIST_POINTS_INFO CrossCertInfo; DWORD cbCrossCertInfo = 0; LPWSTR pwszStringToAdd = NULL; PCERT_ALT_NAME_INFO pAltNameInfo = NULL; BOOL fChecked; WCHAR wszText[CRYPTUI_MAX_STRING_SIZE]; DWORD dwNumUnits = 0; LPWSTR pwszURL = NULL; DWORD dwLength; BOOL fTranslated; PCERT_ALT_NAME_ENTRY rgAltEntry; LONG_PTR PrevWndProc; DWORD dwSecsPerUnit = 1; HWND hwndControl=NULL; int listIndex=0;
switch ( msg ) { case WM_INITDIALOG:
//
// save the pviewhelp struct in DWL_USER so it can always be accessed
//
ps = (PROPSHEETPAGE *) lParam; pviewhelp = (PCERT_SETPROPERTIES_HELPER) ps->lParam; pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR) pviewhelp);
pviewhelp->InWMInit = TRUE;
hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
SendDlgItemMessage(hwndDlg, IDC_NUMBEROFUNITS_EDIT, EM_LIMITTEXT, (WPARAM) 7, (LPARAM) 0); SendDlgItemMessage(hwndDlg, IDC_NEWURL_EDIT, EM_LIMITTEXT, (WPARAM) 512, (LPARAM) 0);
//
// Initialize the combo box fields
//
LoadStringU(HinstDll, IDS_HOURS, wszText, ARRAYSIZE(wszText)); SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 0, (LPARAM) wszText);
LoadStringU(HinstDll, IDS_DAYS, wszText, ARRAYSIZE(wszText)); SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_INSERTSTRING, 1, (LPARAM) wszText);
SendDlgItemMessageU(hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL); SetDlgItemTextU(hwndDlg, IDC_NUMBEROFUNITS_EDIT, L"0");
//
// Initialize the list view control
//
memset(&lvC, 0, sizeof(LV_COLUMNW)); lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; lvC.cx = 150; lvC.pszText = L""; lvC.iSubItem=0; if (ListView_InsertColumnU(GetDlgItem(hwndDlg, IDC_URL_LIST), 0, &lvC) == -1) { return FALSE; }
//DSIE: Bug 465438.
if (pcsp->dwFlags & CRYPTUI_DISABLE_EDITPROPERTIES) { EnableWindow(GetDlgItem(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK), FALSE); SendMessage(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0); EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), FALSE); SendMessage(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), EM_SETREADONLY, (WPARAM) TRUE, (LPARAM) 0); EnableWindow(GetDlgItem(hwndDlg, IDC_URL_LIST), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE); } else { //
// try to get the CERT_CROSS_CERT_DIST_POINTS_PROP_ID property for this cert
//
if (!CertGetCertificateContextProperty( pccert, CERT_CROSS_CERT_DIST_POINTS_PROP_ID, NULL, &cb)) { //
// The property doesn't exist
//
SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), FALSE); EnableWindow(hWndListView, FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE);
pviewhelp->InWMInit = FALSE; return TRUE; } else { SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_SETCHECK, BST_CHECKED, 0); EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), TRUE); EnableWindow(hWndListView, TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE); } }
if (NULL == (pb = (BYTE *) malloc(cb))) { return FALSE; }
if (!CertGetCertificateContextProperty( pccert, CERT_CROSS_CERT_DIST_POINTS_PROP_ID, pb, &cb)) { free(pb); return FALSE; }
if (!CryptDecodeObject( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CROSS_CERT_DIST_POINTS, pb, cb, 0, NULL, &cbCrossCertInfo)) { free(pb); return FALSE; }
if (NULL == (pCrossCertInfo = (CROSS_CERT_DIST_POINTS_INFO *) malloc(cbCrossCertInfo))) { free(pb); return FALSE; }
if (!CryptDecodeObject( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CROSS_CERT_DIST_POINTS, pb, cb, 0, pCrossCertInfo, &cbCrossCertInfo)) { free(pb); return FALSE; }
free(pb);
//
// Initialize the sync time controls
//
if (pCrossCertInfo->dwSyncDeltaTime == 0) { pCrossCertInfo->dwSyncDeltaTime = XCERT_DEFAULT_SYNC_DELTA_TIME; } if ((pCrossCertInfo->dwSyncDeltaTime % 86400) == 0) { //
// Days
//
dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 86400; SendDlgItemMessageU( hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 1, (LPARAM) NULL); } else { //
// Hours
//
dwNumUnits = pCrossCertInfo->dwSyncDeltaTime / 3600;
//
// Force to 1 if exisiting value is less than 1 hour.
//
if (0 == dwNumUnits) { dwNumUnits = 1; }
SendDlgItemMessageU( hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL); }
SetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, dwNumUnits, FALSE);
//
// Add each dist point to the list view
//
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_TEXT | LVIF_PARAM;
for (lvI.iItem=0; lvI.iItem< (int)pCrossCertInfo->cDistPoint; lvI.iItem++) { pAltNameInfo = &(pCrossCertInfo->rgDistPoint[lvI.iItem]);
if ((pAltNameInfo->cAltEntry == 0) || (pAltNameInfo->rgAltEntry[0].dwAltNameChoice != 7)) { continue; }
pwszURL = (LPWSTR) malloc( (wcslen(pAltNameInfo->rgAltEntry[0].pwszURL) + 1) * sizeof(WCHAR)); if (pwszURL == NULL) { continue; } wcscpy(pwszURL, pAltNameInfo->rgAltEntry[0].pwszURL); lvI.pszText = pwszURL; lvI.lParam = (LPARAM) pwszURL;
ListView_InsertItemU(hWndListView, &lvI); }
ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE); ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE);
free(pCrossCertInfo); pviewhelp->InWMInit = FALSE; return TRUE;
case WM_NOTIFY: pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER); pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext;
switch (((NMHDR FAR *) lParam)->code) {
case PSN_SETACTIVE: break;
case PSN_APPLY: hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST); if (BST_CHECKED != SendDlgItemMessage( hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_GETCHECK, 0, 0)) { CertSetCertificateContextProperty( pccert, CERT_CROSS_CERT_DIST_POINTS_PROP_ID, 0, NULL); } else { //
// Set the sync time
//
memset(&CrossCertInfo, 0, sizeof(CrossCertInfo));
dwNumUnits = GetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, &fTranslated, FALSE);
if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL)) { dwSecsPerUnit = 3600; } else { dwSecsPerUnit = 86400; } CrossCertInfo.dwSyncDeltaTime = dwNumUnits * dwSecsPerUnit;
//
// Set the dist points
//
CrossCertInfo.cDistPoint = ListView_GetItemCount(hWndListView); CrossCertInfo.rgDistPoint = (CERT_ALT_NAME_INFO *) malloc( CrossCertInfo.cDistPoint * sizeof(CERT_ALT_NAME_INFO)); if (CrossCertInfo.rgDistPoint == NULL) { break; }
// one AltEntry per DistPoint
rgAltEntry = (CERT_ALT_NAME_ENTRY *) malloc(CrossCertInfo.cDistPoint * sizeof(CERT_ALT_NAME_ENTRY)); if (rgAltEntry == NULL) { free(CrossCertInfo.rgDistPoint); break; }
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_PARAM; for (dw=0; dw<CrossCertInfo.cDistPoint; dw++) { lvI.iItem = dw; if (ListView_GetItemU(hWndListView, &lvI)) { CrossCertInfo.rgDistPoint[dw].cAltEntry = 1; CrossCertInfo.rgDistPoint[dw].rgAltEntry = &(rgAltEntry[dw]); rgAltEntry[dw].dwAltNameChoice = 7; rgAltEntry[dw].pwszURL = (LPWSTR) lvI.lParam; } } //
// Now encode
//
CryptDataBlob.cbData = 0; CryptDataBlob.pbData = NULL; if (CryptEncodeObject( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CROSS_CERT_DIST_POINTS, &CrossCertInfo, NULL, &CryptDataBlob.cbData)) { if (NULL != (CryptDataBlob.pbData = (BYTE *) malloc(CryptDataBlob.cbData))) { if (CryptEncodeObject( X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_CROSS_CERT_DIST_POINTS, &CrossCertInfo, CryptDataBlob.pbData, &CryptDataBlob.cbData)) { CertSetCertificateContextProperty( pccert, CERT_CROSS_CERT_DIST_POINTS_PROP_ID, 0, &CryptDataBlob); }
free(CryptDataBlob.pbData); } }
free(rgAltEntry); free(CrossCertInfo.rgDistPoint); }
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); break;
case PSN_KILLACTIVE: //
// DSIE: Bug 124468. Per PM JohnLa, we don't make any check until user applies.
//
if (BST_CHECKED == SendDlgItemMessage(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_GETCHECK, 0, 0)) { //
// Check the sync time
//
dwNumUnits = GetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, &fTranslated, FALSE);
if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL)) { dwSecsPerUnit = 3600; } else { dwSecsPerUnit = 86400; }
if (!fTranslated || 0 == dwNumUnits || dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit)) { WCHAR * pwszMessage = NULL; DWORD dwMaxInterval = MAX_DWORD_SIZE / dwSecsPerUnit; if (pwszMessage = FormatMessageUnicodeIds(IDS_INVALID_XCERT_INTERVAL, dwMaxInterval)) { WCHAR wszTitle[CRYPTUI_MAX_STRING_SIZE] = L"";
LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, wszTitle, ARRAYSIZE(wszTitle));
MessageBoxU(hwndDlg, pwszMessage, wszTitle, MB_OK | MB_ICONWARNING); LocalFree((HLOCAL) pwszMessage); }
SetFocus(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT));
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT) TRUE); return TRUE; } }
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); return TRUE;
case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)FALSE); break;
case PSN_QUERYCANCEL: pviewhelp->fCancelled = TRUE; return FALSE;
case PSN_HELP: if (FIsWin95) { //WinHelpA(hwndDlg, (LPSTR) pcsp->szHelpFileName,
// HELP_CONTEXT, pcsp->dwHelpId);
} else { // WinHelpW(hwndDlg, pcsp->szHelpFileName, HELP_CONTEXT,
// pcsp->dwHelpId);
} return TRUE;
case LVN_ITEMCHANGED: EnableWindow( GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), (ListView_GetSelectedCount( GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE); return TRUE;
case NM_SETFOCUS: //get the window handle of the url list view
if(NULL==(hwndControl=GetDlgItem(hwndDlg, IDC_URL_LIST))) break;
//get the selected cert
listIndex = ListView_GetNextItem( hwndControl, -1, LVNI_FOCUSED );
//select first item to show hilite.
if (listIndex == -1) ListView_SetItemState(hwndControl, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); return TRUE; }
break;
case WM_COMMAND:
pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER); pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext;
switch (LOWORD(wParam)) { case IDHELP: return TRUE;
case IDC_CHECKFORNEWCERTS_CHECK: if (HIWORD(wParam) == BN_CLICKED) { //
// Get current state of check, then enable/disable all
// controls accordingly
//
fChecked = (BST_CHECKED == SendDlgItemMessage( hwndDlg, IDC_CHECKFORNEWCERTS_CHECK, BM_GETCHECK, 0, 0));
EnableWindow(GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT), fChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_UNITS_COMBO), fChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON), fChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON), fChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_NEWURL_EDIT), fChecked); EnableWindow(GetDlgItem(hwndDlg, IDC_URL_LIST), fChecked); if (fChecked) { //
// DSIE: Bug 124669.
//
dwNumUnits = GetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, &fTranslated, FALSE); if (0 == dwNumUnits) { SendDlgItemMessageU( hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL);
SetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, XCERT_DEFAULT_DELTA_HOURS, FALSE); }
EnableWindow( GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), (ListView_GetSelectedCount( GetDlgItem(hwndDlg,IDC_URL_LIST)) == 0) ? FALSE : TRUE); } else { EnableWindow(GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON), FALSE); }
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = TRUE; } pviewhelp->fPropertiesChanged = TRUE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); }
break;
case IDC_USE_DEFAULT_BUTTON: if (HIWORD(wParam) == BN_CLICKED) { //
// Reset to default interval.
//
SendDlgItemMessageU( hwndDlg, IDC_UNITS_COMBO, CB_SETCURSEL, 0, (LPARAM) NULL);
SetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, XCERT_DEFAULT_DELTA_HOURS, FALSE); } break;
case IDC_ADDURL_BUTTON: if (HIWORD(wParam) == BN_CLICKED) { hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
dwLength = (DWORD) SendDlgItemMessage( hwndDlg, IDC_NEWURL_EDIT, WM_GETTEXTLENGTH, 0, NULL);
if (dwLength == 0) { break; }
pwszURL = (LPWSTR) malloc((dwLength + 1) * sizeof(WCHAR)); if (pwszURL == NULL) { break; } GetDlgItemTextU( hwndDlg, IDC_NEWURL_EDIT, pwszURL, dwLength + 1); pwszURL[dwLength] = '\0';
if (!IsValidURL(pwszURL)) { free(pwszURL); LoadStringU(HinstDll, IDS_INVALID_URL_ERROR, errorString, ARRAYSIZE(errorString)); LoadStringU(HinstDll, IDS_CERTIFICATE_PROPERTIES, errorTitle, ARRAYSIZE(errorTitle)); MessageBoxU(hwndDlg, errorString, errorTitle, MB_OK | MB_ICONWARNING); break; }
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_TEXT | LVIF_PARAM; lvI.iItem = ListView_GetItemCount(hWndListView); lvI.pszText = pwszURL; lvI.lParam = (LPARAM) pwszURL;
ListView_InsertItemU(hWndListView, &lvI); ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE); #if (0) //DSIE: Bug 434091
ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE); #endif
SetDlgItemTextU(hwndDlg, IDC_NEWURL_EDIT, L"");
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = TRUE; } pviewhelp->fPropertiesChanged = TRUE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } break;
case IDC_REMOVEURL_BUTTON:
hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_STATE | LVIF_PARAM; lvI.stateMask = LVIS_SELECTED;
for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--) { lvI.iItem = i; if (ListView_GetItemU(hWndListView, &lvI) && (lvI.state & LVIS_SELECTED)) { free((void *) lvI.lParam); ListView_DeleteItem(hWndListView, i); } }
ListView_SetColumnWidth(hWndListView, 0, LVSCW_AUTOSIZE); #if (0) //DSIE: Bug 434091
ListView_SetColumnWidth(hWndListView, 1, LVSCW_AUTOSIZE); #endif
if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = TRUE; } pviewhelp->fPropertiesChanged = TRUE; PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
if (0 == ListView_GetItemCount(hWndListView)) { SetFocus(GetDlgItem(GetParent(hwndDlg), IDOK)); } else { //get the selected cert
listIndex = ListView_GetNextItem( hWndListView, -1, LVNI_FOCUSED );
//select first item to show hilite.
if (listIndex == -1) listIndex = 0;
ListView_SetItemState(hWndListView, listIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED);
SetFocus(GetDlgItem(hwndDlg,IDC_REMOVEURL_BUTTON)); SendMessage(GetDlgItem(hwndDlg,IDC_REMOVEURL_BUTTON), BM_SETSTYLE, BS_DEFPUSHBUTTON, 0); } break;
case IDC_UNITS_COMBO: if (HIWORD(wParam) == CBN_SELCHANGE) { if (!pviewhelp->InWMInit) { dwNumUnits = GetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, &fTranslated, FALSE);
if (0 == SendDlgItemMessage(hwndDlg, IDC_UNITS_COMBO, CB_GETCURSEL, 0, NULL)) { dwSecsPerUnit = 3600; } else { dwSecsPerUnit = 86400; }
if (dwNumUnits > (MAX_DWORD_SIZE / dwSecsPerUnit)) { SetDlgItemInt( hwndDlg, IDC_NUMBEROFUNITS_EDIT, (DWORD) (MAX_DWORD_SIZE / dwSecsPerUnit), FALSE); }
PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } } break;
case IDC_NUMBEROFUNITS_EDIT: if (HIWORD(wParam) == EN_CHANGE) { if (!pviewhelp->InWMInit) { PropSheet_Changed(GetParent(hwndDlg), hwndDlg); } }
break; } break; case WM_DESTROY:
pviewhelp = (PCERT_SETPROPERTIES_HELPER) GetWindowLongPtr(hwndDlg, DWLP_USER); pcsp = (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp; pccert = pcsp->pCertContext;
hWndListView = GetDlgItem(hwndDlg, IDC_URL_LIST);
memset(&lvI, 0, sizeof(lvI)); lvI.mask = LVIF_PARAM; for (i=(ListView_GetItemCount(hWndListView) - 1); i >=0; i--) { lvI.iItem = i; if (ListView_GetItemU(hWndListView, &lvI)) { free((void *) lvI.lParam); } }
//
// if the properties have changed, and there is a pMMCCallback
// then make the callback to MMC
//
if (pviewhelp->fPropertiesChanged && pviewhelp->fGetPagesCalled && (pviewhelp->pcsp->pMMCCallback != NULL) && (pviewhelp->fMMCCallbackMade != TRUE)) { pviewhelp->fMMCCallbackMade = TRUE;
(*(pviewhelp->pcsp->pMMCCallback->pfnCallback))( pviewhelp->pcsp->pMMCCallback->lNotifyHandle, pviewhelp->pcsp->pMMCCallback->param); }
break;
case WM_HELP: case WM_CONTEXTMENU: if (msg == WM_HELP) { hwnd = GetDlgItem(hwndDlg, ((LPHELPINFO)lParam)->iCtrlId); } else { hwnd = (HWND) wParam; }
if ((hwnd != GetDlgItem(hwndDlg, IDC_CHECKFORNEWCERTS_CHECK)) && (hwnd != GetDlgItem(hwndDlg, IDC_NUMBEROFUNITS_EDIT)) && (hwnd != GetDlgItem(hwndDlg, IDC_UNITS_COMBO)) && (hwnd != GetDlgItem(hwndDlg, IDC_USE_DEFAULT_BUTTON)) && (hwnd != GetDlgItem(hwndDlg, IDC_ADDURL_BUTTON)) && (hwnd != GetDlgItem(hwndDlg, IDC_NEWURL_EDIT)) && (hwnd != GetDlgItem(hwndDlg, IDC_URL_LIST)) && (hwnd != GetDlgItem(hwndDlg, IDC_REMOVEURL_BUTTON))) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, (LRESULT)TRUE); return TRUE; } else { return OnContextHelp(hwndDlg, msg, wParam, lParam, helpmapCrossCert); }
break; }
return FALSE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL GetRegisteredClientPages(PROPSHEETPAGEW **ppClientPages, DWORD *pcClientPages, PCCERT_CONTEXT pCertContext) { HCRYPTOIDFUNCSET hCertPropPagesFuncSet; void * pvFuncAddr = NULL; HCRYPTOIDFUNCADDR hFuncAddr = NULL; PROPSHEETPAGEW callbackPages[MAX_CLIENT_PAGES]; DWORD cCallbackPages = MAX_CLIENT_PAGES; DWORD cChars = 0; LPWSTR pwszDllNames = NULL; BOOL fRet = TRUE; LPWSTR pwszCurrentDll; DWORD i; void *pTemp;
//
// initialize incoming variables
//
*ppClientPages = NULL; *pcClientPages = 0;
//
// get a handle to the function table
//
if (NULL == (hCertPropPagesFuncSet = CryptInitOIDFunctionSet( CRYPTUILDLG_CERTPROP_PAGES_CALLBACK, 0))) { goto ErrorReturn; }
//
// get the list of dlls that contain the callback functions
//
if (!CryptGetDefaultOIDDllList( hCertPropPagesFuncSet, 0, NULL, &cChars)) { goto ErrorReturn; }
if (NULL == (pwszDllNames = (LPWSTR) malloc(cChars * sizeof(WCHAR)))) { SetLastError(E_OUTOFMEMORY); goto ErrorReturn; }
if (!CryptGetDefaultOIDDllList( hCertPropPagesFuncSet, 0, pwszDllNames, &cChars)) { goto ErrorReturn; }
//
// loop for each dll and call it to see if it has property pages for this cert
//
pwszCurrentDll = pwszDllNames; while (pwszCurrentDll[0] != L'\0') { //
// try to get the function pointer
//
if (!CryptGetDefaultOIDFunctionAddress( hCertPropPagesFuncSet, 0, pwszCurrentDll, 0, &pvFuncAddr, &hFuncAddr)) { DWORD dwErr = GetLastError(); pwszCurrentDll += wcslen(pwszCurrentDll) + 1; continue; }
//
// call the client to get the their pages
//
cCallbackPages = MAX_CLIENT_PAGES; memset(callbackPages, 0, sizeof(callbackPages)); if (((PFN_CRYPTUIDLG_CERTPROP_PAGES_CALLBACK) pvFuncAddr)(pCertContext, callbackPages, &cCallbackPages)) { //
// if they handed back pages then add them to the array
//
if (cCallbackPages >= 1) { if (*ppClientPages == NULL) { if (NULL == (*ppClientPages = (PROPSHEETPAGEW *) malloc(cCallbackPages * sizeof(PROPSHEETPAGEW)))) { SetLastError(E_OUTOFMEMORY); goto ErrorReturn; } } else { if (NULL == (pTemp = realloc(*ppClientPages, (cCallbackPages + (*pcClientPages)) * sizeof(PROPSHEETPAGEW)))) { SetLastError(E_OUTOFMEMORY); goto ErrorReturn; } *ppClientPages = (PROPSHEETPAGEW *) pTemp; }
memcpy(&((*ppClientPages)[(*pcClientPages)]), &(callbackPages[0]), cCallbackPages * sizeof(PROPSHEETPAGEW)); *pcClientPages += cCallbackPages; } }
//
// free the function that was just called, and move on to the next one in the string
//
CryptFreeOIDFunctionAddress(hFuncAddr, 0); hFuncAddr = NULL; pwszCurrentDll += wcslen(pwszCurrentDll) + 1; }
CleanUp: if (pwszDllNames != NULL) { free(pwszDllNames); }
if (hFuncAddr != NULL) { CryptFreeOIDFunctionAddress(hFuncAddr, 0); } return fRet;
ErrorReturn: fRet = FALSE; goto CleanUp; }
//////////////////////////////////////////////////////////////////////////////////////
// CertSetCertificateProperties
//
// Description:
// This routine will display and allow the user to edit certain properties of
// a certificate
//
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIDlgViewCertificatePropertiesW(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp, BOOL *pfPropertiesChanged) { int cPages = 2; BOOL fRetValue = FALSE; HRESULT hr; PROPSHEETPAGEW * ppage = NULL; PROPSHEETPAGEW * pClientPages = NULL; DWORD cClientPages = 0; INT_PTR ret; WCHAR rgwch[256]; char rgch[256]; CERT_SETPROPERTIES_HELPER viewhelper;
if (pcsp->dwSize != sizeof(CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW)) { SetLastError(E_INVALIDARG); return FALSE; }
if (!CommonInit()) { return FALSE; }
//
// initialize the helper struct
//
memset (&viewhelper, 0, sizeof(viewhelper)); viewhelper.pcsp = pcsp; viewhelper.fSelfCleanup = FALSE; viewhelper.pfPropertiesChanged = pfPropertiesChanged; viewhelper.fGetPagesCalled = FALSE; viewhelper.fMMCCallbackMade = FALSE;
//
// set the properties changed flag to FALSE initially, it will be set
// to TRUE if when the dialog exits anything has been changed
//
viewhelper.fPropertiesChanged = FALSE; if (viewhelper.pfPropertiesChanged != NULL) { *(viewhelper.pfPropertiesChanged) = FALSE; }
//
// get all the pages from registered clients
//
if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext)) { return FALSE; }
//
// Build up the list of pages we are going to use in the dialog
//
ppage = (PROPSHEETPAGEW *) malloc((cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW)); if (ppage == NULL) { goto Exit; }
memset(ppage, 0, (cPages + pcsp->cPropSheetPages + cClientPages) * sizeof(PROPSHEETPAGEW));
ppage[0].dwSize = sizeof(ppage[0]); ppage[0].dwFlags = 0; ppage[0].hInstance = HinstDll; ppage[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG); ppage[0].hIcon = 0; ppage[0].pszTitle = NULL; ppage[0].pfnDlgProc = ViewPageSetPropertiesGeneral; ppage[0].lParam = (LPARAM) &viewhelper; ppage[0].pfnCallback = 0; ppage[0].pcRefParent = NULL; ppage[1].dwSize = sizeof(ppage[0]); ppage[1].dwFlags = 0; ppage[1].hInstance = HinstDll; ppage[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG); ppage[1].hIcon = 0; ppage[1].pszTitle = NULL; ppage[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts; ppage[1].lParam = (LPARAM) &viewhelper; ppage[1].pfnCallback = 0; ppage[1].pcRefParent = NULL;
//
// copy over the users pages
//
memcpy(&ppage[cPages], pcsp->rgPropSheetPages, pcsp->cPropSheetPages * sizeof(PROPSHEETPAGEW)); cPages += pcsp->cPropSheetPages;
//
// copy over the registered client's pages
//
memcpy(&ppage[cPages], pClientPages, cClientPages * sizeof(PROPSHEETPAGEW)); cPages += cClientPages;
if (FIsWin95) {
PROPSHEETHEADERA hdr;
memset(&hdr, 0, sizeof(hdr)); hdr.dwSize = sizeof(hdr); hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow(); hdr.hInstance = HinstDll; hdr.hIcon = NULL; if (pcsp->szTitle != NULL) { hdr.pszCaption = CertUIMkMBStr(pcsp->szTitle); } else { LoadStringA(HinstDll, IDS_CERTIFICATE_PROPERTIES, (LPSTR) rgch, sizeof(rgch)); hdr.pszCaption = (LPSTR) rgch; } hdr.nPages = cPages; hdr.nStartPage = 0; hdr.ppsp = ConvertToPropPageA(ppage, cPages); if (hdr.ppsp == NULL) { if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL)) { free((void *)hdr.pszCaption); } goto Exit; }
hdr.pfnCallback = NULL;
ret = CryptUIPropertySheetA(&hdr);
if ((pcsp->szTitle != NULL) && (hdr.pszCaption != NULL)) { free((void *)hdr.pszCaption); }
FreePropSheetPagesA((PROPSHEETPAGEA *)hdr.ppsp, cPages); } else { PROPSHEETHEADERW hdr;
memset(&hdr, 0, sizeof(hdr)); hdr.dwSize = sizeof(hdr); hdr.dwFlags = PSH_PROPSHEETPAGE;// | PSH_NOAPPLYNOW;
hdr.hwndParent = (pcsp->hwndParent != NULL) ? pcsp->hwndParent : GetDesktopWindow(); hdr.hInstance = HinstDll; hdr.hIcon = NULL; if (pcsp->szTitle) { hdr.pszCaption = pcsp->szTitle; } else { LoadStringW(HinstDll, IDS_CERTIFICATE_PROPERTIES, rgwch, ARRAYSIZE(rgwch)); hdr.pszCaption = rgwch; }
hdr.nPages = cPages; hdr.nStartPage = 0; hdr.ppsp = (PROPSHEETPAGEW *) ppage; hdr.pfnCallback = NULL;
ret = CryptUIPropertySheetW(&hdr); }
if (viewhelper.fCancelled) { SetLastError(ERROR_CANCELLED); }
fRetValue = (ret >= 1);
Exit: if (pClientPages) free(pClientPages);
if (ppage) free(ppage); return fRetValue; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIDlgViewCertificatePropertiesA(PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp, BOOL *pfPropertiesChanged) { BOOL fRet; CRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW cspW;
memcpy(&cspW, pcsp, sizeof(cspW)); if (!ConvertToPropPageW( pcsp->rgPropSheetPages, pcsp->cPropSheetPages, &(cspW.rgPropSheetPages))) { return FALSE; }
cspW.szTitle = CertUIMkWStr(pcsp->szTitle);
fRet = CryptUIDlgViewCertificatePropertiesW(&cspW, pfPropertiesChanged);
if (cspW.szTitle) free((void *)cspW.szTitle);
//DSIE: Prefix bug 428038.
if (cspW.rgPropSheetPages) { FreePropSheetPagesW((LPPROPSHEETPAGEW) cspW.rgPropSheetPages, cspW.cPropSheetPages); }
return fRet; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
UINT CALLBACK GetCertificatePropertiesPagesPropPageCallback( HWND hWnd, UINT uMsg, LPPROPSHEETPAGEW ppsp) { CERT_SETPROPERTIES_HELPER *pviewhelp = (CERT_SETPROPERTIES_HELPER *) ppsp->lParam;
if (pviewhelp->pcsp->pPropPageCallback != NULL) { (*(pviewhelp->pcsp->pPropPageCallback))(hWnd, uMsg, pviewhelp->pcsp->pvCallbackData); }
if (uMsg == PSPCB_RELEASE) { if (pviewhelp->fSelfCleanup) { FreeSetPropertiesStruct((PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pviewhelp->pcsp); free(pviewhelp); } }
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIGetCertificatePropertiesPagesW( PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pcsp, BOOL *pfPropertiesChanged, PROPSHEETPAGEW **prghPropPages, DWORD *pcPropPages ) { BOOL fRetValue = TRUE; HRESULT hr; WCHAR rgwch[CRYPTUI_MAX_STRING_SIZE]; char rgch[CRYPTUI_MAX_STRING_SIZE]; CERT_SETPROPERTIES_HELPER *pviewhelp = NULL; PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW pNewcsp; PROPSHEETPAGEW * pClientPages = NULL; DWORD cClientPages = 0;
*prghPropPages = NULL; *pcPropPages = 0;
if (NULL == (pNewcsp = AllocAndCopySetPropertiesStruct(pcsp))) { goto ErrorReturn; }
if (NULL == (pviewhelp = (CERT_SETPROPERTIES_HELPER *) malloc(sizeof(CERT_SETPROPERTIES_HELPER)))) { goto ErrorReturn; }
*pcPropPages = 2;
if (!CommonInit()) { goto ErrorReturn; }
//
// initialize the helper struct
//
memset (pviewhelp, 0, sizeof(CERT_SETPROPERTIES_HELPER)); pviewhelp->pcsp = pNewcsp; pviewhelp->fSelfCleanup = TRUE; pviewhelp->pfPropertiesChanged = pfPropertiesChanged; pviewhelp->fGetPagesCalled = TRUE; pviewhelp->fMMCCallbackMade = FALSE;
//
// set the properties changed flag to FALSE initially, it will be set
// to TRUE if when the dialog exits anything has been changed
//
pviewhelp->fPropertiesChanged = FALSE; if (pviewhelp->pfPropertiesChanged != NULL) { *(pviewhelp->pfPropertiesChanged) = FALSE; }
//
// get all the pages from registered clients
//
if (!GetRegisteredClientPages(&pClientPages, &cClientPages, pcsp->pCertContext)) { goto ErrorReturn; }
//
// Build up the list of pages we are going to use in the dialog
//
*prghPropPages = (PROPSHEETPAGEW *) malloc(((*pcPropPages) + cClientPages) * sizeof(PROPSHEETPAGEW)); if (*prghPropPages == NULL) { goto ErrorReturn; }
memset(*prghPropPages, 0, ((*pcPropPages) + cClientPages) * sizeof(PROPSHEETPAGEW));
(*prghPropPages)[0].dwSize = sizeof((*prghPropPages)[0]); (*prghPropPages)[0].dwFlags = PSP_USECALLBACK; (*prghPropPages)[0].hInstance = HinstDll; (*prghPropPages)[0].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_DIALOG); (*prghPropPages)[0].hIcon = 0; (*prghPropPages)[0].pszTitle = NULL; (*prghPropPages)[0].pfnDlgProc = ViewPageSetPropertiesGeneral; (*prghPropPages)[0].lParam = (LPARAM) pviewhelp; (*prghPropPages)[0].pfnCallback = GetCertificatePropertiesPagesPropPageCallback; (*prghPropPages)[0].pcRefParent = NULL; (*prghPropPages)[1].dwSize = sizeof((*prghPropPages)[0]); (*prghPropPages)[1].dwFlags = PSP_USECALLBACK; (*prghPropPages)[1].hInstance = HinstDll; (*prghPropPages)[1].pszTemplate = (LPWSTR) MAKEINTRESOURCE(IDD_CERTIFICATE_PROPERTIES_CROSSCERTS_DIALOG); (*prghPropPages)[1].hIcon = 0; (*prghPropPages)[1].pszTitle = NULL; (*prghPropPages)[1].pfnDlgProc = ViewPageSetPropertiesCrossCerts; (*prghPropPages)[1].lParam = (LPARAM) pviewhelp; (*prghPropPages)[1].pfnCallback = NULL; (*prghPropPages)[1].pcRefParent = NULL;
//
// copy over the registered client's pages
//
memcpy(&((*prghPropPages)[*pcPropPages]), pClientPages, cClientPages * sizeof(PROPSHEETPAGEW)); (*pcPropPages) += cClientPages;
CommonReturn:
if (pClientPages != NULL) { free(pClientPages); }
return fRetValue;
ErrorReturn:
if (pNewcsp != NULL) { free(pNewcsp); }
if (pviewhelp != NULL) { free(pviewhelp); }
if (*prghPropPages != NULL) { free(*prghPropPages); *prghPropPages = NULL; }
fRetValue = FALSE; goto CommonReturn; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIGetCertificatePropertiesPagesA( PCCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTA pcsp, BOOL *pfPropertiesChanged, PROPSHEETPAGEA **prghPropPages, DWORD *pcPropPages ) { return (CryptUIGetCertificatePropertiesPagesW( (PCRYPTUI_VIEWCERTIFICATEPROPERTIES_STRUCTW) pcsp, pfPropertiesChanged, (PROPSHEETPAGEW**) prghPropPages, pcPropPages)); }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIFreeCertificatePropertiesPagesW( PROPSHEETPAGEW *rghPropPages, DWORD cPropPages ) { free(rghPropPages);
return TRUE; }
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI CryptUIFreeCertificatePropertiesPagesA( PROPSHEETPAGEA *rghPropPages, DWORD cPropPages ) { return (CryptUIFreeCertificatePropertiesPagesW((PROPSHEETPAGEW *) rghPropPages, cPropPages)); }
|