//------------------------------------------------------------- // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: import.cpp // // Contents: The cpp file to implement the import wizard // // History: 5-11-1997 xiaohs created // //-------------------------------------------------------------- #include "wzrdpvk.h" #include "import.h" #include "xenroll.h" extern HMODULE g_hmodxEnroll; typedef IEnroll2 * (WINAPI *PFNPIEnroll2GetNoCOM)(); //------------------------------------------------------------------------- // DecodeGenericBlob //------------------------------------------------------------------------- DWORD DecodeGenericBlob (IN PCERT_EXTENSION pCertExtension, IN LPCSTR lpszStructType, IN OUT void ** ppStructInfo) { DWORD dwResult = 0; DWORD cbStructInfo = 0; // check parameters. if (!pCertExtension || !lpszStructType || !ppStructInfo) { return E_POINTER; } // // Determine decoded length. // if(!CryptDecodeObject(X509_ASN_ENCODING, lpszStructType, pCertExtension->Value.pbData, pCertExtension->Value.cbData, 0, NULL, &cbStructInfo)) { return GetLastError(); } // // Allocate memory. // if (!(*ppStructInfo = malloc(cbStructInfo))) { return E_OUTOFMEMORY; } // // Decode data. // if(!CryptDecodeObject(X509_ASN_ENCODING, lpszStructType, pCertExtension->Value.pbData, pCertExtension->Value.cbData, 0, *ppStructInfo, &cbStructInfo)) { free(*ppStructInfo); return GetLastError(); } return S_OK; } //------------------------------------------------------------------------- // IsCACert //------------------------------------------------------------------------- BOOL IsCACert(IN PCCERT_CONTEXT pCertContext) { BOOL bResult = FALSE; PCERT_BASIC_CONSTRAINTS2_INFO pInfo = NULL; PCERT_EXTENSION pBasicConstraints = NULL; if (pCertContext) { // // Find the basic constraints extension. // if (pBasicConstraints = CertFindExtension(szOID_BASIC_CONSTRAINTS2, pCertContext->pCertInfo->cExtension, pCertContext->pCertInfo->rgExtension)) { // // Decode the basic constraints extension. // if (S_OK == DecodeGenericBlob(pBasicConstraints, X509_BASIC_CONSTRAINTS2, (void **) &pInfo)) { bResult = pInfo->fCA; free(pInfo); } } else { // // Extension not found. So, for maximum backward compatibility, we assume CA // for V1 cert, and end user for > V1 cert. // bResult = CERT_V1 == pCertContext->pCertInfo->dwVersion; } } return bResult; } //------------------------------------------------------------------------- // Based on the expected content type, get the file filter //------------------------------------------------------------------------- BOOL FileExist(LPWSTR pwszFileName) { HANDLE hFile=NULL; if(NULL == pwszFileName) return FALSE; if ((hFile = ExpandAndCreateFileU(pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, // lpsa OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) return FALSE; CloseHandle(hFile); return TRUE; } //------------------------------------------------------------------------- // Based on the expected content type, get the file filter //------------------------------------------------------------------------- UINT GetFileFilerIDS(DWORD dwFlags) { BOOL fCert=FALSE; BOOL fCRL=FALSE; BOOL fCTL=FALSE; if(CRYPTUI_WIZ_IMPORT_ALLOW_CERT & dwFlags) fCert=TRUE; if(CRYPTUI_WIZ_IMPORT_ALLOW_CRL & dwFlags) fCRL=TRUE; if(CRYPTUI_WIZ_IMPORT_ALLOW_CTL & dwFlags) fCTL=TRUE; if(fCert && fCRL & fCTL) return IDS_IMPORT_FILE_FILTER; if(fCert && fCRL) return IDS_IMPORT_CER_CRL_FILTER; if(fCert && fCTL) return IDS_IMPORT_CER_CTL_FILTER; if(fCRL && fCTL) return IDS_IMPORT_CTL_CRL_FILTER; if(fCert) return IDS_IMPORT_CER_FILTER; if(fCRL) return IDS_IMPORT_CRL_FILTER; if(fCTL) return IDS_IMPORT_CTL_FILTER; return IDS_IMPORT_FILE_FILTER; } //------------------------------------------------------------------------- // Check for the content of the store //------------------------------------------------------------------------- BOOL CheckForContent(HCERTSTORE hSrcStore, DWORD dwFlags, BOOL fFromWizard, UINT *pIDS) { BOOL fResult=FALSE; UINT ids=IDS_INVALID_WIZARD_INPUT; DWORD dwExpectedContent=0; DWORD dwActualContent=0; PCCERT_CONTEXT pCertContext=NULL; PCCTL_CONTEXT pCTLContext=NULL; PCCRL_CONTEXT pCRLContext=NULL; DWORD dwCRLFlag=0; if(!pIDS) return FALSE; if(!hSrcStore) { ids=IDS_INVALID_WIZARD_INPUT; goto CLEANUP; } //get the expected content if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT) dwExpectedContent |= IMPORT_CONTENT_CERT; if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL) dwExpectedContent |= IMPORT_CONTENT_CRL; if(dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL) dwExpectedContent |= IMPORT_CONTENT_CTL; //get the actual content if(pCertContext=CertEnumCertificatesInStore(hSrcStore, NULL)) dwActualContent |= IMPORT_CONTENT_CERT; if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL)) dwActualContent |= IMPORT_CONTENT_CTL; if(pCRLContext=CertGetCRLFromStore(hSrcStore, NULL, NULL, &dwCRLFlag)) dwActualContent |= IMPORT_CONTENT_CRL; //the actual content should be a subset of expected content if(dwActualContent !=(dwExpectedContent & dwActualContent)) { ids=IDS_IMPORT_OBJECT_NOT_EXPECTED; goto CLEANUP; } //make sure the actual content is not empty if(0 == dwActualContent) { if(fFromWizard) ids=IDS_IMPORT_OBJECT_EMPTY; else ids=IDS_IMPORT_PFX_EMPTY; goto CLEANUP; } fResult=TRUE; CLEANUP: if(pCertContext) CertFreeCertificateContext(pCertContext); if(pCTLContext) CertFreeCTLContext(pCTLContext); if(pCRLContext) CertFreeCRLContext(pCRLContext); if(pIDS) *pIDS=ids; return fResult; } //------------------------------------------------------------------------- //Get the store name(s) based on the store handle //------------------------------------------------------------------------- BOOL GetStoreName(HCERTSTORE hCertStore, LPWSTR *ppwszStoreName) { DWORD dwSize=0; //init *ppwszStoreName=NULL; if(NULL==hCertStore) return FALSE; if(!CertGetStoreProperty( hCertStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, &dwSize) || (0==dwSize)) return FALSE; *ppwszStoreName=(LPWSTR)WizardAlloc(dwSize); if(NULL==*ppwszStoreName) return FALSE; **ppwszStoreName=L'\0'; if(CertGetStoreProperty( hCertStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, *ppwszStoreName, &dwSize)) return TRUE; WizardFree(*ppwszStoreName); *ppwszStoreName=NULL; return FALSE; } //------------------------------------------------------------------------- //Get the store name(s) for the store selected by the wizard //------------------------------------------------------------------------- /*BOOL GetDefaultStoreName(CERT_IMPORT_INFO *pCertImportInfo, HCERTSTORE hSrcStore, LPWSTR *ppwszStoreName, UINT *pidsStatus) { HCERTSTORE hMyStore=NULL; HCERTSTORE hCAStore=NULL; HCERTSTORE hTrustStore=NULL; HCERTSTORE hRootStore=NULL; PCCERT_CONTEXT pCertContext=NULL; PCCERT_CONTEXT pCertPre=NULL; PCCRL_CONTEXT pCRLContext=NULL; PCCTL_CONTEXT pCTLContext=NULL; DWORD dwCRLFlag=0; BOOL fResult=FALSE; LPWSTR pwszStoreName=NULL; HCERTSTORE hCertStore=NULL; DWORD dwData=0; DWORD dwCertOpenStoreFlags; //init *ppwszStoreName=NULL; if(NULL==hSrcStore) return FALSE; if (pCertImportInfo->fPFX && (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)) { dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; } else { dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER; } *ppwszStoreName=(LPWSTR)WizardAlloc(sizeof(WCHAR)); **ppwszStoreName=L'\0'; //we need to find a correct store on user's behalf //put the CTLs in the trust store if(pCTLContext=CertEnumCTLsInStore(hSrcStore, NULL)) { //open trust store if necessary if(NULL==hTrustStore) { if(!(hTrustStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG, L"trust"))) { *pidsStatus=IDS_FAIL_OPEN_TRUST; goto CLEANUP; } //get the store name if(GetStoreName(hTrustStore, &pwszStoreName)) { *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName, sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3)); if(NULL==*ppwszStoreName) { *pidsStatus=IDS_OUT_OF_MEMORY; goto CLEANUP; } wcscat(*ppwszStoreName, pwszStoreName); } } } //free memory if(pwszStoreName) { WizardFree(pwszStoreName); pwszStoreName=NULL; } //put CRL in the CA store if(pCRLContext=CertGetCRLFromStore(hSrcStore, NULL, NULL, &dwCRLFlag)) { //open ca store if necessary if(NULL==hCAStore) { if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG, L"ca"))) { *pidsStatus=IDS_FAIL_OPEN_CA; goto CLEANUP; } //get the store name if(GetStoreName(hCAStore, &pwszStoreName)) { *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName, sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +3)); if(NULL==*ppwszStoreName) { *pidsStatus=IDS_OUT_OF_MEMORY; goto CLEANUP; } if(wcslen(*ppwszStoreName) !=0 ) wcscat(*ppwszStoreName, L", "); wcscat(*ppwszStoreName, pwszStoreName); } } } //free memory if(pwszStoreName) { WizardFree(pwszStoreName); pwszStoreName=NULL; } //add the certificate with private key to my store; and the rest //to the ca store while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre)) { //break if we have opened both MY and CA store and hRootStore if(hCAStore && hMyStore && hRootStore) break; if(TrustIsCertificateSelfSigned(pCertContext, pCertContext->dwCertEncodingType, 0)) { //open the root store if necessary if(NULL==hRootStore) { if(!(hRootStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags | CERT_STORE_SET_LOCALIZED_NAME_FLAG, L"root")) ) { *pidsStatus=IDS_FAIL_OPEN_ROOT; goto CLEANUP; } hCertStore=hRootStore; } else { pCertPre=pCertContext; continue; } } else { //check if the certificate has the property on it //make sure the private key matches the certificate //search for both machine key and user keys if(CertGetCertificateContextProperty( pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwData) && CryptFindCertificateKeyProvInfo( pCertContext, 0, NULL)) { //open my store if necessary if(NULL==hMyStore) { if(!(hMyStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG, L"my"))) { *pidsStatus=IDS_FAIL_OPEN_MY; goto CLEANUP; } hCertStore=hMyStore; } else { pCertPre=pCertContext; continue; } } else { //open ca store if necessary if(NULL==hCAStore) { if(!(hCAStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags |CERT_STORE_SET_LOCALIZED_NAME_FLAG, L"ca")) ) { *pidsStatus=IDS_FAIL_OPEN_CA; goto CLEANUP; } hCertStore=hCAStore; } else { pCertPre=pCertContext; continue; } } } //get the store name if(GetStoreName(hCertStore, &pwszStoreName)) { *ppwszStoreName=(LPWSTR)WizardRealloc(*ppwszStoreName, sizeof(WCHAR)*(wcslen(*ppwszStoreName)+wcslen(pwszStoreName)+wcslen(L", ") +1)); if(NULL==*ppwszStoreName) { *pidsStatus=IDS_OUT_OF_MEMORY; goto CLEANUP; } if(wcslen(*ppwszStoreName) !=0 ) wcscat(*ppwszStoreName, L", "); wcscat(*ppwszStoreName, pwszStoreName); } pCertPre=pCertContext; } fResult=TRUE; CLEANUP: if(pCertContext) CertFreeCertificateContext(pCertContext); if(pCTLContext) CertFreeCTLContext(pCTLContext); if(pCRLContext) CertFreeCRLContext(pCRLContext); if(hMyStore) CertCloseStore(hMyStore, 0); if(hCAStore) CertCloseStore(hCAStore, 0); if(hTrustStore) CertCloseStore(hTrustStore, 0); if(hRootStore) CertCloseStore(hRootStore, 0); //free memory if(pwszStoreName) { WizardFree(pwszStoreName); pwszStoreName=NULL; } return fResult; } */ //------------------------------------------------------------------------- //Get the store name and insert it to the ListView //------------------------------------------------------------------------- void SetImportStoreName(HWND hwndControl, HCERTSTORE hCertStore) { LPWSTR pwszStoreName=NULL; DWORD dwSize=0; // LV_ITEMW lvItem; // LV_COLUMNW lvC; if(!CertGetStoreProperty( hCertStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, &dwSize) || (0==dwSize)) { //Get the string pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH * sizeof(WCHAR)); if(pwszStoreName) { *pwszStoreName=L'\0'; LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH); } } else { pwszStoreName=(LPWSTR)WizardAlloc(dwSize); if(pwszStoreName) { *pwszStoreName=L'\0'; CertGetStoreProperty( hCertStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, pwszStoreName, &dwSize); } } if(pwszStoreName) SetWindowTextU(hwndControl,pwszStoreName); if(pwszStoreName) WizardFree(pwszStoreName); //clear the ListView /*ListView_DeleteAllItems(hwndControl); //insert one column to the store name ListView //set the store name //only one column is needed memset(&lvC, 0, sizeof(LV_COLUMNW)); lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; // Left-align the column. lvC.cx = 20; // Width of the column, in pixels. lvC.pszText = L""; // The text for the column. lvC.iSubItem=0; if (ListView_InsertColumnU(hwndControl, 0, &lvC) == -1) { if(pwszStoreName) WizardFree(pwszStoreName); return; } //insert the store name memset(&lvItem, 0, sizeof(LV_ITEMW)); // set up the fields in the list view item struct that don't change from item to item lvItem.mask = LVIF_TEXT | LVIF_STATE ; lvItem.state = 0; lvItem.stateMask = 0; lvItem.iItem=0; lvItem.iSubItem=0; lvItem.pszText=pwszStoreName; ListView_InsertItemU(hwndControl, &lvItem); //autosize the column ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); */ } //------------------------------------------------------------------------- // Check to see if this is an EFS only cert. //------------------------------------------------------------------------- BOOL IsEFSOnly(PCCERT_CONTEXT pCertContext) { BOOL fResult = FALSE; PCERT_ENHKEY_USAGE pEKU = NULL; DWORD cbEKU = 0; DWORD dwError = 0; if (!pCertContext) { dwError = ERROR_INVALID_PARAMETER; goto CLEANUP; } if (!CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, NULL, &cbEKU)) { dwError = GetLastError(); goto CLEANUP; } if (!(pEKU = (PCERT_ENHKEY_USAGE) malloc(cbEKU))) { dwError = ERROR_NOT_ENOUGH_MEMORY; goto CLEANUP; } if (!CertGetEnhancedKeyUsage(pCertContext, CERT_FIND_EXT_ONLY_ENHKEY_USAGE_FLAG, pEKU, &cbEKU)) { dwError = GetLastError(); goto CLEANUP; } if ((1 == pEKU->cUsageIdentifier) && (0 == strcmp(pEKU->rgpszUsageIdentifier[0], szOID_KP_EFS))) { fResult = TRUE; } CLEANUP: if (pEKU) { free(pEKU); } SetLastError(dwError); return fResult; } #if (0) //DSIE: dead code. //------------------------------------------------------------------------- //Search for the duplicated elements in the destination store //------------------------------------------------------------------------- BOOL ExistInDes(HCERTSTORE hSrcStore, HCERTSTORE hDesStore) { BOOL fResult=FALSE; DWORD dwCRLFlag=0; PCCERT_CONTEXT pCertContext=NULL; PCCERT_CONTEXT pCertPre=NULL; PCCERT_CONTEXT pFindCert=NULL; PCCRL_CONTEXT pCRLContext=NULL; PCCRL_CONTEXT pCRLPre=NULL; PCCRL_CONTEXT pFindCRL=NULL; PCCTL_CONTEXT pCTLContext=NULL; PCCTL_CONTEXT pCTLPre=NULL; PCCTL_CONTEXT pFindCTL=NULL; //add the certs while(pCertContext=CertEnumCertificatesInStore(hSrcStore, pCertPre)) { if((pFindCert=CertFindCertificateInStore(hDesStore, X509_ASN_ENCODING, 0, CERT_FIND_EXISTING, pCertContext, NULL))) { fResult=TRUE; goto CLEANUP; } pCertPre=pCertContext; } //add the CTLs while(pCTLContext=CertEnumCTLsInStore(hSrcStore, pCTLPre)) { if((pFindCTL=CertFindCTLInStore(hDesStore, g_dwMsgAndCertEncodingType, 0, CTL_FIND_EXISTING, pCTLContext, NULL))) { fResult=TRUE; goto CLEANUP; } pCTLPre=pCTLContext; } //add the CRLs while(pCRLContext=CertGetCRLFromStore(hSrcStore, NULL, pCRLPre, &dwCRLFlag)) { if((pFindCRL=CertFindCRLInStore(hDesStore, X509_ASN_ENCODING, 0, CRL_FIND_EXISTING, pCRLContext, NULL))) { fResult=TRUE; goto CLEANUP; } pCRLPre=pCRLContext; } //we can not find a match CLEANUP: if(pCertContext) CertFreeCertificateContext(pCertContext); if(pFindCert) CertFreeCertificateContext(pFindCert); if(pCTLContext) CertFreeCTLContext(pCTLContext); if(pFindCTL) CertFreeCTLContext(pFindCTL); if(pCRLContext) CertFreeCRLContext(pCRLContext); if(pFindCRL) CertFreeCRLContext(pFindCRL); return fResult; } #endif //------------------------------------------------------------------------- //populate the list box in the order of FileName, FileType, and Store information //------------------------------------------------------------------------- void DisplayImportConfirmation(HWND hwndControl, CERT_IMPORT_INFO *pCertImportInfo) { DWORD dwIndex=0; DWORD dwSize=0; UINT ids=0; LPWSTR pwszStoreName=NULL; WCHAR wszFileType[MAX_STRING_SIZE]; WCHAR wszSelectedByWizard[MAX_STRING_SIZE]; LV_ITEMW lvItem; BOOL fNewItem=FALSE; //delete all the old items in the listView ListView_DeleteAllItems(hwndControl); //get the ids of the format type switch(pCertImportInfo->dwContentType) { case CERT_QUERY_CONTENT_CERT: ids=IDS_ENCODE_CERT; break; case CERT_QUERY_CONTENT_CTL: ids=IDS_ENCODE_CTL; break; case CERT_QUERY_CONTENT_CRL: ids=IDS_ENCODE_CRL; break; case CERT_QUERY_CONTENT_SERIALIZED_STORE: ids=IDS_SERIALIZED_STORE; break; case CERT_QUERY_CONTENT_SERIALIZED_CERT: ids=IDS_SERIALIZED_CERT; break; case CERT_QUERY_CONTENT_SERIALIZED_CTL: ids=IDS_SERIALIZED_CTL; break; case CERT_QUERY_CONTENT_SERIALIZED_CRL: ids=IDS_SERIALIZED_CRL; break; case CERT_QUERY_CONTENT_PKCS7_SIGNED : ids=IDS_PKCS7_SIGNED; break; case CERT_QUERY_CONTENT_PFX: ids=IDS_PFX_BLOB; break; default: // case CERT_QUERY_CONTENT_PKCS7_UNSIGNED // case CERT_QUERY_CONTENT_PKCS7_SIGNED_EMBED // case CERT_QUERY_CONTENT_PKCS10 ids=IDS_NONE; break; } //get the format type LoadStringU(g_hmodThisDll, ids, wszFileType, MAX_STRING_SIZE); //get the store name if(pCertImportInfo->hDesStore) { if(!CertGetStoreProperty( pCertImportInfo->hDesStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, NULL, &dwSize) || (0==dwSize)) { //Get the string pwszStoreName=(LPWSTR)WizardAlloc(MAX_TITLE_LENGTH); if(pwszStoreName) { *pwszStoreName=L'\0'; LoadStringU(g_hmodThisDll, IDS_UNKNOWN, pwszStoreName, MAX_TITLE_LENGTH); } } else { pwszStoreName=(LPWSTR)WizardAlloc(dwSize); if(pwszStoreName) { *pwszStoreName=L'\0'; CertGetStoreProperty( pCertImportInfo->hDesStore, CERT_STORE_LOCALIZED_NAME_PROP_ID, pwszStoreName, &dwSize); } } } //insert row by row memset(&lvItem, 0, sizeof(LV_ITEMW)); // set up the fields in the list view item struct that don't change from item to item lvItem.mask = LVIF_TEXT | LVIF_STATE ; lvItem.state = 0; lvItem.stateMask = 0; lvItem.iItem=0; lvItem.iSubItem=0; //file name if(pCertImportInfo->pwszFileName) { lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_FILE_NAME, NULL); //content lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCertImportInfo->pwszFileName); } //file type if(wszFileType) { lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CONTENT_TYPE, NULL); //content lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszFileType); } //StoreName lvItem.iItem=lvItem.iItem ? lvItem.iItem++ : 0; lvItem.iSubItem=0; if(NULL==pCertImportInfo->hDesStore || (FALSE==pCertImportInfo->fSelectedDesStore)) { ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_WIZARD, NULL); /* if(pCertImportInfo->pwszDefaultStoreName) { lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCertImportInfo->pwszDefaultStoreName); } else */ //get the format type if(LoadStringU(g_hmodThisDll, IDS_SELECTED_BY_WIZARD, wszSelectedByWizard, MAX_STRING_SIZE)) { lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszSelectedByWizard); } } else { ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_STORE_BY_USER, NULL); //content if(pwszStoreName) { lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pwszStoreName); } } //auto size the columns in the ListView ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE); if(pwszStoreName) WizardFree(pwszStoreName); return; } //************************************************************************* // // The winproc for import wizards //************************************************************************ //----------------------------------------------------------------------- //Import_Welcome //----------------------------------------------------------------------- INT_PTR APIENTRY Import_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CERT_IMPORT_INFO *pCertImportInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam); //make sure pCertImportInfo is a valid pointer if(NULL==pCertImportInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo); SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1); SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1); SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD2); break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; break; case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT); break; case PSN_WIZBACK: break; case PSN_WIZNEXT: break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // Import_File //----------------------------------------------------------------------- INT_PTR APIENTRY Import_File(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CERT_IMPORT_INFO *pCertImportInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; OPENFILENAMEW OpenFileName; WCHAR szFileName[_MAX_PATH]; HWND hwndControl=NULL; DWORD dwChar=0; LPWSTR pwszInitialDir = NULL; WCHAR szFilter[MAX_STRING_SIZE + MAX_STRING_SIZE]; //"Certificate File (*.cer)\0*.cer\0Certificate File (*.crt)\0*.crt\0All Files\0*.*\0" DWORD dwSize=0; UINT ids=0; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam); //make sure pCertImportInfo is a valid pointer if(NULL==pCertImportInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo); SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1); //set up the file name if pre-selected SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertImportInfo->pwszFileName); break; case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { if(LOWORD(wParam) == IDC_WIZARD_BUTTON1) { if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //the browse button is clicked. Open the FileOpen dialogue memset(&OpenFileName, 0, sizeof(OpenFileName)); *szFileName=L'\0'; OpenFileName.lStructSize=sizeof(OpenFileName); OpenFileName.hwndOwner=hwndDlg; OpenFileName.nFilterIndex = 1; //get the file filer ID ids=GetFileFilerIDS(pCertImportInfo->dwFlag); //load the filter string if(LoadFilterString(g_hmodThisDll, ids, szFilter, MAX_STRING_SIZE + MAX_STRING_SIZE)) { OpenFileName.lpstrFilter = szFilter; } dwChar = (DWORD)SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, WM_GETTEXTLENGTH, 0, 0); if (NULL != (pwszInitialDir = (LPWSTR) WizardAlloc((dwChar+1)*sizeof(WCHAR)))) { GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pwszInitialDir, dwChar+1); } OpenFileName.lpstrInitialDir = pwszInitialDir; OpenFileName.lpstrFile=szFileName; OpenFileName.nMaxFile=_MAX_PATH; OpenFileName.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST; //user has selected a file name if(WizGetOpenFileName(&OpenFileName)) { //set the edit box SetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, szFileName); } if(pwszInitialDir != NULL) { WizardFree(pwszInitialDir); pwszInitialDir = NULL; } } } break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; break; case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK); break; case PSN_WIZBACK: break; case PSN_WIZNEXT: if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //make sure a file is selected if(0==(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, WM_GETTEXTLENGTH, 0, 0))) { I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_FILE, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } //get the file name if(pCertImportInfo->pwszFileName) { //delete the old file name if(TRUE==pCertImportInfo->fFreeFileName) { WizardFree(pCertImportInfo->pwszFileName); pCertImportInfo->pwszFileName=NULL; } } pCertImportInfo->pwszFileName=(LPWSTR)WizardAlloc((dwChar+1)*sizeof(WCHAR)); if(NULL!=(pCertImportInfo->pwszFileName)) { GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertImportInfo->pwszFileName, dwChar+1); pCertImportInfo->fFreeFileName=TRUE; //make sure the file is valid //delete the old store if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore)) { CertCloseStore(pCertImportInfo->hSrcStore, 0); pCertImportInfo->hSrcStore=NULL; } //we import anything but PKCS10 or signed document if(!ExpandAndCryptQueryObject( CERT_QUERY_OBJECT_FILE, pCertImportInfo->pwszFileName, dwExpectedContentType, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &(pCertImportInfo->dwContentType), NULL, &(pCertImportInfo->hSrcStore), NULL, NULL)) { if(FileExist(pCertImportInfo->pwszFileName)) I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); else I_MessageBox(hwndDlg, IDS_NON_EXIST_FILE, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } //we re-mark the pPFX pCertImportInfo->fPFX=FALSE; //get the blobs from the pfx file if(CERT_QUERY_CONTENT_PFX==pCertImportInfo->dwContentType) { //we can not import PFX Files for remote case if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE) { //output the message I_MessageBox(hwndDlg, IDS_IMPORT_NO_PFX_FOR_REMOTE, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } if((pCertImportInfo->blobData).pbData) { UnmapViewOfFile((pCertImportInfo->blobData).pbData); (pCertImportInfo->blobData).pbData=NULL; } if(S_OK !=RetrieveBLOBFromFile( pCertImportInfo->pwszFileName, &((pCertImportInfo->blobData).cbData), &((pCertImportInfo->blobData).pbData))) { //output the message I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } //make sure that the soure store's content match with //the expectation if(0==((pCertImportInfo->dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) { //output the message I_MessageBox(hwndDlg, IDS_IMPORT_OBJECT_NOT_EXPECTED, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } else { //if the content is PKCS7, get the BLOB if(CERT_QUERY_CONTENT_PKCS7_SIGNED==pCertImportInfo->dwContentType) { if((pCertImportInfo->blobData).pbData) { UnmapViewOfFile((pCertImportInfo->blobData).pbData); (pCertImportInfo->blobData).pbData=NULL; } if(S_OK !=RetrieveBLOBFromFile( pCertImportInfo->pwszFileName, &((pCertImportInfo->blobData).cbData), &((pCertImportInfo->blobData).pbData))) { //output the message I_MessageBox(hwndDlg, IDS_FAIL_READ_FILE_ENTER, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } //make sure we do have a source store if(NULL==pCertImportInfo->hSrcStore) { //output the message I_MessageBox(hwndDlg, IDS_FAIL_TO_RECOGNIZE_ENTER, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } //remember to free the Src store pCertImportInfo->fFreeSrcStore=TRUE; //make sure that the soure store's content match with //the expectation ids=0; if(!CheckForContent(pCertImportInfo->hSrcStore, pCertImportInfo->dwFlag, TRUE, &ids)) { //output the message I_MessageBox(hwndDlg, ids, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } } //skip the next page if password is not necessary if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_STORE); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // Import_Password //----------------------------------------------------------------------- INT_PTR APIENTRY Import_Password(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CERT_IMPORT_INFO *pCertImportInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; HWND hwndControl=NULL; DWORD dwChar; UINT ids=0; switch (msg) { case WM_INITDIALOG: HRESULT hr; HKEY hKey; DWORD cb; DWORD dwKeyValue; DWORD dwType; //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam); //make sure pCertImportInfo is a valid pointer if(NULL==pCertImportInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo); SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1); //init the passWord SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 64, (LPARAM) 0); SetDlgItemTextU( hwndDlg, IDC_WIZARD_EDIT1, (pCertImportInfo->pwszPassword != NULL) ? pCertImportInfo->pwszPassword : L""); #if (1) //DSIE: Bug 333621 SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, EM_LIMITTEXT, (WPARAM) 32, (LPARAM) 0); #endif //init the passWord flag if(pCertImportInfo->dwPasswordFlags & CRYPT_EXPORTABLE) SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 1, 0); else SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_SETCHECK, 0, 0); if(pCertImportInfo->dwPasswordFlags & CRYPT_USER_PROTECTED) SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0); else SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 0, 0); //now, we need to grey out the user protection check box for the local //machine import if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE) EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE); else { // // Not Import to Local Machine // Open the CRYPTOAPI_PRIVATE_KEY_OPTIONS registry key under HKLM // hKey = NULL; hr = RegOpenKeyEx( HKEY_LOCAL_MACHINE, szKEY_CRYPTOAPI_PRIVATE_KEY_OPTIONS, 0, KEY_QUERY_VALUE, &hKey); if ( S_OK != hr ) goto error; // // Query the registry key for FORCE_KEY_PROTECTION value // cb = sizeof(dwKeyValue); hr = RegQueryValueEx( hKey, szFORCE_KEY_PROTECTION, NULL, &dwType, (BYTE *) &dwKeyValue, &cb); if( S_OK == hr && REG_DWORD == dwType && sizeof(dwKeyValue) == cb ) { switch( dwKeyValue ) { case dwFORCE_KEY_PROTECTION_DISABLED: // do not force key protection break; case dwFORCE_KEY_PROTECTION_USER_SELECT: // allow the user to select key protection UI, default = yes SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0); break; case dwFORCE_KEY_PROTECTION_HIGH: // set to force key protection and grey out choice so that user cannot change value EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), FALSE); SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_SETCHECK, 1, 0); break; default: // Unknown value in registry break; } } error: if( NULL != hKey ){ RegCloseKey(hKey); } } break; case WM_COMMAND: break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; break; case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK); break; case PSN_WIZBACK: break; case PSN_WIZNEXT: if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //free the memory if(pCertImportInfo->pwszPassword) { // DSIE: Bug 534689. SecureZeroMemory(pCertImportInfo->pwszPassword, lstrlenW(pCertImportInfo->pwszPassword) * sizeof(WCHAR)); WizardFree(pCertImportInfo->pwszPassword); pCertImportInfo->pwszPassword=NULL; } //get the password if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, IDC_WIZARD_EDIT1, WM_GETTEXTLENGTH, 0, 0))) { pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR)*(dwChar+1)); if(NULL!=pCertImportInfo->pwszPassword) { GetDlgItemTextU(hwndDlg, IDC_WIZARD_EDIT1, pCertImportInfo->pwszPassword, dwChar+1); } else break; } else pCertImportInfo->pwszPassword=NULL; //if user request to export the private key if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK_EXPORTKEY), BM_GETCHECK, 0, 0)) pCertImportInfo->dwPasswordFlags |=CRYPT_EXPORTABLE; else pCertImportInfo->dwPasswordFlags &= (~CRYPT_EXPORTABLE); if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_CHECK2), BM_GETCHECK, 0, 0)) pCertImportInfo->dwPasswordFlags |=CRYPT_USER_PROTECTED; else pCertImportInfo->dwPasswordFlags &= (~CRYPT_USER_PROTECTED); //delete the old certificate store if(pCertImportInfo->hSrcStore && (TRUE==pCertImportInfo->fFreeSrcStore)) { CertCloseStore(pCertImportInfo->hSrcStore, 0); pCertImportInfo->hSrcStore=NULL; } //decode the PFX blob if(NULL==(pCertImportInfo->blobData).pbData) break; //convert the PFX BLOB to a certificate store pCertImportInfo->fPFX=PFXVerifyPassword( (CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData), pCertImportInfo->pwszPassword, 0); if((FALSE==pCertImportInfo->fPFX) && (NULL == pCertImportInfo->pwszPassword)) { //we try to use "" for no password case pCertImportInfo->pwszPassword=(LPWSTR)WizardAlloc(sizeof(WCHAR)); if(NULL != pCertImportInfo->pwszPassword) { *(pCertImportInfo->pwszPassword)=L'\0'; pCertImportInfo->fPFX=PFXVerifyPassword( (CRYPT_DATA_BLOB *)&(pCertImportInfo->blobData), pCertImportInfo->pwszPassword, 0); } } if(FALSE==pCertImportInfo->fPFX) { //output the message I_MessageBox(hwndDlg, IDS_INVALID_PASSWORD, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // Import_Store //----------------------------------------------------------------------- INT_PTR APIENTRY Import_Store(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CERT_IMPORT_INFO *pCertImportInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; HWND hwndControl=NULL; DWORD dwSize=0; CRYPTUI_SELECTSTORE_STRUCT CertStoreSelect; STORENUMERATION_STRUCT StoreEnumerationStruct; STORESFORSELCTION_STRUCT StoresForSelectionStruct; HCERTSTORE hCertStore=NULL; HDC hdc=NULL; COLORREF colorRef; LV_COLUMNW lvC; UINT idsError=0; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam); //make sure pCertImportInfo is a valid pointer if(NULL==pCertImportInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo); SetControlFont(pCertImportInfo->hBold, hwndDlg,IDC_WIZARD_STATIC_BOLD1); //getthe background color of the parent window //the background of the list view for store name is grayed /* if(hdc=GetWindowDC(hwndDlg)) { if(CLR_INVALID!=(colorRef=GetBkColor(hdc))) { ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE); ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE); } } */ //mark the store selection if(pCertImportInfo->hDesStore) { //disable the 1st radio button SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0); //select raio2 SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0); //enable the windows for select a certificate store EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE); //mark the store name hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1); if(hwndControl) SetImportStoreName(hwndControl, pCertImportInfo->hDesStore); //diable the radio buttons if CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST //is set if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE) { EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE); } } else { //select the 1st radio button SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0); SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0); //disable the windows for select a certificate store EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE); } break; case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { switch (LOWORD(wParam)) { case IDC_WIZARD_RADIO1: //select the 1st radio button SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 1, 0); //disable raio2 SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 0, 0); //disable the windows for select a certificate store EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), FALSE); break; case IDC_WIZARD_RADIO2: //disable the 1st radio button SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_SETCHECK, 0, 0); //select raio2 SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO2), BM_SETCHECK, 1, 0); //enable the windows for select a certificate store EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_STATIC1), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), TRUE); //if no change of the desination is set, we need to diable the browse //button and 1st radio button if(NULL!=(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) { if(pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE) { EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_WIZARD_BUTTON1), FALSE); } } break; case IDC_WIZARD_BUTTON1: if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) { break; } //get the hwndControl for the list view hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1); //call the store selection dialogue memset(&CertStoreSelect, 0, sizeof(CertStoreSelect)); memset(&StoresForSelectionStruct, 0, sizeof(StoresForSelectionStruct)); memset(&StoreEnumerationStruct, 0, sizeof(StoreEnumerationStruct)); StoreEnumerationStruct.dwFlags=CERT_STORE_MAXIMUM_ALLOWED_FLAG; StoreEnumerationStruct.pvSystemStoreLocationPara=NULL; StoresForSelectionStruct.cEnumerationStructs = 1; StoresForSelectionStruct.rgEnumerationStructs = &StoreEnumerationStruct; // if a pfx import is taking place, then make sure the correct // stores are displayed for selection if ((TRUE == pCertImportInfo->fPFX) && (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)) { StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_LOCAL_MACHINE; } else { StoreEnumerationStruct.dwFlags |= CERT_SYSTEM_STORE_CURRENT_USER; } CertStoreSelect.dwSize=sizeof(CertStoreSelect); CertStoreSelect.hwndParent=hwndDlg; CertStoreSelect.dwFlags=CRYPTUI_VALIDATE_STORES_AS_WRITABLE | CRYPTUI_ALLOW_PHYSICAL_STORE_VIEW | CRYPTUI_DISPLAY_WRITE_ONLY_STORES; CertStoreSelect.pStoresForSelection = &StoresForSelectionStruct; hCertStore=CryptUIDlgSelectStore(&CertStoreSelect); if(hCertStore) { //delete the old destination certificate store if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fFreeDesStore)) { CertCloseStore(pCertImportInfo->hDesStore, 0); pCertImportInfo->hDesStore=NULL; } pCertImportInfo->hDesStore=hCertStore; pCertImportInfo->fFreeDesStore=TRUE; //get the store name if(hwndControl) SetImportStoreName(hwndControl, pCertImportInfo->hDesStore); } break; default: break; } } break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; break; case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_NEXT|PSWIZB_BACK); break; case PSN_WIZBACK: if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) { break; } //skip the next page if password is not necessary if(CERT_QUERY_CONTENT_PFX != pCertImportInfo->dwContentType) { //jump to the welcome page if the source is not from a file if((pCertImportInfo->hSrcStore && (NULL==pCertImportInfo->pwszFileName)) || ((pCertImportInfo->fKnownSrc)&&(pCertImportInfo->pwszFileName)&&(CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType)) ) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_WELCOME); } else { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_IMPORT_FILE); } } break; case PSN_WIZNEXT: if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) { break; } //make sure that we have select some store if(TRUE==SendMessage(GetDlgItem(hwndDlg, IDC_WIZARD_RADIO1), BM_GETCHECK, 0, 0)) { //mark that the des store is not selected pCertImportInfo->fSelectedDesStore=FALSE; /*if(pCertImportInfo->pwszDefaultStoreName) { WizardFree(pCertImportInfo->pwszDefaultStoreName); pCertImportInfo->pwszDefaultStoreName=NULL; }*/ //we will not know the default store name //if PFX was selected /*if(pCertImportInfo->hSrcStore) { if(!GetDefaultStoreName( pCertImportInfo, pCertImportInfo->hSrcStore, &(pCertImportInfo->pwszDefaultStoreName), &idsError)) { //output the message I_MessageBox(hwndDlg, idsError, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } */ } else { //make sure we have something selected if(NULL==pCertImportInfo->hDesStore) { //output the message I_MessageBox(hwndDlg, IDS_HAS_TO_SELECT_STORE, IDS_IMPORT_WIZARD_TITLE, NULL, MB_ICONERROR|MB_OK|MB_APPLMODAL); //make the file page stay SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } else { pCertImportInfo->fSelectedDesStore=TRUE; } } break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // Import_Completion //----------------------------------------------------------------------- INT_PTR APIENTRY Import_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CERT_IMPORT_INFO *pCertImportInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; HWND hwndControl=NULL; LV_COLUMNW lvC; HDC hdc=NULL; COLORREF colorRef; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCertImportInfo = (CERT_IMPORT_INFO *) (pPropSheet->lParam); //make sure pCertImportInfo is a valid pointer if(NULL==pCertImportInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCertImportInfo); SetControlFont(pCertImportInfo->hBigBold, hwndDlg,IDC_WIZARD_STATIC_BIG_BOLD1); //getthe background color of the parent window /* if(hdc=GetWindowDC(hwndDlg)) { if(CLR_INVALID!=(colorRef=GetBkColor(hdc))) { ListView_SetBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE); ListView_SetTextBkColor(GetDlgItem(hwndDlg, IDC_WIZARD_LIST1), CLR_NONE); } } */ //insert two columns for the confirmation if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)) { //1st one is the label for the confirmation memset(&lvC, 0, sizeof(LV_COLUMNW)); lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; // Left-align the column. lvC.cx = 20; // Width of the column, in pixels. lvC.pszText = L""; // The text for the column. lvC.iSubItem=0; ListView_InsertColumnU(hwndControl, 0, &lvC); //2nd column is the content memset(&lvC, 0, sizeof(LV_COLUMNW)); lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; lvC.fmt = LVCFMT_LEFT; // Left-align the column. lvC.cx = 20; // Width of the column, in pixels. lvC.pszText = L""; // The text for the column. lvC.iSubItem= 1; ListView_InsertColumnU(hwndControl, 1, &lvC); } break; case WM_COMMAND: break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case PSN_KILLACTIVE: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; break; case PSN_RESET: SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); break; case PSN_SETACTIVE: PropSheet_SetWizButtons(GetParent(hwndDlg), PSWIZB_BACK|PSWIZB_FINISH); if(NULL==(pCertImportInfo=(CERT_IMPORT_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) { break; } //populate the list box in the order of //FileName, FileType, and store info if(hwndControl=GetDlgItem(hwndDlg, IDC_WIZARD_LIST1)) { DisplayImportConfirmation(hwndControl, pCertImportInfo); ListView_SetItemState(hwndControl, 0, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); } break; case PSN_WIZBACK: break; case PSN_WIZFINISH: break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //-------------------------------------------------------------------------------- // // Add a specified Cert/CTL/CRL context to specified destination store, and prompt // user for permission if attempting to replace an older context over a newer // context, if UI is allowed. // //--------------------------------------------------------------------------------- DWORD AddContextToStore(IN DWORD dwContextType, IN HWND hwndParent, IN PVOID pContext, IN BOOL fUIAllowed, IN HCERTSTORE hDstStore) { DWORD dwRetCode = 0; switch (dwContextType) { case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT: { // // Add cert context to store. // if (!CertAddCertificateContextToStore(hDstStore, (PCCERT_CONTEXT) pContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) { dwRetCode = GetLastError(); break; } break; } case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT: { if (!CertAddCTLContextToStore(hDstStore, (PCCTL_CONTEXT) pContext, CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES, NULL)) { // // If there is a newer copy in the store, then prompt user for permission // to replace, if UI is allowed. // if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError())) { dwRetCode = GetLastError(); break; } if (IDYES != I_MessageBox(hwndParent, IDS_IMPORT_REPLACE_EXISTING_NEWER_CTL, IDS_IMPORT_WIZARD_TITLE, NULL, MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2)) { dwRetCode = ERROR_CANCELLED; break; } // // Try with REPLACE_EXISTING disposition. // if (!CertAddCTLContextToStore(hDstStore, (PCCTL_CONTEXT) pContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) { dwRetCode = GetLastError(); break; } } break; } case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT: { if (!CertAddCRLContextToStore(hDstStore, (PCCRL_CONTEXT) pContext, CERT_STORE_ADD_NEWER_INHERIT_PROPERTIES, NULL)) { // // If there is a newer copy in the store, then prompt user for permission // to replace, if UI is allowed. // if ((!fUIAllowed) && (CRYPT_E_EXISTS != GetLastError())) { dwRetCode = GetLastError(); break; } if (IDYES != I_MessageBox(hwndParent, IDS_IMPORT_REPLACE_EXISTING_NEWER_CRL, IDS_IMPORT_WIZARD_TITLE, NULL, MB_YESNO | MB_ICONINFORMATION | MB_DEFBUTTON2)) { dwRetCode = ERROR_CANCELLED; break; } // // Try with REPLACE_EXISTING disposition. // if (!CertAddCRLContextToStore(hDstStore, (PCCRL_CONTEXT) pContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) { dwRetCode = GetLastError(); break; } } break; } default: { dwRetCode = ERROR_INVALID_PARAMETER; break; } } return dwRetCode; } //-------------------------------------------------------------------------------- // // Add CTLs from source store to destination store. // //--------------------------------------------------------------------------------- DWORD AddCTLsToStore(HWND hwndParent, HCERTSTORE hSrcStore, HCERTSTORE hDstStore, BOOL fUIAllowed, UINT * pidsStatus) { DWORD dwError = 0; PCCTL_CONTEXT pCTLPre = NULL; PCCTL_CONTEXT pCTLContext = NULL; PCCTL_CONTEXT pFindCTL = NULL; //DSIE: Bug 22633. BOOL bCancelled = FALSE; // Add the CTLs while (pCTLContext = CertEnumCTLsInStore(hSrcStore, pCTLPre)) { bCancelled = FALSE; if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT, hwndParent, (PVOID) pCTLContext, fUIAllowed, hDstStore))) { if (ERROR_CANCELLED == dwError) { bCancelled = TRUE; } else { // Check to see if there is alreay a read-only duplicated copy in the store? // If so, ignore the error. if (NULL == (pFindCTL = CertFindCTLInStore(hDstStore, g_dwMsgAndCertEncodingType, 0, CTL_FIND_EXISTING, pCTLContext, NULL))) { *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT; goto CLEANUP; } CertFreeCTLContext(pFindCTL); pFindCTL = NULL; } dwError = 0; } pCTLPre = pCTLContext; } // // As the way we have it now, we can only check the last operation! // if (bCancelled) { dwError = ERROR_CANCELLED; *pidsStatus = IDS_IMPORT_CANCELLED; } else { *pidsStatus = IDS_IMPORT_SUCCEEDED; } CLEANUP: if (pCTLContext) { CertFreeCTLContext(pCTLContext); } return dwError; } //-------------------------------------------------------------------------------- // // Add CRLs from source store to destination store. // //--------------------------------------------------------------------------------- DWORD AddCRLsToStore(HWND hwndParent, HCERTSTORE hSrcStore, HCERTSTORE hDstStore, BOOL fUIAllowed, UINT * pidsStatus) { DWORD dwError = 0; DWORD dwCRLFlag = 0; PCCRL_CONTEXT pCRLPre = NULL; PCCRL_CONTEXT pCRLContext = NULL; PCCRL_CONTEXT pFindCRL = NULL; //DSIE: Bug 22633. BOOL bCancelled = FALSE; // Add the CRLs while (pCRLContext = CertGetCRLFromStore(hSrcStore, NULL, pCRLPre, &dwCRLFlag)) { bCancelled = FALSE; if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT, hwndParent, (PVOID) pCRLContext, fUIAllowed, hDstStore))) { if (ERROR_CANCELLED == dwError) { bCancelled = TRUE; } else { // Check to see if there is alreay a read-only duplicated copy in the store? // If so, ignore the error. if (NULL == (pFindCRL = CertFindCRLInStore(hDstStore, g_dwMsgAndCertEncodingType, 0, CRL_FIND_EXISTING, pCRLContext, NULL))) { *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT; goto CLEANUP; } CertFreeCRLContext(pFindCRL); pFindCRL = NULL; } dwError = 0; } pCRLPre = pCRLContext; } // // As the way we have it now, we can only check the last operation! // if (bCancelled) { dwError = ERROR_CANCELLED; *pidsStatus = IDS_IMPORT_CANCELLED; } else { *pidsStatus = IDS_IMPORT_SUCCEEDED; } CLEANUP: if (pCRLContext) { CertFreeCRLContext(pCRLContext); } return dwError; } //-------------------------------------------------------------------------------- // // Add certs from source store to destination store. // //--------------------------------------------------------------------------------- DWORD AddCertsToStore(HWND hwndParent, HCERTSTORE hSrcStore, HCERTSTORE hDstStore, BOOL fUIAllowed, UINT * pidsStatus) { DWORD dwError = 0; PCCERT_CONTEXT pCertPre = NULL; PCCERT_CONTEXT pCertContext = NULL; PCCERT_CONTEXT pFindCert = NULL; //DSIE: Bug 22633. BOOL bCancelled = FALSE; // Add the certs while (pCertContext = CertEnumCertificatesInStore(hSrcStore, pCertPre)) { bCancelled = FALSE; if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT, hwndParent, (PVOID) pCertContext, fUIAllowed, hDstStore))) { if (ERROR_CANCELLED == dwError) { bCancelled = TRUE; } else { // Check to see if there is alreay a read-only duplicated copy in the store? // If so, ignore the error. if (NULL == (pFindCert = CertFindCertificateInStore(hDstStore, g_dwMsgAndCertEncodingType, 0, CERT_FIND_EXISTING, pCertContext, NULL))) { *pidsStatus = IDS_IMPORT_FAIL_MOVE_CONTENT; goto CLEANUP; } CertFreeCertificateContext(pFindCert); pFindCert = NULL; } dwError = 0; } pCertPre = pCertContext; } // // As the way we have it now, we can only check the last operation! // if (bCancelled) { dwError = ERROR_CANCELLED; *pidsStatus = IDS_IMPORT_CANCELLED; } else { *pidsStatus = IDS_IMPORT_SUCCEEDED; } CLEANUP: if (pCertContext) { CertFreeCertificateContext(pCertContext); } return dwError; } //------------------------------------------------------------------------- // // Move Certs/CRls/CTLs from the source store to the destination // //------------------------------------------------------------------------- DWORD MoveItem(CERT_IMPORT_INFO * pCertImportInfo, UINT * pidsStatus) { DWORD dwError = 0; // Add the CTLs. if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent, pCertImportInfo->hSrcStore, pCertImportInfo->hDesStore, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, pidsStatus))) { goto CLEANUP; } // Add the CRLs. if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent, pCertImportInfo->hSrcStore, pCertImportInfo->hDesStore, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, pidsStatus))) { goto CLEANUP; } // Add the certs. if (0 != (dwError = AddCertsToStore(pCertImportInfo->hwndParent, pCertImportInfo->hSrcStore, pCertImportInfo->hDesStore, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, pidsStatus))) { goto CLEANUP; } CLEANUP: return dwError; } //************************************************************************** // // The entry point for import wizard //************************************************************************** //----------------------------------------------------------------------- // // CryptUIWizImport // // The import wizard to import public key related files to a certificate // store // // dwFlags can be set to any combination of the following flags: // CRYPTUI_WIZ_NO_UI No UI will be shown. Otherwise, User will be // prompted by a wizard. // CRYPTUI_WIZ_IMPORT_ALLOW_CERT Allow importing certificate // CRYPTUI_WIZ_IMPORT_ALLOW_CRL Allow importing CRL(certificate revocation list) // CRYPTUI_WIZ_IMPORT_ALLOW_CTL Allow importing CTL(certificate trust list) // CRYPTUI_WIZ_IMPORT_NO_CHANGE_DEST_STORE user will not be allowed to change // the hDesCertStore in the wizard page // CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE the contents should be imported to local machine // (currently only applicable for PFX imports) // CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER the contents should be imported to current user // (currently only applicable for PFX imports) // // Please notice that if neither of following three flags is in dwFlags, default to is // allow everything. // CRYPTUI_WIZ_IMPORT_ALLOW_CERT // CRYPTUI_WIZ_IMPORT_ALLOW_CRL // CRYPTUI_WIZ_IMPORT_ALLOW_CTL // // Also, note that the CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE and CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER // flags are used force the content of a pfx blob into either local machine or current user. // If neither of these flags are used and hDesCertStore is NULL then: // 1) The private key in the pfx blob will be forced to be imported into current user. // 2) If CRYPTUI_WIZ_NO_UI is NOT set, the wizard will prompt the user to select a certificate // store from the current user stores. // // // // If CRYPTUI_WIZ_NO_UI is set in dwFlags: // hwndParent: Ignored // pwszWizardTitle: Ignored // pImportSubject: IN Required: The subject to import. // hDestCertStore: IN Optional: The destination certficate store // // If CRYPTUI_WIZ_NO_UI is not set in dwFlags: // hwndPrarent: IN Optional: The parent window for the wizard // pwszWizardTitle: IN Optional: The title of the wizard // If NULL, the default will be IDS_BUILDCTL_WIZARD_TITLE // pImportSubject: IN Optional: The file name to import. // If NULL, the wizard will prompt user to enter the file name // hDestCertStore: IN Optional: The destination certificate store where the file wil be // imported to. If NULL, the wizard will prompt user to select // a certificate store //------------------------------------------------------------------------ BOOL WINAPI CryptUIWizImport( DWORD dwFlags, HWND hwndParent, LPCWSTR pwszWizardTitle, PCCRYPTUI_WIZ_IMPORT_SRC_INFO pImportSubject, HCERTSTORE hDestCertStore ) { BOOL fResult=FALSE; HRESULT hr=E_FAIL; CERT_IMPORT_INFO CertImportInfo; HCERTSTORE hTempStore=NULL; UINT ids=IDS_INVALID_WIZARD_INPUT; UINT idsContent=0; PROPSHEETPAGEW rgImportSheet[IMPORT_PROP_SHEET]; PROPSHEETHEADERW importHeader; ENROLL_PAGE_INFO rgImportPageInfo[]= {(LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_WELCOME), Import_Welcome, (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_FILE), Import_File, (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_PASSWORD), Import_Password, (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_STORE), Import_Store, (LPCWSTR)MAKEINTRESOURCE(IDD_IMPORT_COMPLETION), Import_Completion, }; DWORD dwIndex=0; DWORD dwPropCount=0; WCHAR wszTitle[MAX_TITLE_LENGTH]; DWORD dwError=0; int intMsg=0; INT_PTR iReturn=-1; //init memset(&CertImportInfo, 0, sizeof(CERT_IMPORT_INFO)); memset(rgImportSheet, 0, sizeof(PROPSHEETPAGEW)*IMPORT_PROP_SHEET); memset(&importHeader, 0, sizeof(PROPSHEETHEADERW)); //make sure if UIless option is set, all required information //is provided if(dwFlags & CRYPTUI_WIZ_NO_UI) { if(NULL==pImportSubject) goto InvalidArgErr; } if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE) && (dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER)) { goto InvalidArgErr; } //make sure that default is to allow everything if((0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) && (0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CRL)) && (0 == (dwFlags & CRYPTUI_WIZ_IMPORT_ALLOW_CTL))) dwFlags |= CRYPTUI_WIZ_IMPORT_ALLOW_CERT | CRYPTUI_WIZ_IMPORT_ALLOW_CRL | CRYPTUI_WIZ_IMPORT_ALLOW_CTL; //if hDestCertStore is NULL, no need to set the remote flag if(NULL == hDestCertStore) dwFlags &= (~CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE); CertImportInfo.hwndParent=hwndParent; CertImportInfo.dwFlag=dwFlags; //set the subject if(pImportSubject) { if(pImportSubject->dwSize != sizeof(CRYPTUI_WIZ_IMPORT_SRC_INFO)) goto InvalidArgErr; //copy the passWord and flags for PFX BLOBs CertImportInfo.dwPasswordFlags=pImportSubject->dwFlags; if(pImportSubject->pwszPassword) CertImportInfo.pwszPassword=WizardAllocAndCopyWStr((LPWSTR)(pImportSubject->pwszPassword)); else CertImportInfo.pwszPassword=NULL; //open a temparory certificate store hTempStore=CertOpenStore(CERT_STORE_PROV_MEMORY, g_dwMsgAndCertEncodingType, NULL, 0, NULL); if(!hTempStore) goto CertOpenStoreErr; switch(pImportSubject->dwSubjectChoice) { case CRYPTUI_WIZ_IMPORT_SUBJECT_FILE: if(NULL==pImportSubject->pwszFileName) goto InvalidArgErr; CertImportInfo.pwszFileName=(LPWSTR)(pImportSubject->pwszFileName); CertImportInfo.fFreeFileName=FALSE; //get the content type of the file //we import anything but PKCS10 or signed document ExpandAndCryptQueryObject( CERT_QUERY_OBJECT_FILE, CertImportInfo.pwszFileName, dwExpectedContentType, CERT_QUERY_FORMAT_FLAG_ALL, 0, NULL, &(CertImportInfo.dwContentType), NULL, &(CertImportInfo.hSrcStore), NULL, NULL); //if this is a PKCS7 file, get the blob if(CERT_QUERY_CONTENT_PKCS7_SIGNED == CertImportInfo.dwContentType ) { if(S_OK !=(hr=RetrieveBLOBFromFile( CertImportInfo.pwszFileName, &(CertImportInfo.blobData.cbData), &(CertImportInfo.blobData.pbData)))) goto ReadFromFileErr; } else { //get the blobs from the pfx file if(CERT_QUERY_CONTENT_PFX==CertImportInfo.dwContentType) { //we can not import PFX Files for remote case if(dwFlags & CRYPTUI_WIZ_IMPORT_REMOTE_DEST_STORE) { ids=IDS_IMPORT_NO_PFX_FOR_REMOTE; goto InvalidArgErr; } if(S_OK !=(hr=RetrieveBLOBFromFile( CertImportInfo.pwszFileName, &(CertImportInfo.blobData.cbData), &(CertImportInfo.blobData.pbData)))) goto ReadFromFileErr; //convert the PFX BLOB to a certificate store CertImportInfo.fPFX=PFXVerifyPassword( (CRYPT_DATA_BLOB *)&(CertImportInfo.blobData), CertImportInfo.pwszPassword, 0); //PFX blob only contains certificates if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) { ids=IDS_IMPORT_OBJECT_NOT_EXPECTED; goto InvalidArgErr; } } } //make sure we do have a source store if(CertImportInfo.hSrcStore) { //remember to free the Src store CertImportInfo.fFreeSrcStore=TRUE; CertImportInfo.fKnownSrc=TRUE; } break; case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT: if(NULL==pImportSubject->pCertContext) goto InvalidArgErr; //add certificate to the hash if(!CertAddCertificateContextToStore( hTempStore, pImportSubject->pCertContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) goto AddCertErr; CertImportInfo.hSrcStore=hTempStore; CertImportInfo.fFreeSrcStore=FALSE; CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CERT; CertImportInfo.fKnownSrc=TRUE; break; case CRYPTUI_WIZ_IMPORT_SUBJECT_CTL_CONTEXT: if(NULL==pImportSubject->pCTLContext) goto InvalidArgErr; //add CTL to the hash if(!CertAddCTLContextToStore( hTempStore, pImportSubject->pCTLContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) goto Crypt32Err; CertImportInfo.hSrcStore=hTempStore; CertImportInfo.fFreeSrcStore=FALSE; CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CTL; CertImportInfo.fKnownSrc=TRUE; break; case CRYPTUI_WIZ_IMPORT_SUBJECT_CRL_CONTEXT: if(NULL==pImportSubject->pCRLContext) goto InvalidArgErr; //add CRL to the hash if(!CertAddCRLContextToStore( hTempStore, pImportSubject->pCRLContext, CERT_STORE_ADD_REPLACE_EXISTING_INHERIT_PROPERTIES, NULL)) goto Crypt32Err; CertImportInfo.hSrcStore=hTempStore; CertImportInfo.fFreeSrcStore=FALSE; CertImportInfo.fKnownSrc=TRUE; CertImportInfo.dwContentType=CERT_QUERY_CONTENT_CRL; break; case CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_STORE: if(NULL==pImportSubject->hCertStore) goto InvalidArgErr; CertImportInfo.hSrcStore=pImportSubject->hCertStore; CertImportInfo.fFreeSrcStore=FALSE; CertImportInfo.dwContentType=0; CertImportInfo.fKnownSrc=TRUE; break; default: goto InvalidArgErr; } } else { CertImportInfo.fKnownSrc=FALSE; } //if user has supplied a source store, it should contain the correct //information if(NULL != CertImportInfo.hSrcStore) { //make sure that the destination store has the right content if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent)) { ids=idsContent; goto InvalidArgErr; } } else { //check for the PFX if(TRUE == CertImportInfo.fPFX) { //PFX blob only contains certificates if(0==((CertImportInfo.dwFlag) & CRYPTUI_WIZ_IMPORT_ALLOW_CERT)) { ids=IDS_IMPORT_OBJECT_NOT_EXPECTED; goto InvalidArgErr; } } } //set the destination store if supplied if(hDestCertStore) { CertImportInfo.hDesStore=hDestCertStore; CertImportInfo.fFreeDesStore=FALSE; CertImportInfo.fKnownDes=TRUE; CertImportInfo.fSelectedDesStore=TRUE; } else { CertImportInfo.fKnownDes=FALSE; CertImportInfo.fSelectedDesStore=FALSE; } //supply the UI work if((dwFlags & CRYPTUI_WIZ_NO_UI) == 0) { //set up the fonts if(!SetupFonts(g_hmodThisDll, NULL, &(CertImportInfo.hBigBold), &(CertImportInfo.hBold))) goto Win32Err; //init the common control if(!WizardInit(TRUE) || (sizeof(rgImportPageInfo)/sizeof(rgImportPageInfo[0])!=IMPORT_PROP_SHEET) ) goto InvalidArgErr; //set up the property sheet and the property header dwPropCount=0; for(dwIndex=0; dwIndex 2) { //create the wizard iReturn=PropertySheetU(&importHeader); if(-1 == iReturn) goto Win32Err; if(0 == iReturn) { fResult=TRUE; //no need to say anything if the wizard is cancelled ids=0; goto CommonReturn; } } } //Open the destination store for PFX file if(TRUE == CertImportInfo.fPFX) { // if the caller specified local machine then set the appropriate flag if (dwFlags & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE) { CertImportInfo.dwPasswordFlags |= CRYPT_MACHINE_KEYSET; } else if ((dwFlags & CRYPTUI_WIZ_IMPORT_TO_CURRENTUSER) || (hDestCertStore == NULL)) { CertImportInfo.dwPasswordFlags |= CRYPT_USER_KEYSET; } CertImportInfo.hSrcStore= PFXImportCertStore( (CRYPT_DATA_BLOB *)&(CertImportInfo.blobData), CertImportInfo.pwszPassword, CertImportInfo.dwPasswordFlags); if(CertImportInfo.hSrcStore) { //remember to free the Src store CertImportInfo.fFreeSrcStore=TRUE; CertImportInfo.fKnownSrc=TRUE; } else { DWORD dwLastError = GetLastError(); if (dwLastError == ERROR_UNSUPPORTED_TYPE) { ids=IDS_UNSUPPORTED_KEY; } else if (dwLastError == CRYPT_E_BAD_ENCODE) { ids=IDS_BAD_ENCODE; } //DSIE: Bug 22752 else if (dwLastError == ERROR_CANCELLED) { ids=IDS_IMPORT_FAIL_MOVE_CONTENT; } else { ids=IDS_IMPORT_FAIL_FIND_CONTENT; } goto InvalidArgErr; } //make sure the PFX blob is not empty if(!CheckForContent(CertImportInfo.hSrcStore, dwFlags, FALSE, &idsContent)) { ids=idsContent; goto InvalidArgErr; } } //make sure the source store is a valid value if(NULL==(CertImportInfo.hSrcStore)) { ids=IDS_IMPORT_FAIL_FIND_CONTENT; goto InvalidArgErr; } //do the import work. Return a status //we disable the parent window in case the root dialogue will show up //this is to prevent re-entrency if(hwndParent) { EnableWindow(hwndParent,FALSE); } if(S_OK !=(hr=I_ImportCertificate(&CertImportInfo, &ids))) { if(hwndParent) { EnableWindow(hwndParent,TRUE); } goto I_ImportErr; } if(hwndParent) { EnableWindow(hwndParent,TRUE); } fResult=TRUE; CommonReturn: //preserve the last error dwError=GetLastError(); //pop up the confirmation box for failure if(ids && ((dwFlags & CRYPTUI_WIZ_NO_UI) ==0)) { //set the message of inable to gather enough info for PKCS10 if(IDS_IMPORT_SUCCEEDED == ids) I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE, NULL, MB_OK|MB_ICONINFORMATION); else { if(IDS_IMPORT_PFX_EMPTY == ids) I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE, NULL, MB_OK|MB_ICONWARNING); else I_MessageBox(hwndParent, ids, IDS_IMPORT_WIZARD_TITLE, NULL, MB_OK|MB_ICONERROR); } if(IDS_IMPORT_DUPLICATE == ids) { //remark the success case I_MessageBox(hwndParent, IDS_IMPORT_SUCCEEDED, IDS_IMPORT_WIZARD_TITLE, NULL, MB_OK|MB_ICONINFORMATION); } } //destroy the hFont object DestroyFonts(CertImportInfo.hBigBold, CertImportInfo.hBold); if(CertImportInfo.pwszFileName && (TRUE==CertImportInfo.fFreeFileName)) WizardFree(CertImportInfo.pwszFileName); /* if(CertImportInfo.pwszDefaultStoreName) WizardFree(CertImportInfo.pwszDefaultStoreName); */ if(CertImportInfo.hDesStore && (TRUE==CertImportInfo.fFreeDesStore)) CertCloseStore(CertImportInfo.hDesStore, 0); if(CertImportInfo.hSrcStore && (TRUE==CertImportInfo.fFreeSrcStore)) CertCloseStore(CertImportInfo.hSrcStore, 0); if(CertImportInfo.blobData.pbData) UnmapViewOfFile(CertImportInfo.blobData.pbData); if(CertImportInfo.pwszPassword) { SecureZeroMemory(CertImportInfo.pwszPassword, lstrlenW(CertImportInfo.pwszPassword) * sizeof(WCHAR)); WizardFree(CertImportInfo.pwszPassword); } if(hTempStore) CertCloseStore(hTempStore, 0); //reset the error SetLastError(dwError); return fResult; ErrorReturn: fResult=FALSE; goto CommonReturn; SET_ERROR(InvalidArgErr, E_INVALIDARG); TRACE_ERROR(CertOpenStoreErr); SET_ERROR_VAR(ReadFromFileErr, hr); TRACE_ERROR(AddCertErr); TRACE_ERROR(Crypt32Err); TRACE_ERROR(Win32Err); SET_ERROR_VAR(I_ImportErr, hr); } //**************************************************************************** // Helper functions for import wizards // //***************************************************************************** BOOL InstallViaXEnroll(CERT_IMPORT_INFO *pCertImportInfo) { BOOL fResult=FALSE; IEnroll2 *pIEnroll2=NULL; PFNPIEnroll2GetNoCOM pfnPIEnroll2GetNoCOM=NULL; CRYPT_DATA_BLOB DataBlob; PCCERT_CONTEXT pCert=NULL; if(NULL == pCertImportInfo) goto CLEANUP; DataBlob.cbData=pCertImportInfo->blobData.cbData; DataBlob.pbData=pCertImportInfo->blobData.pbData; if((0 == DataBlob.cbData) || (NULL == DataBlob.pbData)) { //this is a certificate case. Get the blob for the cert if(NULL==pCertImportInfo->hSrcStore) goto CLEANUP; if(!(pCert=CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, NULL))) goto CLEANUP; DataBlob.cbData=pCert->cbCertEncoded; DataBlob.pbData=pCert->pbCertEncoded; } //load the library "xEnroll.dll". if(NULL==g_hmodxEnroll) { if(NULL==(g_hmodxEnroll=LoadLibrary("xenroll.dll"))) { goto CLEANUP; } } //get the address for PIEnroll2GetNoCOM() if(NULL==(pfnPIEnroll2GetNoCOM=(PFNPIEnroll2GetNoCOM)GetProcAddress(g_hmodxEnroll, "PIEnroll2GetNoCOM"))) goto CLEANUP; if(NULL==(pIEnroll2=pfnPIEnroll2GetNoCOM())) goto CLEANUP; //specify the destiniation store if user has specified one if(pCertImportInfo->hDesStore && (TRUE==pCertImportInfo->fSelectedDesStore)) { if(S_OK != (pIEnroll2->SetHStoreMy(pCertImportInfo->hDesStore))) goto CLEANUP; if(S_OK != (pIEnroll2->SetHStoreCA(pCertImportInfo->hDesStore))) goto CLEANUP; if(S_OK != (pIEnroll2->SetHStoreROOT(pCertImportInfo->hDesStore))) goto CLEANUP; } if(S_OK != (pIEnroll2->acceptPKCS7Blob(&DataBlob))) goto CLEANUP; fResult=TRUE; CLEANUP: if(pIEnroll2) pIEnroll2->Release(); if(pCert) CertFreeCertificateContext(pCert); return fResult; } //-------------------------------------------------------------------------------- // // The import routine that does the work // //--------------------------------------------------------------------------------- HRESULT I_ImportCertificate(CERT_IMPORT_INFO * pCertImportInfo, UINT * pidsStatus) { UINT idsStatus=0; HCERTSTORE hMyStore=NULL; HCERTSTORE hCAStore=NULL; HCERTSTORE hTrustStore=NULL; HCERTSTORE hRootStore=NULL; HCERTSTORE hAddressBookStore=NULL; HCERTSTORE hTrustedPeopleStore=NULL; HCERTSTORE hCertStore=NULL; PCCERT_CONTEXT pCertContext=NULL; PCCERT_CONTEXT pCertPre=NULL; PCCERT_CONTEXT pFindCert=NULL; DWORD dwData=0; DWORD dwCertOpenStoreFlags; //DSIE: Bug 22633. BOOL bCancelled = FALSE; DWORD dwError = 0; if (NULL == pCertImportInfo || NULL == pidsStatus) return E_INVALIDARG; if (NULL == pCertImportInfo->hSrcStore) { *pidsStatus = IDS_IMPORT_FAIL_FIND_CONTENT; return E_FAIL; } if (pCertImportInfo->fPFX && (pCertImportInfo->dwFlag & CRYPTUI_WIZ_IMPORT_TO_LOCALMACHINE)) { dwCertOpenStoreFlags = CERT_SYSTEM_STORE_LOCAL_MACHINE; } else { dwCertOpenStoreFlags = CERT_SYSTEM_STORE_CURRENT_USER; } // If the content type is PKS7 and use pass in or select a file name. // We try to use xEnroll to accept it as an enrollment response. if ((CERT_QUERY_CONTENT_PKCS7_SIGNED == pCertImportInfo->dwContentType) || (CERT_QUERY_CONTENT_CERT == pCertImportInfo->dwContentType)) { if (InstallViaXEnroll(pCertImportInfo)) { *pidsStatus = IDS_IMPORT_SUCCEEDED; return S_OK; } } // Do a store copy if hDesStore is selected. if (pCertImportInfo->hDesStore && pCertImportInfo->fSelectedDesStore) { dwError = MoveItem(pCertImportInfo, pidsStatus); goto CLEANUP; } // We need to find a correct store on user's behalf. // Put the CTLs in the trust store. if (!(hTrustStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"trust"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_TRUST; goto CLEANUP; } if (0 != (dwError = AddCTLsToStore(pCertImportInfo->hwndParent, pCertImportInfo->hSrcStore, hTrustStore, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, pidsStatus))) { goto CLEANUP; } // Put CRL in the CA store. if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"ca"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_CA; goto CLEANUP; } if (0 != (dwError = AddCRLsToStore(pCertImportInfo->hwndParent, pCertImportInfo->hSrcStore, hCAStore, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, pidsStatus))) { goto CLEANUP; } // Add the certificate with private key to my store; and the rest // to the ca, root, or addressbook store. while (pCertContext = CertEnumCertificatesInStore(pCertImportInfo->hSrcStore, pCertPre)) { // Check if the certificate has the property on it. // Make sure the private key matches the certificate // Search for both machine key and user keys if (CertGetCertificateContextProperty(pCertContext, CERT_KEY_PROV_INFO_PROP_ID, NULL, &dwData) && CryptFindCertificateKeyProvInfo(pCertContext, 0, NULL)) { // Open my store if necessary. if (!hMyStore) { if (!(hMyStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"my"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_MY; goto CLEANUP; } } hCertStore = hMyStore; } // See if the certificate is self-signed. // If it is selfsigned, goes to the root store else if (TrustIsCertificateSelfSigned(pCertContext, pCertContext->dwCertEncodingType, 0)) { // DSIE: Bug 375649. // If EFS only cert, put it in TrustedPeople for self-signed cert, // otherwise, go to the root store. // if (IsEFSOnly(pCertContext)) { // Open the TrustedPeople store if necessary. if (!hTrustedPeopleStore) { if (!(hTrustedPeopleStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"trustedpeople"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_TRUSTEDPEOPLE; goto CLEANUP; } } hCertStore = hTrustedPeopleStore; } else { // Open the root store if necessary. if (!hRootStore) { if (!(hRootStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"root"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_ROOT; goto CLEANUP; } } hCertStore = hRootStore; } } // Go to ca store if for ca cert, otherwise go to addressbook (other people) store. else if (IsCACert(pCertContext)) { // Open the ca store if necessary. if (!hCertStore) { if (!(hCAStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"ca"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_CA; goto CLEANUP; } } hCertStore = hCAStore; } else { // Open the other people store if necessary. if (!hAddressBookStore) { if(!(hAddressBookStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, g_dwMsgAndCertEncodingType, NULL, dwCertOpenStoreFlags, L"addressbook"))) { dwError = GetLastError(); *pidsStatus = IDS_FAIL_OPEN_ADDRESSBOOK; goto CLEANUP; } } hCertStore = hAddressBookStore; } //DSIE: Bug 22633. bCancelled = FALSE; if (0 != (dwError = AddContextToStore(CRYPTUI_WIZ_IMPORT_SUBJECT_CERT_CONTEXT, pCertImportInfo->hwndParent, (PVOID) pCertContext, pCertImportInfo->dwFlag & CRYPTUI_WIZ_NO_UI ? TRUE : FALSE, hCertStore))) { if (ERROR_CANCELLED == dwError) { bCancelled = TRUE; } else { // Check to see if there is alreay a read-only duplicated copy in the store? // If so, ignore the error. if (pFindCert = CertFindCertificateInStore(hCertStore, g_dwMsgAndCertEncodingType, 0, CERT_FIND_EXISTING, pCertContext, NULL)) { CertFreeCertificateContext(pFindCert); pFindCert = NULL; } else if (hCertStore == hMyStore) { *pidsStatus = IDS_FAIL_ADD_CERT_MY; goto CLEANUP; } else if (hCertStore == hRootStore) { *pidsStatus = IDS_FAIL_ADD_CERT_ROOT; goto CLEANUP; } else if (hCertStore == hCAStore) { *pidsStatus = IDS_FAIL_ADD_CERT_CA; goto CLEANUP; } else if (hCertStore == hAddressBookStore) { *pidsStatus = IDS_FAIL_ADD_CERT_OTHERPEOPLE; goto CLEANUP; } else if (hCertStore == hTrustedPeopleStore) { *pidsStatus = IDS_FAIL_ADD_CERT_TRUSTEDPEOPLE; goto CLEANUP; } } dwError = 0; } pCertPre = pCertContext; } if (bCancelled) { dwError = ERROR_CANCELLED; *pidsStatus = IDS_IMPORT_CANCELLED; } else { *pidsStatus = IDS_IMPORT_SUCCEEDED; } CLEANUP: if(pCertContext) CertFreeCertificateContext(pCertContext); if(hMyStore) CertCloseStore(hMyStore, 0); if(hCAStore) CertCloseStore(hCAStore, 0); if(hTrustStore) CertCloseStore(hTrustStore, 0); if(hRootStore) CertCloseStore(hRootStore, 0); if(hAddressBookStore) CertCloseStore(hAddressBookStore, 0); if(hTrustedPeopleStore) CertCloseStore(hTrustedPeopleStore, 0); return HRESULT_FROM_WIN32(dwError); } //-------------------------------------------------------------------------------- // //get the bytes from the file name // //--------------------------------------------------------------------------------- HRESULT RetrieveBLOBFromFile(LPWSTR pwszFileName,DWORD *pcb,BYTE **ppb) { HRESULT hr=E_FAIL; HANDLE hFile=NULL; HANDLE hFileMapping=NULL; DWORD cbData=0; BYTE *pbData=0; DWORD cbHighSize=0; if(!pcb || !ppb || !pwszFileName) return E_INVALIDARG; *ppb=NULL; *pcb=0; if ((hFile = ExpandAndCreateFileU(pwszFileName, GENERIC_READ, FILE_SHARE_READ, NULL, // lpsa OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) { hr=HRESULT_FROM_WIN32(GetLastError()); goto CLEANUP; } if((cbData = GetFileSize(hFile, &cbHighSize)) == 0xffffffff) { hr=HRESULT_FROM_WIN32(GetLastError()); goto CLEANUP; } //we do not handle file more than 4G bytes if(cbHighSize != 0) { hr=E_FAIL; goto CLEANUP; } //create a file mapping object if(NULL == (hFileMapping=CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL))) { hr=HRESULT_FROM_WIN32(GetLastError()); goto CLEANUP; } //create a view of the file if(NULL == (pbData=(BYTE *)MapViewOfFile( hFileMapping, FILE_MAP_READ, 0, 0, cbData))) { hr=HRESULT_FROM_WIN32(GetLastError()); goto CLEANUP; } hr=S_OK; *pcb=cbData; *ppb=pbData; CLEANUP: if(hFile) CloseHandle(hFile); if(hFileMapping) CloseHandle(hFileMapping); return hr; }