// // File: select.cpp // // Description: This file contains the implmentation code for the // "Certificate Select" dialog. // // // M00BUG -- Mutli-Select is not implemented // #include "pch.hxx" #include "demand.h" #define REIDK_PRIVATE TRUE #define ARRAYSIZE(_rg) (sizeof(_rg)/sizeof(_rg[0])) #pragma warning (disable: 4201) // nameless struct/union #pragma warning (disable: 4514) // remove inline functions #pragma warning (disable: 4127) // conditional expression is constant //#include #ifdef MAC #include #else // !MAC HMODULE HmodRichEdit = NULL; #endif // !MAC HINSTANCE HinstDll; BOOL FIsWin95 = TRUE; const HELPMAP RgctxSelect[] = { {IDC_CS_CERTLIST, IDH_CS_CERTLIST}, {IDC_CS_PROPERTIES, IDH_CS_PROPERTIES}, {IDC_CS_ALGORITHM, IDH_CS_ALGORITHM}}; #ifdef WIN16 #define LPCDLGTEMPLATE_X HGLOBAL #else #define LPCDLGTEMPLATE_X LPCDLGTEMPLATE #endif // // Generic DLL Main function, we need to get our own hinstance handle. // // We don't need to get thread attaches however. #ifndef WIN16 #ifdef MAC BOOL WINAPI FormatPKIXEmailProtection( DWORD /*dwCertEncodingType*/, DWORD /*dwFormatType*/, DWORD /*dwFormatStrType*/, void * /*pFormatStruct*/, LPCSTR /*lpszStructType*/, const BYTE * /*pbEncoded*/, DWORD /*cbEncoded*/, void * pbFormat, DWORD * pcbFormat); static const CRYPT_OID_FUNC_ENTRY SpcFormatFuncTable[] = { szOID_PKIX_KP_EMAIL_PROTECTION, FormatPKIXEmailProtection, }; #define SPC_FORMAT_FUNC_COUNT (sizeof(SpcFormatFuncTable) / sizeof(SpcFormatFuncTable[0])) BOOL WINAPI CryptDlgASNDllMain(HINSTANCE hInst, ULONG ulReason, LPVOID) { BOOL fRet = TRUE; switch (ulReason) { case DLL_PROCESS_ATTACH: fRet = CryptInstallOIDFunctionAddress(hInst, X509_ASN_ENCODING, CRYPT_OID_FORMAT_OBJECT_FUNC, SPC_FORMAT_FUNC_COUNT, SpcFormatFuncTable, 0); break; case DLL_PROCESS_DETACH: case DLL_THREAD_DETACH: default: break; } return fRet; } #endif // MAC // DLL Entry point #ifdef MAC EXTERN_C BOOL WINAPI CryptDlg_DllMain(HANDLE hInst, ULONG ulReason, LPVOID pv) #else // !MAC extern BOOL WINAPI WXP_CertTrustDllMain( HINSTANCE hInst, ULONG ulReason, LPVOID ); BOOL WINAPI DllMain(HANDLE hInst, ULONG ulReason, LPVOID pv) #endif // MAC { switch( ulReason ) { case DLL_PROCESS_ATTACH: HinstDll = (HINSTANCE) hInst; // Kill all thread attach and detach messages DisableThreadLibraryCalls(HinstDll); #ifndef MAC // Are we running in Win95 or something equally bad FIsWin95 = IsWin95(); InitDemandLoadedLibs(); #endif // !MAC break; case DLL_PROCESS_DETACH: #ifndef MAC FreeDemandLoadedLibs(); // If the rich edit dll was loaded, then unload it now if (HmodRichEdit != NULL) { FreeLibrary(HmodRichEdit); } #endif // !MAC break; } #ifndef MAC return WXP_CertTrustDllMain((HINSTANCE) hInst, ulReason, pv); #else // MAC // Handle the ASN OID functions return CryptDlgASNDllMain((HINSTANCE)hInst, ulReason, pv); #endif // !MAC } #else // WIN16 BOOL FAR PASCAL LibMain (HINSTANCE hDll, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine) { HinstDll = (HINSTANCE) hDll; InitDemandLoadedLibs(); // Done return TRUE; } int CALLBACK WEP(int x) { FreeDemandLoadedLibs(); // If the rich edit dll was loaded, then unload it now if (HmodRichEdit != NULL) { FreeLibrary(HmodRichEdit); } return 1; } #endif // !WIN16 #ifndef WIN16 DWORD ComputeExtent(HWND hwnd, int id) { int c; ULONG cb; ULONG cbMax = 0; DWORD dwExtent; DWORD dwExtentMax = 0; HDC hdc; HFONT hfontOld; HFONT hfontNew; int i; LPWSTR psz = NULL; SIZE sz; #ifndef MAC TEXTMETRICW tmW={0}; #endif // !MAC TEXTMETRICA tmA={0}; hdc = GetDC(hwnd); hfontNew = (HFONT) SendMessage(hwnd, WM_GETFONT, NULL, NULL); hfontOld = (HFONT) SelectObject(hdc, hfontNew); if (FIsWin95) { GetTextMetricsA(hdc, &tmA); } #ifndef MAC else { GetTextMetricsW(hdc, &tmW); } #endif // !MAC c = (int) SendDlgItemMessage(hwnd, id, LB_GETCOUNT, 0, 0); for (i=0; i cbMax) { free(psz); cbMax = cb + 100; psz = (LPWSTR) malloc(cbMax*sizeof(WCHAR)); if (psz == NULL) { break; } } #ifndef MAC if (FIsWin95) { #endif // !MAC SendDlgItemMessageA(hwnd, id, LB_GETTEXT, i, (LPARAM) psz); GetTextExtentPointA(hdc, (LPSTR) psz, strlen((LPSTR) psz), &sz); dwExtent = sz.cx + tmA.tmAveCharWidth; #ifndef MAC } else { SendDlgItemMessageW(hwnd, id, LB_GETTEXT, i, (LPARAM) psz); GetTextExtentPointW(hdc, psz, wcslen(psz), &sz); dwExtent = sz.cx + tmW.tmAveCharWidth; } #endif // !MAC if (dwExtent > dwExtentMax) { dwExtentMax = dwExtent; } } free(psz); SelectObject(hdc, hfontOld); ReleaseDC(hwnd, hdc); return dwExtentMax; } #else // WIN16 DWORD ComputeExtent(HWND hwnd, int id) { int c; int cb; int cbMax = 0; DWORD dwExtent; DWORD dwExtentMax = 0; HDC hdc; HFONT hfontOld; HFONT hfontNew; int i; LPWSTR psz = NULL; SIZE sz; TEXTMETRIC tm; hdc = GetDC(hwnd); hfontNew = (HFONT) SendMessage(hwnd, WM_GETFONT, NULL, NULL); hfontOld = (HFONT) SelectObject(hdc, hfontNew); GetTextMetrics(hdc, &tm); c = SendDlgItemMessage(hwnd, id, LB_GETCOUNT, 0, 0); for (i=0; i cbMax) { free(psz); cbMax = cb + 100; psz = (LPWSTR) malloc(cbMax*sizeof(WCHAR)); if (psz == NULL) { break; } } SendDlgItemMessage(hwnd, id, LB_GETTEXT, i, (LONG) psz); GetTextExtentPoint(hdc, (LPSTR) psz, strlen((LPSTR) psz), &sz); dwExtent = sz.cx + tm.tmAveCharWidth; if (dwExtent > dwExtentMax) { dwExtentMax = dwExtent; } } free(psz); SelectObject(hdc, hfontOld); ReleaseDC(hwnd, hdc); return dwExtentMax; } #endif // !WIN16 BOOL FillInFields(HWND hwnd, PCCERT_CONTEXT pccert) { LPWSTR pwsz; WCHAR rgwch[200]; LPWSTR rgpwsz[3]; rgpwsz[2] = (LPWSTR)-1; // Sentinal Value FormatAlgorithm(hwnd, IDC_CS_ALGORITHM, pccert); FormatSerialNo(hwnd, IDC_CS_SERIAL_NUMBER, pccert); FormatThumbprint(hwnd, IDC_CS_THUMBPRINT, pccert); FormatValidity(hwnd, IDC_CS_VALIDITY, pccert); rgpwsz[0] = PrettySubject(pccert); rgpwsz[1] = PrettyIssuer(pccert); LoadString(HinstDll, IDS_SELECT_INFO, rgwch, ARRAYSIZE(rgwch)); FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, rgwch, 0, 0, (LPWSTR) &pwsz, 0, (va_list *) rgpwsz); #ifndef WIN16 TruncateToWindowW(hwnd, IDC_CS_INFO, pwsz); #else TruncateToWindowA(hwnd, IDC_CS_INFO, pwsz); #endif // !WIN16 SetDlgItemText(hwnd, IDC_CS_INFO, pwsz); free(rgpwsz[0]); free(rgpwsz[1]); LocalFree((HLOCAL)pwsz); return TRUE; } INT_PTR CALLBACK SelectCertDlgProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam) { int c; CTL_USAGE ctlUsage; PCERT_CONTEXT pcertctx; BOOL f; int i; DWORD iStore; LPWSTR pwsz; PCCERT_CONTEXT pccert; PCERT_SELECT_STRUCT pcss; pcss = (PCERT_SELECT_STRUCT) GetWindowLongPtr(hwndDlg, DWLP_USER); // // If a hook proc has been registered for this dialog, then we need // to call the hook proc. Notice that if the hook proc returns TRUE // then we don't do normal processing // if ((pcss != NULL) && (pcss->dwFlags & CSS_ENABLEHOOK) && (pcss->pfnHook != 0)) { f = pcss->pfnHook(hwndDlg, msg, wParam, lParam); if (f) { return f; } } // switch (msg) { case WM_INITDIALOG: // Center the dialog on its parent // CenterThisDialog(hwndDlg); // Save the pointer to the control structure for later use. SetWindowLongPtr(hwndDlg, DWLP_USER, lParam); // pcss = (PCERT_SELECT_STRUCT) lParam; // // Is there a title to be displayed? // if (pcss->szTitle != NULL) { if (FIsWin95) { SendMessageA(hwndDlg, WM_SETTEXT, 0, (LPARAM) pcss->szTitle); } #ifndef WIN16 #ifndef MAC else { SendMessageW(hwndDlg, WM_SETTEXT, 0, (LPARAM) pcss->szTitle); } #endif // !MAC #endif // !WIN16 } // // If we want a help button, then show it // if (pcss->dwFlags & CSS_SHOW_HELP) { ShowWindow(GetDlgItem(hwndDlg, IDHELP), SW_SHOW); } // // Check to see if the properties button should be suppressed // if (pcss->dwFlags & CSS_HIDE_PROPERTIES) { ShowWindow(GetDlgItem(hwndDlg, IDC_CS_PROPERTIES), SW_HIDE); } // // Let populate the list box, walk through the list of stores // to populate the list // if (pcss->szPurposeOid != NULL) { ctlUsage.cUsageIdentifier = 1; ctlUsage.rgpszUsageIdentifier = (LPSTR *) &pcss->szPurposeOid; } for (iStore = 0; iStore < pcss->cCertStore; iStore++) { pccert = NULL; if (!pcss->arrayCertStore[iStore]) continue; while (TRUE) { // // Get the next certificate in the current store. If // we are finished then move on to the next store // if (pcss->szPurposeOid != NULL) { pccert = CertFindCertificateInStore( pcss->arrayCertStore[iStore], CRYPT_ASN_ENCODING, CERT_FIND_OPTIONAL_CTL_USAGE_FLAG, CERT_FIND_CTL_USAGE, &ctlUsage, pccert); } else { pccert = CertEnumCertificatesInStore( pcss->arrayCertStore[iStore], pccert); } if (pccert == NULL) { break; } // // Filter the certificate according to the purpse desired // // // If we have a filter set, then call back and see if // the filter approves the certificate. If it is not // approved then move onto the next certificate in this // store. // if (pcss->pfnFilter != NULL) { if (!pcss->pfnFilter(pccert, pcss->lCustData, 0, 0)) { continue; } } // // If there is no filter function, then kill all V1 certs // else { if (pccert->pCertInfo->dwVersion < 2) { continue; } } // // Convert the certificate subject to a name // pwsz = PrettySubjectIssuer(pccert); i = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_ADDSTRING, 0, (LPARAM) pwsz); SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_SETITEMDATA, i, (LPARAM) CertDuplicateCertificateContext(pccert)); free(pwsz); } } SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_SETHORIZONTALEXTENT, ComputeExtent(hwndDlg, IDC_CS_CERTLIST), 0); c = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCOUNT, 0, 0); if (c != 0 && pcss->arrayCertContext[0] != NULL) { for (i=0; iarrayCertContext[0]->pCertInfo, pcertctx->pCertInfo)) { SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_SETCURSEL, i, 0); pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); FillInFields(hwndDlg, pcertctx); break; } } } else { // no certs at all or no default certificate, // so there is no selection in the listbox EnableWindow(GetDlgItem(hwndDlg, IDC_CS_PROPERTIES), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDC_CS_FINEPRINT), FALSE); EnableWindow(GetDlgItem(hwndDlg, IDOK), FALSE); } if ((pcss->dwFlags & CSS_ENABLEHOOK) && (pcss->pfnHook != 0)) { f = pcss->pfnHook(hwndDlg, msg, wParam, lParam); if (f) { return f; } } return TRUE; case WM_COMMAND: switch (LOWORD(wParam)) { case IDOK: i = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCURSEL, 0, 0); if (i != LB_ERR) { // Free the old cert if there is one if (pcss->arrayCertContext[0] != NULL) { CertFreeCertificateContext(pcss->arrayCertContext[0]); } // Get the new cert from the system. pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); // Put the new cert into the location pcss->cCertContext = 1; pcss->arrayCertContext[0] = CertDuplicateCertificateContext(pcertctx); } else { pcss->cCertContext = 0; } EndDialog(hwndDlg, IDOK); return TRUE; case IDCANCEL: EndDialog(hwndDlg, IDCANCEL); return TRUE; case IDHELP: if (FIsWin95) { WinHelpA(hwndDlg, (LPSTR) pcss->szHelpFileName, HELP_CONTEXT, pcss->dwHelpId); } #ifndef MAC else { WinHelp(hwndDlg, pcss->szHelpFileName, HELP_CONTEXT, pcss->dwHelpId); } #endif // !MAC return TRUE; case IDC_CS_PROPERTIES: i = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCURSEL, 0, 0); if (i == LB_ERR) { return TRUE; } pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); f = TRUE; if (FIsWin95) { CERT_VIEWPROPERTIES_STRUCT_A cvps; memset(&cvps, 0, sizeof(cvps)); cvps.dwSize = sizeof(cvps); cvps.hwndParent = hwndDlg; cvps.pCertContext = pcertctx; pcss = (PCERT_SELECT_STRUCT) GetWindowLongPtr(hwndDlg, DWLP_USER); if (pcss->szPurposeOid != NULL) { cvps.cArrayPurposes = 1; cvps.arrayPurposes = (LPSTR *) &pcss->szPurposeOid; } if (pcss->dwSize > (DWORD_PTR) &((PCERT_SELECT_STRUCT_A) 0)->hprov) { cvps.hprov = pcss->hprov; } f = CertViewPropertiesA(&cvps); } #ifndef WIN16 #ifndef MAC else { CERT_VIEWPROPERTIES_STRUCT_W cvps; memset(&cvps, 0, sizeof(cvps)); cvps.dwSize = sizeof(cvps); cvps.hwndParent = hwndDlg; cvps.pCertContext = pcertctx; pcss = (PCERT_SELECT_STRUCT) GetWindowLongPtr(hwndDlg, DWLP_USER); if (pcss->szPurposeOid != NULL) { cvps.cArrayPurposes = 1; cvps.arrayPurposes = (LPSTR *) &pcss->szPurposeOid; } if (pcss->dwSize > (DWORD_PTR) &((PCERT_SELECT_STRUCT_W) 0)->hprov) { cvps.hprov = pcss->hprov; } f = CertViewPropertiesW(&cvps); } #endif // !MAC #endif // !WIN16 if (f) { // M00BUG -- repopulate the line. The friendly name // may have changed. } return TRUE; case IDC_CS_FINEPRINT: i = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCURSEL, 0, 0); if (i == LB_ERR) { return TRUE; } pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); FinePrint(pcertctx, hwndDlg); return TRUE; case IDC_CS_CERTLIST: if (HIWORD(wParam) == LBN_SELCHANGE) { i = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCARETINDEX, 0, 0); pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); FillInFields(hwndDlg, pcertctx); if (!(pcss->dwFlags & CSS_HIDE_PROPERTIES)) { EnableWindow(GetDlgItem(hwndDlg, IDC_CS_PROPERTIES), TRUE); } EnableWindow(GetDlgItem(hwndDlg, IDC_CS_FINEPRINT), TRUE); EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE); } return TRUE; } break; #ifndef MAC case WM_HELP: case WM_CONTEXTMENU: return OnContextHelp(hwndDlg, msg, wParam, lParam, RgctxSelect); #endif // !MAC case WM_DESTROY: c = (int) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETCOUNT, 0, 0); for (i=0; iszPurposeOid != NULL) { pExt = CertFindExtension(szOID_ENHANCED_KEY_USAGE, pccert->pCertInfo->cExtension, pccert->pCertInfo->rgExtension); if (pExt != NULL) { BOOL f; DWORD i; PCERT_ENHKEY_USAGE pUsage; pUsage = (PCERT_ENHKEY_USAGE) PVCryptDecode(szOID_ENHANCED_KEY_USAGE, pExt->Value.cbData, pExt->Value.pbData); if (pUsage == NULL) { return FALSE; } for (i=0, f=FALSE; icUsageIdentifier; i++) { if (strcmp(pcssW->szPurposeOid, pUsage->rgpszUsageIdentifier[i]) == 0) { break; } } if (i == pUsage->cUsageIdentifier) { free(pUsage); return FALSE; } free(pUsage); } } // Let them filter if they want if (pcssW->pfnFilter != NULL) { if (!pcssW->pfnFilter(pccert, pcssW->lCustData, 0, 0)) { return FALSE; } } else if (pccert->pCertInfo->dwVersion < 2) { return FALSE; } if ((pfSelect != NULL) && (pcssW->arrayCertContext[0] != NULL)) { *pfSelect = CertCompareCertificate(X509_ASN_ENCODING, pccert->pCertInfo, pcssW->arrayCertContext[0]->pCertInfo); } return TRUE; } BOOL WINAPI MyDisplay(PCCERT_CONTEXT pccert, HWND hwnd, void * pv) { CERT_VIEWPROPERTIES_STRUCT_A cvps = {0}; PCERT_SELECT_STRUCT_W pcss = (PCERT_SELECT_STRUCT_W) pv; cvps.dwSize = sizeof(cvps); cvps.hwndParent = hwnd; cvps.pCertContext = pccert; if (pcss->szPurposeOid != NULL) { cvps.cArrayPurposes = 1; cvps.arrayPurposes = (LPSTR *) &pcss->szPurposeOid; } if (pcss->dwSize > (DWORD_PTR) &((PCERT_SELECT_STRUCT_A) 0)->hprov) { cvps.hprov = pcss->hprov; } CertViewPropertiesA(&cvps); return TRUE; } BOOL CallCryptUISelect(BOOL fWide, PCERT_SELECT_STRUCT_W pcssW) { CRYPTUI_SELECTCERTIFICATE_STRUCTW cscs = {0}; PCCERT_CONTEXT pccert; cscs.dwSize = sizeof(cscs); cscs.hwndParent = pcssW->hwndParent; // cscs.dwFlags = 0; cscs.szTitle = pcssW->szTitle; if (pcssW->szPurposeOid != NULL) { cscs.dwDontUseColumn = /*CRYPTUI_SELECT_INTENDEDUSE_COLUMN |*/ CRYPTUI_SELECT_LOCATION_COLUMN; } else { cscs.dwDontUseColumn = CRYPTUI_SELECT_LOCATION_COLUMN; } // cscs.szDisplayString = NULL; cscs.pFilterCallback = MyCryptFilter; cscs.pDisplayCallback = MyDisplay; cscs.pvCallbackData = pcssW; cscs.cDisplayStores = pcssW->cCertStore; cscs.rghDisplayStores = pcssW->arrayCertStore; // cscs.cStores = 0; // cscs.rghStores = NULL; // cscs.cPropSheetPages = 0; // cscs.rgPropSheetPages = NULL; if (fWide) { pccert = CryptUIDlgSelectCertificateW(&cscs); } else { pccert = CryptUIDlgSelectCertificateA((PCRYPTUI_SELECTCERTIFICATE_STRUCTA) &cscs); } if (pccert != NULL) { if (pcssW->cCertContext == 1) { CertFreeCertificateContext(pcssW->arrayCertContext[0]); } pcssW->cCertContext = 1; pcssW->arrayCertContext[0] = pccert; return TRUE; } return FALSE; } extern "C" BOOL APIENTRY CertSelectCertificateA(PCERT_SELECT_STRUCT_A pcssA) { if (CryptUIAvailable()) { return CallCryptUISelect(FALSE, (PCERT_SELECT_STRUCT_W) pcssA); } HCERTSTORE hCertStore = NULL; int ret = FALSE; CERT_SELECT_STRUCT_W cssW = {0}; #ifndef MAC int cch; INITCOMMONCONTROLSEX initcomm = { sizeof(initcomm), ICC_LISTVIEW_CLASSES #ifndef WIN16 | ICC_NATIVEFNTCTL_CLASS #endif // ! WIN16 }; #endif // ! MAC if (pcssA->cCertStore == 0) { hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (hCertStore == NULL) { ret = -1; goto Exit; } pcssA->cCertStore = 1; pcssA->arrayCertStore = &hCertStore; } // // Size of the object must be acceptable in order to copy it over // if (pcssA->dwSize > sizeof(cssW)) { SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } if (FIsWin95) { // // Deal with some DBCS issues // #ifndef MAC InitCommonControlsEx(&initcomm); #endif // !MAC // // Launch the dialog // if (pcssA->dwFlags & CSS_ENABLETEMPLATEHANDLE) { ret = (int) DialogBoxIndirectParamA(pcssA->hInstance, (LPCDLGTEMPLATE_X) pcssA->pTemplateName, pcssA->hwndParent, SelectCertDlgProc, (LPARAM) pcssA); } else if (pcssA->dwFlags & CSS_ENABLETEMPLATE) { ret = (int) DialogBoxParamA(pcssA->hInstance, pcssA->pTemplateName, pcssA->hwndParent, SelectCertDlgProc, (LPARAM) pcssA); } else { ret = (int) DialogBoxParamA(HinstDll, (LPSTR) MAKEINTRESOURCE(IDD_SELECT_DIALOG), pcssA->hwndParent, SelectCertDlgProc, (LPARAM) pcssA); } } #if ! defined(WIN16) && ! defined (MAC) else { // // Do a bulk copy of the passed in structure then we fix up the // individual fields to go from the A to the W version of the structure // memcpy(&cssW, pcssA, pcssA->dwSize); if (pcssA->szTitle != NULL) { cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->szTitle, -1, NULL, 0); cssW.szTitle = (LPWSTR) malloc((cch+1)*sizeof(WCHAR)); if (cssW.szTitle == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto ExitW; } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->szTitle, -1, (LPWSTR) cssW.szTitle, cch+1); } if (pcssA->szHelpFileName != NULL) { cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->szHelpFileName, -1, NULL, 0); cssW.szHelpFileName = (LPWSTR) malloc((cch+1)*sizeof(WCHAR)); if (cssW.szHelpFileName == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto ExitW; } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->szHelpFileName, -1, (LPWSTR) cssW.szHelpFileName, cch+1); } if (pcssA->dwFlags & CSS_ENABLETEMPLATE) { cch = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->pTemplateName, -1, NULL, 0); cssW.pTemplateName = (LPWSTR) malloc((cch+1)*sizeof(WCHAR)); if (cssW.pTemplateName == NULL) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); goto ExitW; } MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcssA->pTemplateName, -1, (LPWSTR) cssW.pTemplateName, cch+1); } // // Call Wide char version of the function now // ret = CertSelectCertificateW(&cssW); pcssA->cCertContext = cssW.cCertContext; // // If we allocated buffers to hold data, free them now // ExitW: if (cssW.szTitle != NULL) free((LPWSTR) cssW.szTitle); if (cssW.szHelpFileName != NULL) free((LPWSTR) cssW.szHelpFileName); if (pcssA->dwFlags & CSS_ENABLETEMPLATE) { free((LPWSTR) cssW.pTemplateName); } // // return the return value of the original function // } #endif // !WIN16 and !MAC Exit: if (hCertStore != NULL) { CertCloseStore(hCertStore, 0); pcssA->cCertStore = 0; pcssA->arrayCertStore = NULL; } return (ret == IDOK); } #ifndef WIN16 #ifndef MAC BOOL APIENTRY CertSelectCertificateW(PCERT_SELECT_STRUCT_W pcssW) { if (CryptUIAvailable()) { return CallCryptUISelect(TRUE, pcssW); } HCERTSTORE hCertStore = NULL; int ret = FALSE; #ifndef MAC INITCOMMONCONTROLSEX initcomm = { sizeof(initcomm), ICC_NATIVEFNTCTL_CLASS | ICC_LISTVIEW_CLASSES }; #endif // !MAC // // If cCertStore == 0, then default to using the "MY" cert store // if (pcssW->cCertStore == 0) { hCertStore = CertOpenStore(CERT_STORE_PROV_SYSTEM, X509_ASN_ENCODING, NULL, CERT_SYSTEM_STORE_CURRENT_USER, L"MY"); if (hCertStore == NULL) { ret = -1; goto Exit; } pcssW->cCertStore = 1; pcssW->arrayCertStore = &hCertStore; } // // Deal with some DBCS issues // InitCommonControlsEx(&initcomm); // // Launch the dialog // if (pcssW->dwFlags & CSS_ENABLETEMPLATEHANDLE) { ret = (int) DialogBoxIndirectParam(pcssW->hInstance, (LPCDLGTEMPLATE_X) pcssW->pTemplateName, pcssW->hwndParent, SelectCertDlgProc, (LPARAM) pcssW); } else if (pcssW->dwFlags & CSS_ENABLETEMPLATE) { ret = (int) DialogBoxParam(pcssW->hInstance, pcssW->pTemplateName, pcssW->hwndParent, SelectCertDlgProc, (LPARAM) pcssW); } else { ret = (int) DialogBoxParam(HinstDll, MAKEINTRESOURCE(IDD_SELECT_DIALOG), pcssW->hwndParent, SelectCertDlgProc, (LPARAM) pcssW); } Exit: if (hCertStore != NULL) { CertCloseStore(hCertStore, 0); pcssW->cCertStore = 0; pcssW->arrayCertStore = NULL; } return (ret == IDOK); } #endif // !MAC #endif // !WIN16