//+------------------------------------------------------------------------- // // Microsoft Windows NT // // Copyright (C) Microsoft Corporation, 1995 - 1998 // // File: cepsetup.cpp // // Contents: The setup code for MSCEP //-------------------------------------------------------------------------- #include "global.hxx" #include #include "setuputil.h" #include "cepsetup.h" #include "resource.h" //----------------------------------------------------------------------- // // Global data // //----------------------------------------------------------------------- HMODULE g_hModule=NULL; //----------------------------------------------------------------------- //CN has to be the 1st item and O the third in the following list and C is the last item. No other requirements for //the order //----------------------------------------------------------------------- CEP_ENROLL_INFO g_rgRAEnrollInfo[RA_INFO_COUNT]= {L"CN=", IDC_ENROLL_NAME, L"E=", IDC_ENROLL_EMAIL, L"O=", IDC_ENROLL_COMPANY, L"OU=", IDC_ENROLL_DEPARTMENT, L"L=", IDC_ENROLL_CITY, L"S=", IDC_ENROLL_STATE, L"C=", IDC_ENROLL_COUNTRY, }; //----------------------------------------------------------------------- //the key length table //----------------------------------------------------------------------- DWORD g_rgdwKeyLength[] = { 512, 1024, 2048, 4096, }; DWORD g_dwKeyLengthCount=sizeof(g_rgdwKeyLength)/sizeof(g_rgdwKeyLength[0]); DWORD g_rgdwSmallKeyLength[] = { 128, 256, 512, 1024, }; DWORD g_dwSmallKeyLengthCount=sizeof(g_rgdwSmallKeyLength)/sizeof(g_rgdwSmallKeyLength[0]); //the list of possible default key lenght in the order of preference DWORD g_rgdwDefaultKey[] = { 1024, 2048, 512, 256, 4096, 128 }; DWORD g_dwDefaultKeyCount=sizeof(g_rgdwDefaultKey)/sizeof(g_rgdwDefaultKey[0]); //----------------------------------------------------------------------- // //The winProc for each of the setup wizard page // //----------------------------------------------------------------------- //----------------------------------------------------------------------- //Welcome //----------------------------------------------------------------------- INT_PTR APIENTRY CEP_Welcome(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CEP_WIZARD_INFO *pCEPWizardInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo); SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE); 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; } //----------------------------------------------------------------------- //Chanllenge //----------------------------------------------------------------------- INT_PTR APIENTRY CEP_Challenge(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CEP_WIZARD_INFO *pCEPWizardInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam); //make sure pCertWizardInfo is a valid pointer if(NULL==pCEPWizardInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo); SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE); //by default, we do use Challenge password SendMessage(GetDlgItem(hwndDlg, IDC_CHALLENGE_CHECK), BM_SETCHECK, BST_CHECKED, 0); 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==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //check for the Challenge password options if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_CHALLENGE_CHECK, BM_GETCHECK, 0, 0)) pCEPWizardInfo->fPassword=TRUE; else pCEPWizardInfo->fPassword=FALSE; if(!EmptyCEPStore()) { CEPMessageBox(hwndDlg, IDS_EXISTING_RA, MB_ICONINFORMATION|MB_OK|MB_APPLMODAL); if(IDNO==CEPMessageBox(hwndDlg, IDS_PROCESS_PENDING, MB_ICONQUESTION|MB_YESNO|MB_APPLMODAL)) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // Enroll //----------------------------------------------------------------------- INT_PTR APIENTRY CEP_Enroll(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CEP_WIZARD_INFO *pCEPWizardInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; DWORD dwIndex=0; DWORD dwChar=0; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam); //make sure pCertWizardInfo is a valid pointer if(NULL==pCEPWizardInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo); SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE); //by default, we do not use the advanced enrollment options SendMessage(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), BM_SETCHECK, BST_UNCHECKED, 0); //preset the country string since we only allow 2 characters SetDlgItemTextU(hwndDlg, IDC_ENROLL_COUNTRY, L"US"); 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); if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //if the adv selection is made, it has to stay selected if(pCEPWizardInfo->fEnrollAdv) EnableWindow(GetDlgItem(hwndDlg, IDC_ENORLL_ADV_CHECK), FALSE); break; case PSN_WIZBACK: break; case PSN_WIZNEXT: if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //gather RA subject informaton for(dwIndex=0; dwIndex < RA_INFO_COUNT; dwIndex++) { if(pCEPWizardInfo->rgpwszName[dwIndex]) { free(pCEPWizardInfo->rgpwszName[dwIndex]); pCEPWizardInfo->rgpwszName[dwIndex]=NULL; } if(0!=(dwChar=(DWORD)SendDlgItemMessage(hwndDlg, g_rgRAEnrollInfo[dwIndex].dwIDC, WM_GETTEXTLENGTH, 0, 0))) { pCEPWizardInfo->rgpwszName[dwIndex]=(LPWSTR)malloc(sizeof(WCHAR)*(dwChar+1)); if(NULL!=(pCEPWizardInfo->rgpwszName[dwIndex])) { GetDlgItemTextU(hwndDlg, g_rgRAEnrollInfo[dwIndex].dwIDC, pCEPWizardInfo->rgpwszName[dwIndex], dwChar+1); } } } //we require name and company if((NULL==(pCEPWizardInfo->rgpwszName[0])) || (NULL==(pCEPWizardInfo->rgpwszName[2])) ) { CEPMessageBox(hwndDlg, IDS_ENROLL_REQUIRE_NAME, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } //we only allow 2 characeters for the country if(NULL !=(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1])) { if(2 < wcslen(pCEPWizardInfo->rgpwszName[RA_INFO_COUNT -1])) { CEPMessageBox(hwndDlg, IDS_ENROLL_COUNTRY_TOO_LARGE, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } } //check for the advanced options if(BST_CHECKED==SendDlgItemMessage(hwndDlg,IDC_ENORLL_ADV_CHECK, BM_GETCHECK, 0, 0)) pCEPWizardInfo->fEnrollAdv=TRUE; else pCEPWizardInfo->fEnrollAdv=FALSE; //If the advanced is selected, skip the CSP Page if(FALSE== pCEPWizardInfo->fEnrollAdv) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_COMPLETION); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- // CSP //----------------------------------------------------------------------- INT_PTR APIENTRY CEP_CSP(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CEP_WIZARD_INFO *pCEPWizardInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; NM_LISTVIEW FAR * pnmv=NULL; BOOL fSign=FALSE; int idCombo=0; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam); //make sure pCertWizardInfo is a valid pointer if(NULL==pCEPWizardInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo); SetControlFont(pCEPWizardInfo->hBold, hwndDlg,IDC_BOLD_TITLE); //populate the CSP list and key length combo box InitCSPList(hwndDlg, IDC_CSP_SIGN_LIST, TRUE, pCEPWizardInfo); InitCSPList(hwndDlg, IDC_CSP_ENCRYPT_LIST, FALSE, pCEPWizardInfo); RefreshKeyLengthCombo(hwndDlg, IDC_CSP_SIGN_LIST, IDC_CSP_SIGN_COMBO, TRUE, pCEPWizardInfo); RefreshKeyLengthCombo(hwndDlg, IDC_CSP_ENCRYPT_LIST, IDC_CSP_ENCRYPT_COMBO, FALSE, pCEPWizardInfo); break; case WM_COMMAND: break; case WM_NOTIFY: switch (((NMHDR FAR *) lParam)->code) { case LVN_ITEMCHANGED: if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; pnmv = (LPNMLISTVIEW) lParam; if(NULL==pnmv) break; if (pnmv->uNewState & LVIS_SELECTED) { if(IDC_CSP_SIGN_LIST == (pnmv->hdr).idFrom) { fSign=TRUE; idCombo=IDC_CSP_SIGN_COMBO; } else { if(IDC_CSP_ENCRYPT_LIST != (pnmv->hdr).idFrom) break; fSign=FALSE; idCombo=IDC_CSP_ENCRYPT_COMBO; } RefreshKeyLengthCombo( hwndDlg, (pnmv->hdr).idFrom, idCombo, fSign, pCEPWizardInfo); } break; 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==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //get the select CSP and key length if(!GetSelectedCSP(hwndDlg, IDC_CSP_SIGN_LIST, &(pCEPWizardInfo->dwSignProvIndex))) { CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } if(!GetSelectedCSP(hwndDlg, IDC_CSP_ENCRYPT_LIST, &(pCEPWizardInfo->dwEncryptProvIndex))) { CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_CSP, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } if(!GetSelectedKeyLength(hwndDlg, IDC_CSP_SIGN_COMBO, &(pCEPWizardInfo->dwSignKeyLength))) { CEPMessageBox(hwndDlg, IDS_SELECT_SIGN_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } if(!GetSelectedKeyLength(hwndDlg, IDC_CSP_ENCRYPT_COMBO, &(pCEPWizardInfo->dwEncryptKeyLength))) { CEPMessageBox(hwndDlg, IDS_SELECT_ENCRYPT_KEY_LENGTH, MB_ICONERROR|MB_OK|MB_APPLMODAL); SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, -1); break; } break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //----------------------------------------------------------------------- //Completion //----------------------------------------------------------------------- INT_PTR APIENTRY CEP_Completion(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { CEP_WIZARD_INFO *pCEPWizardInfo=NULL; PROPSHEETPAGE *pPropSheet=NULL; HWND hwndControl=NULL; LV_COLUMNW lvC; HCURSOR hPreCursor=NULL; HCURSOR hWinPreCursor=NULL; switch (msg) { case WM_INITDIALOG: //set the wizard information so that it can be shared pPropSheet = (PROPSHEETPAGE *) lParam; pCEPWizardInfo = (CEP_WIZARD_INFO *) (pPropSheet->lParam); //make sure pCertWizardInfo is a valid pointer if(NULL==pCEPWizardInfo) break; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pCEPWizardInfo); SetControlFont(pCEPWizardInfo->hBigBold, hwndDlg,IDC_BIG_BOLD_TITLE); //insert two columns hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST); 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) break; //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 = 10; //(dwMaxSize+2)*7; // Width of the column, in pixels. lvC.pszText = L""; // The text for the column. lvC.iSubItem= 1; if (ListView_InsertColumnU(hwndControl, 1, &lvC) == -1) break; 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==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; if(hwndControl=GetDlgItem(hwndDlg, IDC_COMPLETION_LIST)) DisplayConfirmation(hwndControl, pCEPWizardInfo); break; case PSN_WIZBACK: if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //skip CSP page if adv is not selected if(FALSE == pCEPWizardInfo->fEnrollAdv) SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, IDD_ENROLL); break; case PSN_WIZFINISH: if(NULL==(pCEPWizardInfo=(CEP_WIZARD_INFO *)GetWindowLongPtr(hwndDlg, DWLP_USER))) break; //overwrite the cursor for this window class hWinPreCursor=(HCURSOR)SetClassLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)NULL); hPreCursor=SetCursor(LoadCursor(NULL, IDC_WAIT)); //do the real setup work I_DoSetupWork(hwndDlg, pCEPWizardInfo); //set the cursor back SetCursor(hPreCursor); SetWindowLongPtr(hwndDlg, GCLP_HCURSOR, (LONG_PTR)hWinPreCursor); break; default: return FALSE; } break; default: return FALSE; } return TRUE; } //-------------------------------------------------------------------------- // // Helper Functions for the wizard pages // //-------------------------------------------------------------------------- //-------------------------------------------------------------------------- // // RefreshKeyLengthCombo // //-------------------------------------------------------------------------- BOOL WINAPI RefreshKeyLengthCombo(HWND hwndDlg, int idsList, int idsCombo, BOOL fSign, CEP_WIZARD_INFO *pCEPWizardInfo) { BOOL fResult=FALSE; DWORD dwDefaultKeyLength=0; DWORD *pdwList=NULL; DWORD dwListCount=0; DWORD dwMax=0; DWORD dwMin=0; DWORD dwIndex=0; DWORD dwCSPIndex=0; CEP_CSP_INFO *pCSPInfo=NULL; int iInsertedIndex=0; WCHAR wszKeyLength[CEP_KEY_LENGTH_STRING]; BOOL fSelected=FALSE; //get the selected list view item if(!GetSelectedCSP(hwndDlg,idsList,&dwCSPIndex)) goto CLEANUP; pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwCSPIndex]); if(fSign) { dwDefaultKeyLength=pCSPInfo->dwDefaultSign; pdwList=pCSPInfo->pdwSignList; dwListCount= pCSPInfo->dwSignCount; dwMax=pCSPInfo->dwMaxSign; dwMin=pCSPInfo->dwMinSign; } else { dwDefaultKeyLength=pCSPInfo->dwDefaultEncrypt; pdwList=pCSPInfo->pdwEncryptList; dwListCount=pCSPInfo->dwEncryptCount; dwMax=pCSPInfo->dwMaxEncrypt; dwMin=pCSPInfo->dwMinEncrypt; } //clear out the combo box SendDlgItemMessageU(hwndDlg, idsCombo, CB_RESETCONTENT, 0, 0); for(dwIndex=0; dwIndex < dwListCount; dwIndex++) { if((pdwList[dwIndex] >= dwMin) && (pdwList[dwIndex] <= dwMax)) { _ltow(pdwList[dwIndex], wszKeyLength, 10); iInsertedIndex=SendDlgItemMessageU(hwndDlg, idsCombo, CB_ADDSTRING, 0, (LPARAM)wszKeyLength); if((iInsertedIndex != CB_ERR) && (iInsertedIndex != CB_ERRSPACE)) { SendDlgItemMessage(hwndDlg, idsCombo, CB_SETITEMDATA, (WPARAM)iInsertedIndex, (LPARAM)pdwList[dwIndex]); if(dwDefaultKeyLength==pdwList[dwIndex]) { SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, iInsertedIndex, 0); fSelected=TRUE; } } } } if(fSelected==FALSE) SendDlgItemMessageU(hwndDlg, idsCombo, CB_SETCURSEL, 0, 0); fResult=TRUE; CLEANUP: return fResult; } //-------------------------------------------------------------------------- // // InitCSPList // //-------------------------------------------------------------------------- BOOL WINAPI InitCSPList(HWND hwndDlg, int idControl, BOOL fSign, CEP_WIZARD_INFO *pCEPWizardInfo) { BOOL fResult=FALSE; DWORD dwIndex=0; CEP_CSP_INFO *pCSPInfo=NULL; int iInsertedIndex=0; HWND hwndList=NULL; LV_ITEMW lvItem; LV_COLUMNW lvC; BOOL fSelected=FALSE; if(NULL==(hwndList=GetDlgItem(hwndDlg, idControl))) goto CLEANUP; //insert a column into the list view 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; //(dwMaxSize+2)*7; // Width of the column, in pixels. lvC.pszText = L""; // The text for the column. lvC.iSubItem=0; if (-1 == ListView_InsertColumnU(hwndList, 0, &lvC)) goto CLEANUP; // set up the fields in the list view item struct that don't change from item to item memset(&lvItem, 0, sizeof(LV_ITEMW)); lvItem.mask = LVIF_TEXT | LVIF_STATE |LVIF_PARAM ; for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++) { fSelected=FALSE; pCSPInfo= &(pCEPWizardInfo->rgCSPInfo[dwIndex]); if(fSign) { if(!(pCSPInfo->fSignature)) continue; if(dwIndex==pCEPWizardInfo->dwSignProvIndex) fSelected=TRUE; } else { if(!(pCSPInfo->fEncryption)) continue; if(dwIndex==pCEPWizardInfo->dwEncryptProvIndex) fSelected=TRUE; } lvItem.iItem=dwIndex; lvItem.lParam = (LPARAM)dwIndex; lvItem.pszText=pCSPInfo->pwszCSPName; iInsertedIndex=ListView_InsertItemU(hwndList, &lvItem); if(fSelected) { ListView_SetItemState( hwndList, iInsertedIndex, LVIS_SELECTED, LVIS_SELECTED); } } //make the column autosize ListView_SetColumnWidth(hwndList, 0, LVSCW_AUTOSIZE); fResult=TRUE; CLEANUP: return fResult; } //-------------------------------------------------------------------------- // // GetSelectedCSP // //-------------------------------------------------------------------------- BOOL WINAPI GetSelectedCSP(HWND hwndDlg, int idControl, DWORD *pdwCSPIndex) { BOOL fResult=FALSE; HWND hwndControl=NULL; LV_ITEM lvItem; int iIndex=0; //get the window handle of the list view if(NULL==(hwndControl=GetDlgItem(hwndDlg, idControl))) goto CLEANUP; //now, mark the one that is selected if(-1 == (iIndex= ListView_GetNextItem( hwndControl, -1, LVNI_SELECTED ))) goto CLEANUP; memset(&lvItem, 0, sizeof(LV_ITEM)); lvItem.mask=LVIF_PARAM; lvItem.iItem=iIndex; if(!ListView_GetItem(hwndControl, &lvItem)) goto CLEANUP; *pdwCSPIndex=lvItem.lParam; fResult=TRUE; CLEANUP: return fResult; } //-------------------------------------------------------------------------- // // GetSelectedKeyLength // //-------------------------------------------------------------------------- BOOL WINAPI GetSelectedKeyLength(HWND hwndDlg, int idControl, DWORD *pdwKeyLength) { int iIndex=0; BOOL fResult=FALSE; iIndex=(int)SendDlgItemMessage(hwndDlg, idControl, CB_GETCURSEL, 0, 0); if(CB_ERR==iIndex) goto CLEANUP; *pdwKeyLength=SendDlgItemMessage(hwndDlg, idControl, CB_GETITEMDATA, iIndex, 0); fResult=TRUE; CLEANUP: return fResult; } //-------------------------------------------------------------------------- // // FormatMessageStr // //-------------------------------------------------------------------------- int ListView_InsertItemU_IDS(HWND hwndList, LV_ITEMW *plvItem, UINT idsString, LPWSTR pwszText) { WCHAR wszText[MAX_STRING_SIZE]; if(pwszText) plvItem->pszText=pwszText; else { if(!LoadStringU(g_hModule, idsString, wszText, MAX_STRING_SIZE)) return -1; plvItem->pszText=wszText; } return ListView_InsertItemU(hwndList, plvItem); } //------------------------------------------------------------------------- // // populate the wizards's confirmation page in the order of Challenge, // RA informaton, and CSPs // //------------------------------------------------------------------------- void WINAPI DisplayConfirmation(HWND hwndControl, CEP_WIZARD_INFO *pCEPWizardInfo) { WCHAR wszYes[MAX_TITLE_LENGTH]; DWORD dwIndex=0; UINT ids=0; BOOL fNewItem=FALSE; WCHAR wszLength[CEP_KEY_LENGTH_STRING]; LV_COLUMNW lvC; LV_ITEMW lvItem; //delete all the old items in the listView ListView_DeleteAllItems(hwndControl); //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; //******************************************************************* //challenge lvItem.iItem=0; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_CHALLENGE_PHRASE, NULL); //content (lvItem.iSubItem)++; if(pCEPWizardInfo->fPassword) ids=IDS_YES; else ids=IDS_NO; if(LoadStringU(g_hModule, ids, wszYes, MAX_TITLE_LENGTH)) ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem,wszYes); //*************************************************************************** // RA credentials lvItem.iItem++; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_RA_CREDENTIAL, NULL); //content for(dwIndex=0; dwIndexrgpwszName[dwIndex]) { if(TRUE==fNewItem) { //increase the row lvItem.iItem++; lvItem.pszText=L""; lvItem.iSubItem=0; ListView_InsertItemU(hwndControl, &lvItem); } else fNewItem=TRUE; lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->rgpwszName[dwIndex]); } } //*************************************************************************** //CSPInfo if(pCEPWizardInfo->fEnrollAdv) { //signature CSP Name lvItem.iItem++; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_CSP, NULL); lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].pwszCSPName); //signaure key length lvItem.iItem++; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_SIGN_KEY_LENGTH, NULL); lvItem.iSubItem++; _ltow(pCEPWizardInfo->dwSignKeyLength, wszLength, 10); ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength); //encryption CSP name lvItem.iItem++; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_CSP, NULL); lvItem.iSubItem++; ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName); //encryption key length lvItem.iItem++; lvItem.iSubItem=0; ListView_InsertItemU_IDS(hwndControl, &lvItem, IDS_ENCRYPT_KEY_LENGTH, NULL); lvItem.iSubItem++; _ltow(pCEPWizardInfo->dwEncryptKeyLength, wszLength, 10); ListView_SetItemTextU(hwndControl, lvItem.iItem, lvItem.iSubItem, wszLength); } //autosize the columns ListView_SetColumnWidth(hwndControl, 0, LVSCW_AUTOSIZE); ListView_SetColumnWidth(hwndControl, 1, LVSCW_AUTOSIZE); return; } //-------------------------------------------------------------------- // // Main Function // //-------------------------------------------------------------------------- extern "C" int _cdecl wmain(int nArgs, WCHAR ** rgwszArgs) { BOOL fResult=FALSE; UINT idsMsg=IDS_FAIL_INIT_WIZARD; HRESULT hr=E_FAIL; PROPSHEETPAGEW rgCEPSheet[CEP_PROP_SHEET]; PROPSHEETHEADERW cepHeader; CEP_PAGE_INFO rgCEPPageInfo[CEP_PROP_SHEET]= {(LPCWSTR)MAKEINTRESOURCE(IDD_WELCOME), CEP_Welcome, (LPCWSTR)MAKEINTRESOURCE(IDD_CHALLENGE), CEP_Challenge, (LPCWSTR)MAKEINTRESOURCE(IDD_ENROLL), CEP_Enroll, (LPCWSTR)MAKEINTRESOURCE(IDD_CSP), CEP_CSP, (LPCWSTR)MAKEINTRESOURCE(IDD_COMPLETION), CEP_Completion, }; DWORD dwIndex=0; WCHAR wszTitle[MAX_TITLE_LENGTH]; INT_PTR iReturn=-1; ENUM_CATYPES catype; DWORD dwWaitCounter=0; BOOL fEnterpriseCA=FALSE; CEP_WIZARD_INFO CEPWizardInfo; memset(rgCEPSheet, 0, sizeof(PROPSHEETPAGEW)*CEP_PROP_SHEET); memset(&cepHeader, 0, sizeof(PROPSHEETHEADERW)); memset(&CEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO)); if(FAILED(CoInitialize(NULL))) return FALSE; if(NULL==(g_hModule=GetModuleHandle(NULL))) goto CommonReturn; if(!IsValidInstallation(&idsMsg)) goto ErrorReturn; if(!IsCaRunning()) { if(S_OK != (hr=CepStartService(CERTSVC_NAME))) { idsMsg=IDS_NO_CA_RUNNING; goto ErrorWithHResultReturn; } } //make sure the CA is up running for (dwWaitCounter=0; dwWaitCounter < 15; dwWaitCounter++) { if (!IsCaRunning()) Sleep(1000); else break; } if (15 == dwWaitCounter) { idsMsg=IDS_CAN_NOT_START_CA; goto ErrorWithHResultReturn; } //make sure we have the correct admin rights based on the CA type if(S_OK != (hr=GetCaType(&catype))) { idsMsg=IDS_FAIL_GET_CA_TYPE; goto ErrorWithHResultReturn; } //some cisco routers only work with root CA if((ENUM_ENTERPRISE_ROOTCA != catype) && (ENUM_STANDALONE_ROOTCA != catype)) { if(IDNO==CEPMessageBox(NULL, IDS_CAN_NOT_ROOT_CA, MB_ICONWARNING|MB_YESNO|MB_APPLMODAL)) { fResult=FALSE; goto CommonReturn; } } if (ENUM_ENTERPRISE_ROOTCA==catype || ENUM_ENTERPRISE_SUBCA==catype) { fEnterpriseCA=TRUE; // check for enterprise admin if(!IsUserInAdminGroup(TRUE)) { idsMsg=IDS_NOT_ENT_ADMIN; goto ErrorReturn; } } else { // check for machine admin if(!IsUserInAdminGroup(FALSE)) { idsMsg=IDS_NOT_MACHINE_ADMIN; goto ErrorReturn; } } //everything looks good. We start the wizard page if(!CEPWizardInit()) goto ErrorWithWin32Return; CEPWizardInfo.fEnrollAdv=FALSE; CEPWizardInfo.fPassword=TRUE; CEPWizardInfo.fEnterpriseCA=fEnterpriseCA; if(!CEPGetCSPInformation(&CEPWizardInfo)) { idsMsg=IDS_FAIL_GET_CSP_INFO; goto ErrorWithWin32Return; } for(dwIndex=0; dwIndexfPassword, pCEPWizardInfo->fEnterpriseCA)) { idsMsg=IDS_FAIL_UPDATE_REGISTRY; goto ErrorWithWin32Return; } //************************************************************************************ // Add the virtual root if(S_OK != (hr=AddVDir(CEP_DIR_NAME))) { idsMsg=IDS_FAIL_ADD_VROOT; goto ErrorWithHResultReturn; } //************************************************************************************ //Update the certificate template and its ACLs for enterprise CA if (pCEPWizardInfo->fEnterpriseCA) { // get the templates and permisisons right if(S_OK != (hr=DoCertSrvEnterpriseChanges())) { idsMsg=IDS_FAIL_ADD_TEMPLATE; goto ErrorWithHResultReturn; } } //************************************************************************************ //Enroll for the RA certificate //build the name in the form of L"C=US;S=Washington;CN=TestSetupUtil" pwszRADN=(LPWSTR)malloc(sizeof(WCHAR)); if(NULL==pwszRADN) { idsMsg=IDS_NO_MEMORY; goto ErrorReturn; } *pwszRADN=L'\0'; for(dwIndex=0; dwIndexrgpwszName)[dwIndex]) { if(0 != wcslen(pwszRADN)) wcscat(pwszRADN, L";"); pwszRADN=(LPWSTR)realloc(pwszRADN, sizeof(WCHAR) * (wcslen(pwszRADN) + wcslen((pCEPWizardInfo->rgpwszName)[dwIndex]) + wcslen(L";") + wcslen(g_rgRAEnrollInfo[dwIndex].pwszPreFix) + 1)); if(NULL==pwszRADN) { idsMsg=IDS_NO_MEMORY; goto ErrorReturn; } wcscat(pwszRADN,g_rgRAEnrollInfo[dwIndex].pwszPreFix); wcscat(pwszRADN,(pCEPWizardInfo->rgpwszName)[dwIndex]); } } if(S_OK != (hr=EnrollForRACertificates( pwszRADN, (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].pwszCSPName, (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwSignProvIndex].dwCSPType, pCEPWizardInfo->dwSignKeyLength, (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].pwszCSPName, (pCEPWizardInfo->rgCSPInfo)[pCEPWizardInfo->dwEncryptProvIndex].dwCSPType, pCEPWizardInfo->dwEncryptKeyLength))) { idsMsg=IDS_FAIL_ENROLL_RA_CERT; goto ErrorWithHResultReturn; } //************************************************************************************ //CA policy registry CepStopService(CERTSVC_NAME, &bStart); if(S_OK != (hr=DoCertSrvRegChanges(FALSE))) { idsMsg=IDS_FAIL_UPDATE_CERTSVC; goto ErrorWithHResultReturn; } if(S_OK != (hr=CepStartService(CERTSVC_NAME))) { idsMsg=IDS_FAIL_START_CERTSVC; goto ErrorWithHResultReturn; } //make sure the CA is up running for (dwWaitCounter=0; dwWaitCounter < 15; dwWaitCounter++) { if (!IsCaRunning()) Sleep(1000); else break; } if (15 == dwWaitCounter) { idsMsg=IDS_CAN_NOT_START_CA; goto ErrorWithHResultReturn; } //************************************************************************************ //success //inform the user of the password location and URL dwSize=0; GetComputerNameExW(ComputerNamePhysicalDnsHostname, NULL, &dwSize); pwszComputerName=(LPWSTR)malloc(dwSize * sizeof(WCHAR)); if(NULL==pwszComputerName) { idsMsg=IDS_NO_MEMORY; goto ErrorReturn; } if(!GetComputerNameExW(ComputerNamePhysicalDnsHostname, pwszComputerName, &dwSize)) { idsMsg=IDS_FAIL_GET_COMPUTER_NAME; goto ErrorWithWin32Return; } if(!FormatMessageUnicode(&pwszText, IDS_CEP_SUCCESS_INFO, pwszComputerName, CEP_DIR_NAME, CEP_DLL_NAME)) { idsMsg=IDS_NO_MEMORY; goto ErrorWithWin32Return; } wszTitle[0]=L'\0'; LoadStringU(g_hModule, IDS_WIZARD_CAPTION, wszTitle, sizeof(wszTitle)/sizeof(wszTitle[0])); MessageBoxU(hWnd, pwszText, wszTitle, MB_OK | MB_APPLMODAL); fResult=TRUE; CommonReturn: if(pwszText) LocalFree((HLOCAL)pwszText); if(pwszComputerName) free(pwszComputerName); if(pwszRADN) free(pwszRADN); return fResult; ErrorReturn: fResult=FALSE; CEPMessageBox(hWnd, idsMsg, MB_ICONERROR|MB_OK|MB_APPLMODAL); goto CommonReturn; ErrorWithHResultReturn: fResult=FALSE; CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL); goto CommonReturn; ErrorWithWin32Return: fResult=FALSE; hr=HRESULT_FROM_WIN32(GetLastError()); CEPErrorMessageBox(hWnd, idsMsg, hr, MB_ICONERROR|MB_OK|MB_APPLMODAL); goto CommonReturn; } //----------------------------------------------------------------------- // // CEPGetCSPInformation // // We initialize the following members of CEP_WIZARD_INFO: // // CEP_CSP_INFO *rgCSPInfo; // DWORD dwCSPCount; // DWORD dwSignProvIndex; // DWORD dwSignKeySize; // DWORD dwEncryptProvIndex; // DWORD dwEncryptKeySize; // // // typedef struct _CEP_CSP_INFO //{ // LPWSTR pwszCSPName; // DWORD dwCSPType; // BOOL fSignature; // BOOL fExchange; // DWORD dwMaxSign; //Max key length of signature // DWORD dwMinSign; //Min key length of signature // DWORD dwDefaultSign; //default key length of signature // DWORD dwMaxEncrypt; // DWORD dwMinEncrypt; // DWORD dwDefaultEncrypt; // DWORD *pdwSignList; //the table of possible signing key length // DWORD dwSignCount; //the count of entries in the table // DWORD *pdwEncryptList; // DWORD dwEncryptCount; //}CEP_CSP_INFO; // // //------------------------------------------------------------------------ BOOL WINAPI CEPGetCSPInformation(CEP_WIZARD_INFO *pCEPWizardInfo) { BOOL fResult=FALSE; DWORD dwCSPIndex=0; DWORD dwProviderType=0; DWORD cbSize=0; DWORD dwFlags=0; DWORD dwIndex=0; int iDefaultSignature=-1; int iDefaultEncryption=-1; PROV_ENUMALGS_EX paramData; CEP_CSP_INFO *pCSPInfo=NULL; HCRYPTPROV hProv = NULL; //enum all the providers on the system while(CryptEnumProvidersU( dwCSPIndex, NULL, 0, &dwProviderType, NULL, &cbSize)) { pCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO)); if(NULL == pCSPInfo) goto MemoryErr; memset(pCSPInfo, 0, sizeof(CEP_CSP_INFO)); pCSPInfo->pwszCSPName=(LPWSTR)malloc(cbSize); if(NULL==(pCSPInfo->pwszCSPName)) goto MemoryErr; //get the CSP name and the type if(!CryptEnumProvidersU( dwCSPIndex, NULL, 0, &(pCSPInfo->dwCSPType), pCSPInfo->pwszCSPName, &cbSize)) goto TryNext; if(!CryptAcquireContextU(&hProv, NULL, pCSPInfo->pwszCSPName, pCSPInfo->dwCSPType, CRYPT_VERIFYCONTEXT)) goto TryNext; //get the max/min of key length for both signature and encryption dwFlags=CRYPT_FIRST; cbSize=sizeof(paramData); memset(¶mData, 0, sizeof(PROV_ENUMALGS_EX)); while(CryptGetProvParam( hProv, PP_ENUMALGS_EX, (BYTE *) ¶mData, &cbSize, dwFlags)) { if (ALG_CLASS_SIGNATURE == GET_ALG_CLASS(paramData.aiAlgid)) { pCSPInfo->fSignature=TRUE; pCSPInfo->dwMaxSign = paramData.dwMaxLen; pCSPInfo->dwMinSign = paramData.dwMinLen; } if (ALG_CLASS_KEY_EXCHANGE == GET_ALG_CLASS(paramData.aiAlgid)) { pCSPInfo->fEncryption=TRUE; pCSPInfo->dwMaxEncrypt = paramData.dwMaxLen; pCSPInfo->dwMinEncrypt = paramData.dwMinLen; } dwFlags=0; cbSize=sizeof(paramData); memset(¶mData, 0, sizeof(PROV_ENUMALGS_EX)); } //the min/max has to within the limit if(pCSPInfo->fSignature) { if(pCSPInfo->dwMaxSign < g_rgdwSmallKeyLength[0]) pCSPInfo->fSignature=FALSE; if(pCSPInfo->dwMinSign > g_rgdwKeyLength[g_dwKeyLengthCount-1]) pCSPInfo->fSignature=FALSE; } if(pCSPInfo->fEncryption) { if(pCSPInfo->dwMaxEncrypt < g_rgdwSmallKeyLength[0]) pCSPInfo->fEncryption=FALSE; if(pCSPInfo->dwMinEncrypt > g_rgdwKeyLength[g_dwKeyLengthCount-1]) pCSPInfo->fEncryption=FALSE; } if((FALSE == pCSPInfo->fEncryption) && (FALSE==pCSPInfo->fSignature)) goto TryNext; //decide the default key length for(dwIndex=0; dwIndexfSignature) && (0==pCSPInfo->dwDefaultSign)) { if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinSign) && (g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxSign) ) pCSPInfo->dwDefaultSign=g_rgdwDefaultKey[dwIndex]; } if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt)) { if((g_rgdwDefaultKey[dwIndex] >= pCSPInfo->dwMinEncrypt) && (g_rgdwDefaultKey[dwIndex] <= pCSPInfo->dwMaxEncrypt) ) pCSPInfo->dwDefaultEncrypt=g_rgdwDefaultKey[dwIndex]; } } //make sure that we have find a default if((pCSPInfo->fSignature) && (0==pCSPInfo->dwDefaultSign)) goto TryNext; if((pCSPInfo->fEncryption) && (0==pCSPInfo->dwDefaultEncrypt)) goto TryNext; //decide the display list if(pCSPInfo->fSignature) { if(pCSPInfo->dwMaxSign <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1]) { pCSPInfo->pdwSignList=g_rgdwSmallKeyLength; pCSPInfo->dwSignCount=g_dwSmallKeyLengthCount; } else { pCSPInfo->pdwSignList=g_rgdwKeyLength; pCSPInfo->dwSignCount=g_dwKeyLengthCount; } } if(pCSPInfo->fEncryption) { if(pCSPInfo->dwMaxEncrypt <= g_rgdwSmallKeyLength[g_dwSmallKeyLengthCount-1]) { pCSPInfo->pdwEncryptList=g_rgdwSmallKeyLength; pCSPInfo->dwEncryptCount=g_dwSmallKeyLengthCount; } else { pCSPInfo->pdwEncryptList=g_rgdwKeyLength; pCSPInfo->dwEncryptCount=g_dwKeyLengthCount; } } //the CSP looks good (pCEPWizardInfo->dwCSPCount)++; //realloc to mapped to LocalRealloc which does not take NULL if(1 == pCEPWizardInfo->dwCSPCount) pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)malloc(sizeof(CEP_CSP_INFO)); else pCEPWizardInfo->rgCSPInfo=(CEP_CSP_INFO *)realloc(pCEPWizardInfo->rgCSPInfo, (pCEPWizardInfo->dwCSPCount) * sizeof(CEP_CSP_INFO)); if(NULL==pCEPWizardInfo->rgCSPInfo) { pCEPWizardInfo->dwCSPCount=0; goto MemoryErr; } memcpy(&(pCEPWizardInfo->rgCSPInfo[(pCEPWizardInfo->dwCSPCount)-1]), pCSPInfo, sizeof(CEP_CSP_INFO)); free(pCSPInfo); pCSPInfo=NULL; //we default to use RSA_FULL if(0 == _wcsicmp(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].pwszCSPName, MS_DEF_PROV_W)) { if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fSignature) { iDefaultSignature=pCEPWizardInfo->dwCSPCount-1; } if(pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwCSPCount-1].fEncryption) { iDefaultEncryption=pCEPWizardInfo->dwCSPCount-1; } } TryNext: cbSize=0; dwCSPIndex++; if(pCSPInfo) { if(pCSPInfo->pwszCSPName) free(pCSPInfo->pwszCSPName); free(pCSPInfo); } pCSPInfo=NULL; if(hProv) CryptReleaseContext(hProv, 0); hProv=NULL; } //we need to have some valid data if((0==pCEPWizardInfo->dwCSPCount) || (NULL==pCEPWizardInfo->rgCSPInfo)) goto InvalidArgErr; //get the default CSP selection if(-1 != iDefaultSignature) pCEPWizardInfo->dwSignProvIndex=iDefaultSignature; else { //find the 1st signature CSP for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++) { if(pCEPWizardInfo->rgCSPInfo[dwIndex].fSignature) { pCEPWizardInfo->dwSignProvIndex=dwIndex; break; } //we do no have signature CSPs if(dwIndex == pCEPWizardInfo->dwCSPCount) goto InvalidArgErr; } } pCEPWizardInfo->dwSignKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwSignProvIndex].dwDefaultSign; if(-1 != iDefaultEncryption) pCEPWizardInfo->dwEncryptProvIndex=iDefaultEncryption; else { //find the 1st exchange CSP for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++) { if(pCEPWizardInfo->rgCSPInfo[dwIndex].fEncryption) { pCEPWizardInfo->dwEncryptProvIndex=dwIndex; break; } //we do no have encryption CSPs if(dwIndex == pCEPWizardInfo->dwCSPCount) goto InvalidArgErr; } } pCEPWizardInfo->dwEncryptKeyLength=pCEPWizardInfo->rgCSPInfo[pCEPWizardInfo->dwEncryptProvIndex].dwDefaultEncrypt; fResult=TRUE; CommonReturn: return fResult; ErrorReturn: if(pCSPInfo) { if(pCSPInfo->pwszCSPName) free(pCSPInfo->pwszCSPName); free(pCSPInfo); } if(hProv) CryptReleaseContext(hProv, 0); if(pCEPWizardInfo->rgCSPInfo) { for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++) { if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName) free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName); } free(pCEPWizardInfo->rgCSPInfo); } pCEPWizardInfo->dwCSPCount=0; pCEPWizardInfo->rgCSPInfo=NULL; fResult=FALSE; goto CommonReturn; SET_ERROR(MemoryErr, E_OUTOFMEMORY); SET_ERROR(InvalidArgErr, E_INVALIDARG); } //----------------------------------------------------------------------- // // UpdateCEPRegistry // //------------------------------------------------------------------------ BOOL WINAPI UpdateCEPRegistry(BOOL fPassword, BOOL fEnterpriseCA) { BOOL fResult=FALSE; DWORD dwDisposition=0; LPWSTR pwszReg[]={MSCEP_REFRESH_LOCATION, MSCEP_PASSWORD_LOCATION, MSCEP_PASSWORD_MAX_LOCATION, MSCEP_PASSWORD_VALIDITY_LOCATION, MSCEP_CACHE_REQUEST_LOCATION, MSCEP_CATYPE_LOCATION}; DWORD dwRegCount=0; DWORD dwRegIndex=0; HKEY hKey=NULL; //we delete all existing CEP related registry keys dwRegCount=sizeof(pwszReg)/sizeof(pwszReg[0]); for(dwRegIndex=0; dwRegIndex < dwRegCount; dwRegIndex++) { RegDeleteKeyU(HKEY_LOCAL_MACHINE, pwszReg[dwRegIndex]); } //password if (ERROR_SUCCESS != RegCreateKeyExU( HKEY_LOCAL_MACHINE, MSCEP_PASSWORD_LOCATION, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition)) goto RegErr; if(fPassword) dwDisposition=1; else dwDisposition=0; if(ERROR_SUCCESS != RegSetValueExU( hKey, MSCEP_KEY_PASSWORD, 0, REG_DWORD, (BYTE *)&dwDisposition, sizeof(dwDisposition))) goto RegErr; if(hKey) RegCloseKey(hKey); hKey=NULL; //caType dwDisposition=0; if (ERROR_SUCCESS != RegCreateKeyExU( HKEY_LOCAL_MACHINE, MSCEP_CATYPE_LOCATION, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition)) goto RegErr; if(fEnterpriseCA) dwDisposition=1; else dwDisposition=0; if(ERROR_SUCCESS != RegSetValueExU( hKey, MSCEP_KEY_CATYPE, 0, REG_DWORD, (BYTE *)&dwDisposition, sizeof(dwDisposition))) goto RegErr; fResult=TRUE; CommonReturn: if(hKey) RegCloseKey(hKey); return fResult; ErrorReturn: fResult=FALSE; goto CommonReturn; TRACE_ERROR(RegErr); } //----------------------------------------------------------------------- // // EmptyCEPStore // //------------------------------------------------------------------------ BOOL WINAPI EmptyCEPStore() { BOOL fResult=TRUE; HCERTSTORE hCEPStore=NULL; PCCERT_CONTEXT pCurCert=NULL; if(NULL == (hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, ENCODE_TYPE, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_READONLY_FLAG | CERT_STORE_OPEN_EXISTING_FLAG, CEP_STORE_NAME))) return TRUE; if(NULL != (pCurCert=CertEnumCertificatesInStore(hCEPStore, NULL))) { CertFreeCertificateContext(pCurCert); fResult=FALSE; } CertCloseStore(hCEPStore, 0); return fResult; } //----------------------------------------------------------------------- // // RemoveRACertificates // //------------------------------------------------------------------------ BOOL WINAPI RemoveRACertificates() { PCCERT_CONTEXT pCurCert=NULL; PCCERT_CONTEXT pPreCert=NULL; PCCERT_CONTEXT pDupCert=NULL; BOOL fResult=TRUE; HCERTSTORE hCEPStore=NULL; if(hCEPStore=CertOpenStore(CERT_STORE_PROV_SYSTEM_W, ENCODE_TYPE, NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, CEP_STORE_NAME)) { while(pCurCert=CertEnumCertificatesInStore(hCEPStore, pPreCert)) { if(pDupCert=CertDuplicateCertificateContext(pCurCert)) { if(!CertDeleteCertificateFromStore(pDupCert)) { fResult=FALSE; } pDupCert=NULL; } else fResult=FALSE; pPreCert=pCurCert; } CertCloseStore(hCEPStore, 0); } return fResult; } //----------------------------------------------------------------------- // // FreeCEPWizardInfo // //------------------------------------------------------------------------ void WINAPI FreeCEPWizardInfo(CEP_WIZARD_INFO *pCEPWizardInfo) { DWORD dwIndex=0; if(pCEPWizardInfo) { DestroyFonts(pCEPWizardInfo->hBigBold, pCEPWizardInfo->hBold); for(dwIndex=0; dwIndexrgpwszName[dwIndex]) free(pCEPWizardInfo->rgpwszName[dwIndex]); } if(pCEPWizardInfo->rgCSPInfo) { for(dwIndex=0; dwIndex < pCEPWizardInfo->dwCSPCount; dwIndex++) { if(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName) free(pCEPWizardInfo->rgCSPInfo[dwIndex].pwszCSPName); } free(pCEPWizardInfo->rgCSPInfo); } memset(pCEPWizardInfo, 0, sizeof(CEP_WIZARD_INFO)); } } //----------------------------------------------------------------------- // // CEPWizardInit // //------------------------------------------------------------------------ BOOL WINAPI CEPWizardInit() { INITCOMMONCONTROLSEX initcomm = { sizeof(initcomm), ICC_NATIVEFNTCTL_CLASS | ICC_LISTVIEW_CLASSES }; return InitCommonControlsEx(&initcomm); } //----------------------------------------------------------------------- // // IsValidInstallation // //------------------------------------------------------------------------ BOOL WINAPI IsValidInstallation(UINT *pidsMsg) { if(!IsNT5()) { *pidsMsg=IDS_NO_NT5; return FALSE; } if(!IsIISInstalled()) { *pidsMsg=IDS_NO_IIS; return FALSE; } if(!IsGoodCaInstalled()) { *pidsMsg=IDS_NO_GOOD_CA; return FALSE; } return TRUE; } //----------------------------------------------------------------------- // // CEPErrorMessageBox // //------------------------------------------------------------------------ int WINAPI CEPErrorMessageBox( HWND hWnd, UINT idsReason, HRESULT hr, UINT uType ) { WCHAR wszReason[MAX_STRING_SIZE]; WCHAR wszCaption[MAX_STRING_SIZE]; UINT intReturn=0; LPWSTR pwszText=NULL; LPWSTR pwszErrorMsg=NULL; if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption))) goto CLEANUP; if(!LoadStringU(g_hModule, idsReason, wszReason, sizeof(wszReason))) goto CLEANUP; if(!FAILED(hr)) hr=E_FAIL; //using W version because this is a NT5 only function call if(FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPWSTR) &pwszErrorMsg, 0, NULL)) { if(!FormatMessageUnicode(&pwszText, IDS_CEP_ERROR_MSG_HR, wszReason, pwszErrorMsg)) goto CLEANUP; } else { if(!FormatMessageUnicode(&pwszText, IDS_CEP_ERROR_MSG, wszReason)) goto CLEANUP; } intReturn=MessageBoxU(hWnd, pwszText, wszCaption, uType); CLEANUP: if(pwszText) LocalFree((HLOCAL)pwszText); if(pwszErrorMsg) LocalFree((HLOCAL)pwszText); return intReturn; } //----------------------------------------------------------------------- // // CEPMessageBox // //------------------------------------------------------------------------ int WINAPI CEPMessageBox( HWND hWnd, UINT idsText, UINT uType ) { WCHAR wszText[MAX_STRING_SIZE]; WCHAR wszCaption[MAX_STRING_SIZE]; UINT intReturn=0; if(!LoadStringU(g_hModule, IDS_MEG_CAPTION, wszCaption, sizeof(wszCaption))) return 0; if(!LoadStringU(g_hModule, idsText, wszText, sizeof(wszText))) return 0; intReturn=MessageBoxU(hWnd, wszText, wszCaption, uType); return intReturn; } //-------------------------------------------------------------------------- // // SetControlFont // //-------------------------------------------------------------------------- void WINAPI SetControlFont( IN HFONT hFont, IN HWND hwnd, IN INT nId ) { if( hFont ) { HWND hwndControl = GetDlgItem(hwnd, nId); if( hwndControl ) { SetWindowFont(hwndControl, hFont, TRUE); } } } //-------------------------------------------------------------------------- // // SetupFonts // //-------------------------------------------------------------------------- BOOL WINAPI SetupFonts( IN HINSTANCE hInstance, IN HWND hwnd, IN HFONT *pBigBoldFont, IN HFONT *pBoldFont ) { // // Create the fonts we need based on the dialog font // NONCLIENTMETRICS ncm = {0}; ncm.cbSize = sizeof(ncm); SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0); LOGFONT BigBoldLogFont = ncm.lfMessageFont; LOGFONT BoldLogFont = ncm.lfMessageFont; // // Create Big Bold Font and Bold Font // BigBoldLogFont.lfWeight = FW_BOLD; BoldLogFont.lfWeight = FW_BOLD; INT BigBoldFontSize = 12; HDC hdc = GetDC( hwnd ); if( hdc ) { BigBoldLogFont.lfHeight = 0 - (GetDeviceCaps(hdc,LOGPIXELSY) * BigBoldFontSize / 72); *pBigBoldFont = CreateFontIndirect(&BigBoldLogFont); *pBoldFont = CreateFontIndirect(&BoldLogFont); ReleaseDC(hwnd,hdc); if(*pBigBoldFont && *pBoldFont) return TRUE; else { if( *pBigBoldFont ) { DeleteObject(*pBigBoldFont); } if( *pBoldFont ) { DeleteObject(*pBoldFont); } return FALSE; } } return FALSE; } //-------------------------------------------------------------------------- // // DestroyFonts // //-------------------------------------------------------------------------- void WINAPI DestroyFonts( IN HFONT hBigBoldFont, IN HFONT hBoldFont ) { if( hBigBoldFont ) { DeleteObject( hBigBoldFont ); } if( hBoldFont ) { DeleteObject( hBoldFont ); } } //-------------------------------------------------------------------------- // // FormatMessageUnicode // //-------------------------------------------------------------------------- BOOL WINAPI FormatMessageUnicode(LPWSTR *ppwszFormat,UINT ids,...) { // get format string from resources WCHAR wszFormat[1000]; va_list argList; DWORD cbMsg=0; BOOL fResult=FALSE; HRESULT hr=S_OK; if(NULL == ppwszFormat) goto InvalidArgErr; if(!LoadStringU(g_hModule, ids, wszFormat, sizeof(wszFormat))) goto LoadStringError; // format message into requested buffer va_start(argList, ids); cbMsg = FormatMessageU( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING, wszFormat, 0, // dwMessageId 0, // dwLanguageId (LPWSTR) (ppwszFormat), 0, // minimum size to allocate &argList); va_end(argList); if(!cbMsg) goto FormatMessageError; fResult=TRUE; CommonReturn: return fResult; ErrorReturn: fResult=FALSE; goto CommonReturn; TRACE_ERROR(LoadStringError); TRACE_ERROR(FormatMessageError); SET_ERROR(InvalidArgErr, E_INVALIDARG); }