Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1018 lines
31 KiB

//
// 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