windows-nt/Source/XPSP1/NT/ds/security/cryptoapi/ui/cryptui/linkutil.cpp
2020-09-26 16:20:57 +08:00

338 lines
10 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: linkutil.cpp
//
//--------------------------------------------------------------------------
#include "global.hxx"
#include <dbgdef.h>
extern HINSTANCE HinstDll;
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
void CryptuiGoLink(HWND hwndParent, char *pszWhere, BOOL fNoCOM)
{
HCURSOR hcursPrev = NULL;
HMODULE hURLMon = NULL;
BOOL fCallCoUnInit = FALSE;
//
// since we're a model dialog box, we want to go behind IE once it comes up!!!
//
SetWindowPos(hwndParent, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE);
hcursPrev = SetCursor(LoadCursor(NULL, IDC_WAIT));
__try
{
hURLMon = (HMODULE)LoadLibraryU(L"urlmon.dll");
if (!(hURLMon) || fNoCOM)
{
//
// The hyperlink module is unavailable, go to fallback plan
//
//
// This works in test cases, but causes deadlock problems when used from withing
// the Internet Explorer itself. The dialog box is up (that is, IE is in a modal
// dialog loop) and in comes this DDE request...).
//
ShellExecute(hwndParent, "open", pszWhere, NULL, NULL, SW_SHOWNORMAL);
}
else
{
//
// The hyperlink module is there. Use it
//
if (SUCCEEDED(CoInitialize(NULL))) // Init OLE if no one else has
{
fCallCoUnInit = TRUE;
//
// allow com to fully init...
//
MSG msg;
PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); // peek but not remove
typedef void (WINAPI *pfnHlinkSimpleNavigateToString)(LPCWSTR, LPCWSTR, LPCWSTR, IUnknown *,
IBindCtx *, IBindStatusCallback *,
DWORD, DWORD);
pfnHlinkSimpleNavigateToString pProcAddr;
pProcAddr = (pfnHlinkSimpleNavigateToString)GetProcAddress(hURLMon, TEXT("HlinkSimpleNavigateToString"));
if (pProcAddr)
{
WCHAR *pwszWhere;
IBindCtx *pbc;
pwszWhere = new WCHAR[strlen(pszWhere) + 1];
if (pwszWhere == NULL)
{
return;
}
MultiByteToWideChar(0, 0, (const char *)pszWhere, -1, pwszWhere, strlen(pszWhere) + 1);
pbc = NULL;
CreateBindCtx( 0, &pbc );
(*pProcAddr)(pwszWhere, NULL, NULL, NULL, pbc, NULL, HLNF_OPENINNEWWINDOW, NULL);
if (pbc)
{
pbc->Release();
}
delete [] pwszWhere;
}
CoUninitialize();
}
FreeLibrary(hURLMon);
}
SetCursor(hcursPrev);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if (hURLMon != NULL)
{
FreeLibrary(hURLMon);
}
if (fCallCoUnInit)
{
CoUninitialize();
}
if (hcursPrev != NULL)
{
SetCursor(hcursPrev);
}
}
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL AllocAndGetIssuerURL(LPSTR *ppURLString, PCCERT_CONTEXT pCertContext)
{
PCERT_EXTENSION pExt = NULL;
PSPC_SP_AGENCY_INFO pInfo = NULL;
DWORD cbInfo = 0;
PCERT_ALT_NAME_ENTRY pAltName = NULL;
DWORD cbAltName = 0;
*ppURLString = NULL;
//
// first look for the Agency Info extension and see if it has an URL
//
if ((pExt = CertFindExtension(SPC_SP_AGENCY_INFO_OBJID, pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension)))
{
CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
pExt->Value.pbData, pExt->Value.cbData, 0, NULL,
&cbInfo);
if (!(pInfo = (PSPC_SP_AGENCY_INFO) malloc(cbInfo)))
{
return FALSE;
}
if (!(CryptDecodeObject(X509_ASN_ENCODING, SPC_SP_AGENCY_INFO_STRUCT,
pExt->Value.pbData, pExt->Value.cbData, 0, pInfo,
&cbInfo)))
{
free(pInfo);
return FALSE;
}
if (!(pInfo->pPolicyInformation))
{
free(pInfo);
return FALSE;
}
switch (pInfo->pPolicyInformation->dwLinkChoice)
{
case SPC_URL_LINK_CHOICE:
if (NULL != (*ppURLString =
(LPSTR) malloc(wcslen(pInfo->pPolicyInformation->pwszUrl)+1)))
{
WideCharToMultiByte(
0,
0,
pInfo->pPolicyInformation->pwszUrl,
-1,
*ppURLString,
wcslen(pInfo->pPolicyInformation->pwszUrl)+1,
NULL,
NULL);
free(pInfo);
return TRUE;
}
else
{
free(pInfo);
return FALSE;
}
break;
case SPC_FILE_LINK_CHOICE:
if (NULL != (*ppURLString =
(LPSTR) malloc(wcslen(pInfo->pPolicyInformation->pwszFile)+1)))
{
WideCharToMultiByte(
0,
0,
pInfo->pPolicyInformation->pwszFile,
-1,
*ppURLString,
wcslen(pInfo->pPolicyInformation->pwszFile)+1,
NULL,
NULL);
return TRUE;
}
else
{
free(pInfo);
return FALSE;
}
break;
}
free(pInfo);
}
//
// if there was no Agency Info extension or it didn't contain an URL,
// look for the Authority Info Access Syntax extension
//
/*if ((pExt = CertFindExtension(SPC_SP_AGENCY_INFO_OBJID, pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension)))
{
FIX FIX
}*/
//
// finally, if there was no Agency Info and no Authority Info Access Syntax
// check to see if there is an Alternate Name extension
//
if ((pExt = CertFindExtension(szOID_ISSUER_ALT_NAME, pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension)))
{
CryptDecodeObject(X509_ASN_ENCODING, szOID_ISSUER_ALT_NAME,
pExt->Value.pbData, pExt->Value.cbData, 0, NULL,
&cbAltName);
if (!(pAltName = (PCERT_ALT_NAME_ENTRY) malloc(cbAltName)))
{
return FALSE;
}
if (!(CryptDecodeObject(X509_ASN_ENCODING, szOID_ISSUER_ALT_NAME,
pExt->Value.pbData, pExt->Value.cbData, 0, pAltName,
&cbAltName)))
{
free(pAltName);
return FALSE;
}
if (pAltName->dwAltNameChoice == CERT_ALT_NAME_URL)
{
if (NULL != (*ppURLString = (LPSTR) malloc(wcslen(pAltName->pwszURL)+1)))
{
WideCharToMultiByte(
0,
0,
pAltName->pwszURL,
-1,
*ppURLString,
wcslen(pAltName->pwszURL)+1,
NULL,
NULL);
free(pAltName);
return TRUE;
}
}
free(pAltName);
}
return FALSE;
}
//////////////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////////////
BOOL AllocAndGetSubjectURL(LPSTR *ppURLString, PCCERT_CONTEXT pCertContext)
{
PCERT_EXTENSION pExt = NULL;
PCERT_ALT_NAME_ENTRY pAltName = NULL;
DWORD cbAltName = 0;
*ppURLString = NULL;
//
// check to see if there is an Alternate Name extension
//
if ((pExt = CertFindExtension(szOID_SUBJECT_ALT_NAME, pCertContext->pCertInfo->cExtension,
pCertContext->pCertInfo->rgExtension)))
{
CryptDecodeObject(X509_ASN_ENCODING, szOID_SUBJECT_ALT_NAME,
pExt->Value.pbData, pExt->Value.cbData, 0, NULL,
&cbAltName);
if (!(pAltName = (PCERT_ALT_NAME_ENTRY) malloc(cbAltName)))
{
return FALSE;
}
if (!(CryptDecodeObject(X509_ASN_ENCODING, szOID_SUBJECT_ALT_NAME,
pExt->Value.pbData, pExt->Value.cbData, 0, pAltName,
&cbAltName)))
{
free(pAltName);
return FALSE;
}
if (pAltName->dwAltNameChoice == CERT_ALT_NAME_URL)
{
if (NULL != (*ppURLString = (LPSTR) malloc(wcslen(pAltName->pwszURL)+1)))
{
WideCharToMultiByte(
0,
0,
pAltName->pwszURL,
-1,
*ppURLString,
wcslen(pAltName->pwszURL)+1,
NULL,
NULL);
free(pAltName);
return TRUE;
}
}
free(pAltName);
}
return FALSE;
}