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.
 
 
 
 
 
 

1213 lines
31 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows NT Security
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: iih.cpp
//
// Contents: ACUI Invoke Info Helper class implementation
//
// History: 10-May-97 kirtd Created
//
//----------------------------------------------------------------------------
#include <stdpch.h>
#include "malloc.h"
#include "sgnerror.h"
//
// Personal trust database interface id
//
extern "C" const GUID IID_IPersonalTrustDB = IID_IPersonalTrustDB_Data;
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::CInvokeInfoHelper, public
//
// Synopsis: Constructor, initializes member variables from data found
// in the invoke info data structure
//
// Arguments: [pInvokeInfo] -- invoke info
// [rhr] -- result of construction
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CInvokeInfoHelper::CInvokeInfoHelper (
PACUI_INVOKE_INFO pInvokeInfo,
HRESULT& rhr
)
: m_pInvokeInfo ( pInvokeInfo ),
m_pszSubject ( NULL ),
m_pszPublisher ( NULL ),
m_pszAdvancedLink ( NULL ),
m_pszControlWebPage ( NULL ),
m_pszCAWebPage ( NULL ),
m_pszPublisherCertIssuer ( NULL ),
m_pszErrorStatement ( NULL ),
m_pszCertTimestamp ( NULL ),
m_pszTestCertInChain ( NULL ),
m_fKnownPublisher ( FALSE ),
m_hModCVPA ( NULL ),
m_pfnCVPA ( NULL )
{
//
// Initialize the subject
//
rhr = InitSubject();
//
// if there's a test cert, format the text!
//
InitTestCertInChain();
//
// If we actually have a signature then ...
//
//
// If we need an error statement, initialize it
//
if ( ( rhr == S_OK ) && ( pInvokeInfo->hrInvokeReason != S_OK ) )
{
rhr = InitErrorStatement();
}
if ( ( rhr == S_OK ) &&
( pInvokeInfo->hrInvokeReason != TRUST_E_NOSIGNATURE ) )
{
//
// Initialize the publisher
//
rhr = InitPublisher();
//
// If we have a known publisher, then we initialize the publisher
// cert issuer
//
if ( ( rhr == S_OK ) && ( m_fKnownPublisher == TRUE ) )
{
rhr = InitPublisherCertIssuer();
}
//
// Initialize the timestamp string
//
if ( rhr == S_OK )
{
rhr = InitCertTimestamp();
}
//
// initialize the "advanced link" text
//
InitAdvancedLink();
//
// initialize the Control's Web page link
//
InitControlWebPage();
//
// initialize the CA's Web page link
//
InitCAWebPage();
}
//
// Initialize the CertViewProperties entry point
//
if ( rhr == S_OK )
{
InitCertViewPropertiesEntryPoint();
}
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::~CInvokeInfoHelper, public
//
// Synopsis: Destructor, frees up member variables
//
// Arguments: (none)
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
CInvokeInfoHelper::~CInvokeInfoHelper ()
{
DELETE_OBJECT(m_pszSubject);
DELETE_OBJECT(m_pszPublisher);
DELETE_OBJECT(m_pszPublisherCertIssuer);
DELETE_OBJECT(m_pszAdvancedLink);
DELETE_OBJECT(m_pszControlWebPage);
DELETE_OBJECT(m_pszCAWebPage);
DELETE_OBJECT(m_pszTestCertInChain);
DELETE_OBJECT(m_pszCertTimestamp);
DELETE_OBJECT(m_pszErrorStatement);
if ( m_hModCVPA != NULL )
{
FreeLibrary(m_hModCVPA);
}
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::AddPublisherToPersonalTrust, public
//
// Synopsis: adds the current publisher to the personal trust database
//
// Arguments: (none)
//
// Returns: hr == S_OK, publisher added to personal trust database
// hr != S_OK, publisher NOT added to personal trust database
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::AddPublisherToPersonalTrust ()
{
HRESULT hr = S_OK;
IPersonalTrustDB* pTrustDB = NULL;
//
// Get the personal trust database interface
//
hr = m_pInvokeInfo->pPersonalTrustDB->QueryInterface(
IID_IPersonalTrustDB,
(LPVOID *)&pTrustDB
);
//
// Add the publisher cert to the database
//
if ( hr == S_OK )
{
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
{
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
{
hr = pTrustDB->AddTrustCert(
pCert->pCert,
0,
FALSE
);
}
}
pTrustDB->Release();
}
return( hr );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::GetUIControl, public
//
// Synopsis: gets the UI control
//
// Arguments: [ppUI] -- UI returned here
//
// Returns: S_OK for success, any other valid HRESULT otherwise
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::GetUIControl (IACUIControl** ppUI)
{
HRESULT hr = S_OK;
IACUIControl* pUI = NULL;
//
// Get the right UI control
//
switch (m_pInvokeInfo->hrInvokeReason)
{
case S_OK:
pUI = new CVerifiedTrustUI(*this, hr);
break;
case CERT_E_EXPIRED:
case CERT_E_PURPOSE:
case CERT_E_WRONG_USAGE:
case CERT_E_CN_NO_MATCH:
case CERT_E_INVALID_NAME:
case CERT_E_INVALID_POLICY:
case CERT_E_REVOCATION_FAILURE:
case CRYPT_E_NO_REVOCATION_CHECK:
case CRYPT_E_REVOCATION_OFFLINE:
pUI = new CUnverifiedTrustUI(*this, hr);
break;
#if (0)
case CRYPT_E_FILE_ERROR:
case TRUST_E_PROVIDER_UNKNOWN:
case TRUST_E_SUBJECT_FORM_UNKNOWN:
case TRUST_E_NOSIGNATURE:
case CERT_E_CHAINING:
case CERT_E_UNTRUSTEDROOT:
case CERT_E_UNTRUSTEDTESTROOT:
#endif
default:
pUI = new CNoSignatureUI(*this, hr);
break;
}
//
// Set the out parameter and return value
//
if ( ( pUI != NULL ) && ( hr == S_OK ) )
{
*ppUI = pUI;
}
else if ( pUI == NULL )
{
hr = E_OUTOFMEMORY;
}
else
{
delete pUI;
}
return( hr );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::ReleaseUIControl, public
//
// Synopsis: frees the UI control
//
// Arguments: [pUI] -- UI control
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID
CInvokeInfoHelper::ReleaseUIControl (IACUIControl* pUI)
{
delete pUI;
}
VOID CInvokeInfoHelper::InitControlWebPage ()
{
WCHAR *pwsz;
if (!(m_pInvokeInfo->pOpusInfo))
{
return;
}
if (!(m_pInvokeInfo->pOpusInfo->pMoreInfo))
{
return;
}
pwsz = GetGoLink(m_pInvokeInfo->pOpusInfo->pMoreInfo);
if (!(pwsz))
{
return;
}
m_pszControlWebPage = new WCHAR[wcslen(pwsz) + 1];
if (m_pszControlWebPage != NULL)
{
wcscpy(m_pszControlWebPage, pwsz);
}
}
VOID CInvokeInfoHelper::InitCAWebPage ()
{
//
// until IE submits.... don't do it!
//
return;
WCHAR *pwsz;
DWORD cb;
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
SPC_SP_AGENCY_INFO *pAgencyInfo;
if (!(pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0)))
{
return;
}
if (!(pCert = WTHelperGetProvCertFromChain(pSgnr, 0))) // try the publisher's cert first!
{
return;
}
cb = 0;
WTHelperGetAgencyInfo(pCert->pCert, &cb, NULL);
if (cb < 1)
{
if (!(pCert = WTHelperGetProvCertFromChain(pSgnr, 1))) // try the issuer's next
{
return;
}
cb = 0;
WTHelperGetAgencyInfo(pCert->pCert, &cb, NULL);
if (cb < 1)
{
return;
}
}
if (!(pAgencyInfo = (SPC_SP_AGENCY_INFO *)new BYTE[cb]))
{
return;
}
if (!(WTHelperGetAgencyInfo(pCert->pCert, &cb, pAgencyInfo)))
{
delete pAgencyInfo;
return;
}
pwsz = GetGoLink(pAgencyInfo->pPolicyInformation);
m_pszCAWebPage = new WCHAR[wcslen(pwsz) + 1];
if (m_pszCAWebPage != NULL)
{
wcscpy(m_pszCAWebPage, pwsz);
}
delete pAgencyInfo;
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitSubject, private
//
// Synopsis: Initialize m_pszSubject
//
// Arguments: (none)
//
// Returns: hr == S_OK, initialize succeeded
// hr != S_OK, initialize failed
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::InitSubject ()
{
HRESULT hr = S_OK;
LPCWSTR pwszSubject = NULL;
//
// Find out what we will use as the subject name
//
if ( ( m_pInvokeInfo->pOpusInfo != NULL ) &&
( m_pInvokeInfo->pOpusInfo->pwszProgramName != NULL ) )
{
pwszSubject = m_pInvokeInfo->pOpusInfo->pwszProgramName;
}
else
{
pwszSubject = m_pInvokeInfo->pwcsAltDisplayName;
}
//
// At this point we must have a valid subject name
//
assert( pwszSubject != NULL );
//
// Fill in the subject member by converting the one we found from
// UNICODE to MBS
//
m_pszSubject = new WCHAR[wcslen(pwszSubject) + 1];
if ( m_pszSubject != NULL )
{
wcscpy(m_pszSubject, pwszSubject);
}
else
{
hr = E_OUTOFMEMORY;
}
return( hr );
}
VOID
CInvokeInfoHelper::InitTestCertInChain ()
{
WCHAR szTestCertInChain[MAX_LOADSTRING_BUFFER + 1];
if (IsTestCertInPublisherChain())
{
if ( LoadStringU(
g_hModule,
IDS_TESTCERTINCHAIN,
szTestCertInChain,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return;
}
m_pszTestCertInChain = new WCHAR[wcslen(szTestCertInChain) + 1];
if (m_pszTestCertInChain != NULL)
{
wcscpy(m_pszTestCertInChain, szTestCertInChain);
}
}
}
VOID
CInvokeInfoHelper::InitAdvancedLink ()
{
ULONG cbAL;
if ((ProviderData()) &&
(WVT_IS_CBSTRUCT_GT_MEMBEROFFSET(CRYPT_PROVIDER_FUNCTIONS, ProviderData()->psPfns->cbStruct, psUIpfns)) &&
(ProviderData()->psPfns->psUIpfns) &&
(ProviderData()->psPfns->psUIpfns->psUIData) &&
(ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText))
{
m_pszAdvancedLink = new WCHAR[wcslen(ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText) + 1];
if (m_pszAdvancedLink != NULL)
{
wcscpy(m_pszAdvancedLink, ProviderData()->psPfns->psUIpfns->psUIData->pAdvancedLinkText);
}
}
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitPublisher, private
//
// Synopsis: Initialize m_pszPublisher
//
// Arguments: (none)
//
// Returns: hr == S_OK, initialize succeeded
// hr != S_OK, initialize failed
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::InitPublisher ()
{
HRESULT hr = S_OK;
ULONG cchPublisher;
LPWSTR pwszPublisher = NULL;
WCHAR szPublisher[MAX_LOADSTRING_BUFFER];
//
// Load the unknown publisher string
//
if ( LoadStringU(
g_hModule,
IDS_UNKNOWNPUBLISHER,
szPublisher,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
//
// Since the publisher is the subject of the signer certificate, we try to
// find the publisher name in the common name extensions of that cert
//
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
{
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
{
cchPublisher = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, NULL, 0);
if (cchPublisher > 1)
{
pwszPublisher = new WCHAR[cchPublisher];
if ( pwszPublisher == NULL )
{
return (E_OUTOFMEMORY);
}
cchPublisher = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL,
pwszPublisher, cchPublisher);
}
}
}
//
// If we still don't have a publisher, use the unknown publisher string
//
if ( pwszPublisher == NULL )
{
m_fKnownPublisher = FALSE;
cchPublisher = wcslen(szPublisher) + 1;
}
else
{
m_fKnownPublisher = TRUE;
cchPublisher = wcslen(pwszPublisher) + 1;
}
//
// Fill in the publisher member by converting from UNICODE to MBS
// or by copying the unknown publisher string
//
m_pszPublisher = new WCHAR[cchPublisher];
if ( m_pszPublisher != NULL )
{
if ( m_fKnownPublisher == FALSE )
{
wcscpy(m_pszPublisher, szPublisher);
}
else
{
wcscpy(m_pszPublisher, pwszPublisher);
}
}
else
{
hr = E_OUTOFMEMORY;
}
if ( pwszPublisher != NULL )
{
delete[] pwszPublisher;
}
return( hr );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitPublisherCertIssuer, private
//
// Synopsis: Initialize m_pszPublisherCertIssuer
//
// Arguments: (none)
//
// Returns: hr == S_OK, initialize succeeded
// hr != S_OK, initialize failed
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::InitPublisherCertIssuer ()
{
HRESULT hr = S_OK;
ULONG cchCertIssuer;
LPWSTR pwszCertIssuer = NULL;
WCHAR szCertIssuer[MAX_LOADSTRING_BUFFER];
BOOL fKnownCertIssuer;
//
// Load the unknown cert issuer string
//
if ( LoadStringU(
g_hModule,
IDS_UNKNOWNPUBLISHERCERTISSUER,
szCertIssuer,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
//
// Since the publisher cert issuer is the issuer of the signer certificate,
// we try to find the name in the RDN attributes of the cert issuer
//
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
{
if (pCert = WTHelperGetProvCertFromChain(pSgnr, 0))
{
cchCertIssuer = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL,
NULL, 0);
if (cchCertIssuer > 1)
{
pwszCertIssuer = new WCHAR[cchCertIssuer];
if ( pwszCertIssuer == NULL)
{
return (E_OUTOFMEMORY);
}
cchCertIssuer = CertGetNameStringW(pCert->pCert, CERT_NAME_SIMPLE_DISPLAY_TYPE, CERT_NAME_ISSUER_FLAG, NULL,
pwszCertIssuer, cchCertIssuer);
}
}
}
//
// If we still don't have a name, we set the unknown issuer string
//
if ( pwszCertIssuer == NULL )
{
fKnownCertIssuer = FALSE;
cchCertIssuer = wcslen(szCertIssuer) + 1;
}
else
{
fKnownCertIssuer = TRUE;
cchCertIssuer = wcslen(pwszCertIssuer) + 1;
}
//
// Fill in the publisher cert issuer member by converting from UNICODE
// to MBS or by copying the unknown issuer string
//
m_pszPublisherCertIssuer = new WCHAR[cchCertIssuer];
if ( m_pszPublisherCertIssuer != NULL )
{
if ( fKnownCertIssuer == FALSE )
{
wcscpy(m_pszPublisherCertIssuer, szCertIssuer);
}
else
{
wcscpy(m_pszPublisherCertIssuer, pwszCertIssuer);
}
}
else
{
hr = E_OUTOFMEMORY;
}
if ( pwszCertIssuer != NULL )
{
delete[] pwszCertIssuer;
}
return( hr );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitErrorStatement, private
//
// Synopsis: Initialize m_pszErrorStatement
//
// Arguments: (none)
//
// Returns: hr == S_OK, initialize succeeded
// hr != S_OK, initialize failed
//
// Notes:
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::InitErrorStatement ()
{
return( ACUIMapErrorToString(
m_pInvokeInfo->hrInvokeReason,
&m_pszErrorStatement
) );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitCertTimestamp, public
//
// Synopsis: initialize the certificate timestamp string
//
//----------------------------------------------------------------------------
HRESULT
CInvokeInfoHelper::InitCertTimestamp ()
{
HRESULT hr = S_OK;
WCHAR szCertTimestamp[MAX_LOADSTRING_BUFFER];
FILETIME ftTimestamp;
SYSTEMTIME stTimestamp;
//
// Get the time stamp
//
// TBDTBD: change to a loop!!!! pberkman
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_SGNR *pTimeSgnr;
if ((pTimeSgnr =
WTHelperGetProvSignerFromChain(ProviderData(), 0, TRUE, 0)) &&
(pTimeSgnr->dwSignerType & SGNR_TYPE_TIMESTAMP) &&
(pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0)))
{
// convert UTC to local
FileTimeToLocalFileTime(&pSgnr->sftVerifyAsOf, &ftTimestamp);
// make it system format
FileTimeToSystemTime(&ftTimestamp, &stTimestamp);
m_pszCertTimestamp = GetFormattedCertTimestamp(&stTimestamp);
if ( m_pszCertTimestamp == NULL )
{
hr = E_OUTOFMEMORY;
}
}
else
{
m_pszCertTimestamp = NULL;
}
return( hr );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::InitCertViewPropertiesEntryPoint, public
//
// Synopsis: initialize the cert view properties entry point
//
// Arguments: (none)
//
// Returns: (none)
//
// Notes:
//
//----------------------------------------------------------------------------
VOID
CInvokeInfoHelper::InitCertViewPropertiesEntryPoint ()
{
m_hModCVPA = LoadLibraryA(CVP_DLL);
if ( m_hModCVPA != NULL )
{
m_pfnCVPA = (pfnCertViewProperties)GetProcAddress(m_hModCVPA, CVP_FUNC_NAME);
}
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::GetFormattedCertTimestamp, public
//
// Synopsis: gets the formatted cert timestamp string which will be
// allocated using the new operator
//
//----------------------------------------------------------------------------
LPWSTR
CInvokeInfoHelper::GetFormattedCertTimestamp (LPSYSTEMTIME pst)
{
LPWSTR psz;
int cDate;
int cTime;
if ( ( cDate = GetDateFormatU(
LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
pst,
NULL,
NULL,
0
) ) == 0 )
{
return( NULL );
}
cDate--;
if ( ( cTime = GetTimeFormatU(
LOCALE_USER_DEFAULT,
TIME_NOSECONDS,
pst,
NULL,
NULL,
0
) ) == 0 )
{
return( NULL );
}
cTime--;
psz = new WCHAR [ cDate + cTime + 2 ];
if ( psz == NULL )
{
return( NULL );
}
if ( GetDateFormatU(
LOCALE_USER_DEFAULT,
DATE_SHORTDATE,
pst,
NULL,
psz,
cDate + 1
) == 0 )
{
delete[] psz;
return( NULL );
}
psz[cDate] = L' ';
if ( GetTimeFormatU(
LOCALE_USER_DEFAULT,
TIME_NOSECONDS,
pst,
NULL,
&psz[cDate+1],
cTime + 1
) == 0 )
{
delete[] psz;
return( NULL );
}
return( psz );
}
//+---------------------------------------------------------------------------
//
// Member: CInvokeInfoHelper::IsTestCertInChain, public
//
// Synopsis: is there a test cert in the publisher's chain
//
//----------------------------------------------------------------------------
BOOL
CInvokeInfoHelper::IsTestCertInPublisherChain ()
{
ULONG cCount;
CRYPT_PROVIDER_SGNR *pSgnr;
CRYPT_PROVIDER_CERT *pCert;
if (pSgnr = WTHelperGetProvSignerFromChain(ProviderData(), 0, FALSE, 0))
{
for (cCount = 0; cCount < pSgnr->csCertChain; cCount++)
{
if (pCert = WTHelperGetProvCertFromChain(pSgnr, cCount))
{
if (pCert->fTestCert)
{
return(TRUE);
}
}
}
}
return(FALSE);
}
//+---------------------------------------------------------------------------
//
// Function: ACUIMapErrorToString
//
// Synopsis: maps error to string
//
// Arguments: [hr] -- error
// [ppsz] -- error string goes here
//
// Returns: S_OK if successful, any valid HRESULT otherwise
//
//----------------------------------------------------------------------------
HRESULT ACUIMapErrorToString (HRESULT hr, LPWSTR* ppsz)
{
UINT ResourceId = 0;
WCHAR psz[MAX_LOADSTRING_BUFFER];
//
// See if it maps to some non system error code
//
switch (hr)
{
case TRUST_E_SYSTEM_ERROR:
case ERROR_NOT_ENOUGH_MEMORY:
case ERROR_INVALID_PARAMETER:
//
// leave the resourceid zero... these will be mapped to
// IDS_SPC_UNKNOWN and the error code displayed.
//
break;
case CRYPT_E_FILE_ERROR:
ResourceId = IDS_FILE_NOT_FOUND;
break;
case TRUST_E_PROVIDER_UNKNOWN:
ResourceId = IDS_SPC_PROVIDER;
break;
case TRUST_E_SUBJECT_FORM_UNKNOWN:
ResourceId = IDS_SPC_SUBJECT;
break;
case TRUST_E_NOSIGNATURE:
ResourceId = IDS_SPC_NO_SIGNATURE;
break;
case CRYPT_E_BAD_MSG:
ResourceId = IDS_SPC_BAD_SIGNATURE;
break;
case TRUST_E_BAD_DIGEST:
ResourceId = IDS_SPC_BAD_FILE_DIGEST;
break;
case CRYPT_E_NO_SIGNER:
ResourceId = IDS_SPC_NO_VALID_SIGNER;
break;
case TRUST_E_NO_SIGNER_CERT:
ResourceId = IDS_SPC_SIGNER_CERT;
break;
case TRUST_E_COUNTER_SIGNER:
ResourceId = IDS_SPC_VALID_COUNTERSIGNER;
break;
case CERT_E_EXPIRED:
ResourceId = IDS_SPC_CERT_EXPIRED;
break;
case TRUST_E_CERT_SIGNATURE:
ResourceId = IDS_SPC_CERT_SIGNATURE;
break;
case CERT_E_CHAINING:
ResourceId = IDS_SPC_CHAINING;
break;
case CERT_E_UNTRUSTEDROOT:
ResourceId = IDS_SPC_UNTRUSTED_ROOT;
break;
case CERT_E_UNTRUSTEDTESTROOT:
ResourceId = IDS_SPC_UNTRUSTED_TEST_ROOT;
break;
case CERT_E_VALIDITYPERIODNESTING:
ResourceId = IDS_SPC_INVALID_CERT_NESTING;
break;
case CERT_E_PURPOSE:
ResourceId = IDS_SPC_INVALID_PURPOSE;
break;
case TRUST_E_BASIC_CONSTRAINTS:
ResourceId = IDS_SPC_INVALID_BASIC_CONSTRAINTS;
break;
case TRUST_E_FINANCIAL_CRITERIA:
ResourceId = IDS_SPC_INVALID_FINANCIAL;
break;
case TRUST_E_TIME_STAMP:
ResourceId = IDS_SPC_TIMESTAMP;
break;
case CERT_E_REVOKED:
ResourceId = IDS_SPC_CERT_REVOKED;
break;
case CERT_E_REVOCATION_FAILURE:
ResourceId = IDS_SPC_REVOCATION_ERROR;
break;
case CRYPT_E_SECURITY_SETTINGS:
ResourceId = IDS_SPC_SECURITY_SETTINGS;
break;
case CERT_E_MALFORMED:
ResourceId = IDS_SPC_INVALID_EXTENSION;
break;
case CERT_E_WRONG_USAGE:
ResourceId = IDS_WRONG_USAGE;
break;
}
//
// If it does, load the string out of our resource string tables and
// return that. Otherwise, try to format the message from the system
//
DWORD_PTR MessageArgument;
CHAR szError[33];
WCHAR wszError[33];
LPVOID pvMsg;
pvMsg = NULL;
if ( ResourceId != 0 )
{
if ( LoadStringU(
g_hModule,
ResourceId,
psz,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
*ppsz = new WCHAR[wcslen(psz) + 1];
if ( *ppsz != NULL )
{
wcscpy(*ppsz, psz);
}
else
{
return( E_OUTOFMEMORY );
}
}
else if ( ( hr >= 0x80093000 ) && ( hr <= 0x80093999 ) )
{
if ( LoadStringU(
g_hModule,
IDS_SPC_OSS_ERROR,
psz,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
#if (0) // DSIE: Use the snprintf, instead.
_sprintf(szError, "%lx", hr);
#else
_snprintf(szError, ARRAYSIZE(szError), "%lx", hr);
#endif
if (0 == MultiByteToWideChar(0, 0, szError, -1, &wszError[0], ARRAYSIZE(wszError)))
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
MessageArgument = (DWORD_PTR)wszError;
if ( FormatMessageU(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
psz,
0,
0,
(LPWSTR)&pvMsg,
0,
(va_list *)&MessageArgument
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
}
else
{
if ( FormatMessageU(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
hr,
0,
(LPWSTR)&pvMsg,
0,
NULL
) == 0 )
{
if ( LoadStringU(
g_hModule,
IDS_SPC_UNKNOWN,
psz,
MAX_LOADSTRING_BUFFER
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
_snprintf(szError, ARRAYSIZE(szError), "%lx", hr);
if (0 == MultiByteToWideChar(0, 0, szError, -1, &wszError[0], ARRAYSIZE(wszError)))
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
MessageArgument = (DWORD_PTR)wszError;
if ( FormatMessageU(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_STRING |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
psz,
0,
0,
(LPWSTR)&pvMsg,
0,
(va_list *)&MessageArgument
) == 0 )
{
return( HRESULT_FROM_WIN32(GetLastError()) );
}
}
}
if (pvMsg)
{
*ppsz = new WCHAR[wcslen((WCHAR *)pvMsg) + 1];
if (*ppsz)
{
wcscpy(*ppsz, (WCHAR *)pvMsg);
}
LocalFree(pvMsg);
}
return( S_OK );
}