|
|
//
// 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 <wchar.h>
#ifdef MAC
#include <stdio.h>
#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<c; i++) { cb = (ULONG) SendDlgItemMessage(hwnd, id, LB_GETTEXTLEN, i, 0); if (cb > 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<c; i++) { cb = SendDlgItemMessage(hwnd, id, LB_GETTEXTLEN, i, 0); if (cb > 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);
if (NULL != pwsz) { 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; i<c; i++) { pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); if (CertCompareCertificate(X509_ASN_ENCODING, pcss->arrayCertContext[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; i<c; i++) { pcertctx = (PCERT_CONTEXT) SendDlgItemMessage(hwndDlg, IDC_CS_CERTLIST, LB_GETITEMDATA, i, 0); CertFreeCertificateContext(pcertctx); } return FALSE;
//
// Use the default handler -- we don't do anything for it
//
default: return FALSE; }
return TRUE; } // SelectCertDialogProc()
BOOL WINAPI MyCryptFilter(PCCERT_CONTEXT pccert, BOOL * pfSelect, void * pv) { PCERT_SELECT_STRUCT_W pcssW = (PCERT_SELECT_STRUCT_W) pv; PCERT_EXTENSION pExt;
// Test purpose
if (pcssW->szPurposeOid != 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; i<pUsage->cUsageIdentifier; 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
//
//Assert(pcssA->dwSize <= sizeof(cssW));
memcpy(&cssW, pcssA, (int)min(pcssA->dwSize, sizeof(cssW)));
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
|