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.
816 lines
19 KiB
816 lines
19 KiB
//+--------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
//
|
|
// File: exit.cpp
|
|
//
|
|
// Contents: CCertExitSample implementation
|
|
//
|
|
//---------------------------------------------------------------------------
|
|
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
#include <assert.h>
|
|
#include "celib.h"
|
|
#include "exit.h"
|
|
#include "module.h"
|
|
|
|
BOOL fDebug = DBG_CERTSRV;
|
|
|
|
#ifndef DBG_CERTSRV
|
|
#error -- DBG_CERTSRV not defined!
|
|
#endif
|
|
|
|
#define ceEXITEVENTS \
|
|
(EXITEVENT_CERTDENIED | \
|
|
EXITEVENT_CERTISSUED | \
|
|
EXITEVENT_CERTPENDING | \
|
|
EXITEVENT_CERTRETRIEVEPENDING | \
|
|
EXITEVENT_CERTREVOKED | \
|
|
EXITEVENT_CRLISSUED | \
|
|
EXITEVENT_SHUTDOWN)
|
|
|
|
|
|
extern HINSTANCE g_hInstance;
|
|
|
|
|
|
HRESULT
|
|
GetServerCallbackInterface(
|
|
OUT ICertServerExit** ppServer,
|
|
IN LONG Context)
|
|
{
|
|
HRESULT hr;
|
|
|
|
if (NULL == ppServer)
|
|
{
|
|
hr = E_POINTER;
|
|
_JumpError(hr, error, "Exit:NULL pointer");
|
|
}
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_CCertServerExit,
|
|
NULL, // pUnkOuter
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICertServerExit,
|
|
(VOID **) ppServer);
|
|
_JumpIfError(hr, error, "Exit:CoCreateInstance");
|
|
|
|
if (*ppServer == NULL)
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
_JumpError(hr, error, "Exit:NULL *ppServer");
|
|
}
|
|
|
|
// only set context if nonzero
|
|
if (0 != Context)
|
|
{
|
|
hr = (*ppServer)->SetContext(Context);
|
|
_JumpIfError(hr, error, "Exit: SetContext");
|
|
}
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::~CCertExitSample -- destructor
|
|
//
|
|
// free memory associated with this instance
|
|
//+--------------------------------------------------------------------------
|
|
|
|
CCertExitSample::~CCertExitSample()
|
|
{
|
|
if (NULL != m_strCAName)
|
|
{
|
|
SysFreeString(m_strCAName);
|
|
}
|
|
if (NULL != m_pwszRegStorageLoc)
|
|
{
|
|
LocalFree(m_pwszRegStorageLoc);
|
|
}
|
|
if (NULL != m_hExitKey)
|
|
{
|
|
RegCloseKey(m_hExitKey);
|
|
}
|
|
if (NULL != m_strDescription)
|
|
{
|
|
SysFreeString(m_strDescription);
|
|
}
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::Initialize -- initialize for a CA & return interesting Event Mask
|
|
//
|
|
// Returns S_OK on success.
|
|
//+--------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
CCertExitSample::Initialize(
|
|
/* [in] */ BSTR const strConfig,
|
|
/* [retval][out] */ LONG __RPC_FAR *pEventMask)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
DWORD cbbuf;
|
|
DWORD dwType;
|
|
ENUM_CATYPES CAType;
|
|
ICertServerExit *pServer = NULL;
|
|
VARIANT varValue;
|
|
WCHAR sz[MAX_PATH];
|
|
|
|
VariantInit(&varValue);
|
|
|
|
assert(wcslen(wsz_SAMPLE_DESCRIPTION) < ARRAYSIZE(sz));
|
|
wcsncpy(sz, wsz_SAMPLE_DESCRIPTION, ARRAYSIZE(sz));
|
|
sz[ARRAYSIZE(sz) - 1] = L'\0';
|
|
|
|
m_strDescription = SysAllocString(sz);
|
|
if (NULL == m_strDescription)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:SysAllocString");
|
|
}
|
|
|
|
m_strCAName = SysAllocString(strConfig);
|
|
if (NULL == m_strCAName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:SysAllocString");
|
|
}
|
|
|
|
*pEventMask = ceEXITEVENTS;
|
|
DBGPRINT((fDebug, "Exit:Initialize(%ws) ==> %x\n", m_strCAName, *pEventMask));
|
|
|
|
// get server callbacks
|
|
|
|
hr = GetServerCallbackInterface(&pServer, 0);
|
|
_JumpIfError(hr, error, "Exit:GetServerCallbackInterface");
|
|
|
|
// get storage location
|
|
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest
|
|
wszPROPMODULEREGLOC,
|
|
PROPTYPE_STRING,
|
|
&varValue);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPMODULEREGLOC);
|
|
|
|
m_pwszRegStorageLoc = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(varValue.bstrVal)+1) *sizeof(WCHAR));
|
|
if (NULL == m_pwszRegStorageLoc)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:LocalAlloc");
|
|
}
|
|
wcscpy(m_pwszRegStorageLoc, varValue.bstrVal);
|
|
VariantClear(&varValue);
|
|
|
|
// get CA type
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest
|
|
wszPROPCATYPE,
|
|
PROPTYPE_LONG,
|
|
&varValue);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPCATYPE);
|
|
|
|
CAType = (ENUM_CATYPES) varValue.lVal;
|
|
VariantClear(&varValue);
|
|
|
|
hr = RegOpenKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
m_pwszRegStorageLoc,
|
|
0, // dwReserved
|
|
KEY_ENUMERATE_SUB_KEYS | KEY_EXECUTE | KEY_QUERY_VALUE,
|
|
&m_hExitKey);
|
|
|
|
if (S_OK != hr)
|
|
{
|
|
if ((HRESULT) ERROR_FILE_NOT_FOUND == hr)
|
|
{
|
|
hr = S_OK;
|
|
goto error;
|
|
}
|
|
_JumpError(hr, error, "Exit:RegOpenKeyEx");
|
|
}
|
|
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest
|
|
wszPROPCERTCOUNT,
|
|
PROPTYPE_LONG,
|
|
&varValue);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPCERTCOUNT);
|
|
|
|
m_cCACert = varValue.lVal;
|
|
|
|
cbbuf = sizeof(m_dwExitPublishFlags);
|
|
hr = RegQueryValueEx(
|
|
m_hExitKey,
|
|
wszREGCERTPUBLISHFLAGS,
|
|
NULL, // lpdwReserved
|
|
&dwType,
|
|
(BYTE *) &m_dwExitPublishFlags,
|
|
&cbbuf);
|
|
if (S_OK != hr)
|
|
{
|
|
m_dwExitPublishFlags = 0;
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
error:
|
|
VariantClear(&varValue);
|
|
if (NULL != pServer)
|
|
{
|
|
pServer->Release();
|
|
}
|
|
return(ceHError(hr));
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::_ExpandEnvironmentVariables -- Expand environment variables
|
|
//
|
|
//+--------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CCertExitSample::_ExpandEnvironmentVariables(
|
|
IN WCHAR const *pwszIn,
|
|
OUT WCHAR *pwszOut,
|
|
IN DWORD cwcOut)
|
|
{
|
|
HRESULT hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
|
WCHAR awcVar[MAX_PATH];
|
|
WCHAR const *pwszSrc;
|
|
WCHAR *pwszDst;
|
|
WCHAR *pwszDstEnd;
|
|
WCHAR *pwszVar;
|
|
DWORD cwc;
|
|
|
|
pwszSrc = pwszIn;
|
|
pwszDst = pwszOut;
|
|
pwszDstEnd = &pwszOut[cwcOut];
|
|
|
|
while (L'\0' != (*pwszDst = *pwszSrc++))
|
|
{
|
|
if ('%' == *pwszDst)
|
|
{
|
|
*pwszDst = L'\0';
|
|
pwszVar = awcVar;
|
|
|
|
while (L'\0' != *pwszSrc)
|
|
{
|
|
if ('%' == *pwszSrc)
|
|
{
|
|
pwszSrc++;
|
|
break;
|
|
}
|
|
*pwszVar++ = *pwszSrc++;
|
|
if (pwszVar >= &awcVar[sizeof(awcVar)/sizeof(awcVar[0]) - 1])
|
|
{
|
|
_JumpError(hr, error, "Exit:overflow 1");
|
|
}
|
|
}
|
|
*pwszVar = L'\0';
|
|
cwc = GetEnvironmentVariable(awcVar, pwszDst, SAFE_SUBTRACT_POINTERS(pwszDstEnd, pwszDst));
|
|
if (0 == cwc)
|
|
{
|
|
hr = ceHLastError();
|
|
_JumpError(hr, error, "Exit:GetEnvironmentVariable");
|
|
}
|
|
if ((DWORD) (pwszDstEnd - pwszDst) <= cwc)
|
|
{
|
|
_JumpError(hr, error, "Exit:overflow 2");
|
|
}
|
|
pwszDst += cwc;
|
|
}
|
|
else
|
|
{
|
|
pwszDst++;
|
|
}
|
|
if (pwszDst >= pwszDstEnd)
|
|
{
|
|
_JumpError(hr, error, "Exit:overflow 3");
|
|
}
|
|
}
|
|
hr = S_OK;
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
exitGetRequestAttribute(
|
|
IN ICertServerExit *pServer,
|
|
IN WCHAR const *pwszAttributeName,
|
|
OUT BSTR *pstrOut)
|
|
{
|
|
HRESULT hr;
|
|
BSTR strName = NULL;
|
|
|
|
*pstrOut = NULL;
|
|
strName = SysAllocString(pwszAttributeName);
|
|
if (NULL == strName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:SysAllocString");
|
|
}
|
|
hr = pServer->GetRequestAttribute(strName, pstrOut);
|
|
_JumpIfErrorStr2(
|
|
hr,
|
|
error,
|
|
"Exit:GetRequestAttribute",
|
|
pwszAttributeName,
|
|
CERTSRV_E_PROPERTY_EMPTY);
|
|
|
|
error:
|
|
if (NULL != strName)
|
|
{
|
|
SysFreeString(strName);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::_WriteCertToFile -- write binary certificate to a file
|
|
//
|
|
//+--------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CCertExitSample::_WriteCertToFile(
|
|
IN ICertServerExit *pServer,
|
|
IN BYTE const *pbCert,
|
|
IN DWORD cbCert)
|
|
{
|
|
HRESULT hr;
|
|
BSTR strCertFile = NULL;
|
|
DWORD cbWritten;
|
|
HANDLE hFile = INVALID_HANDLE_VALUE;
|
|
WCHAR wszDir[MAX_PATH];
|
|
WCHAR *pwszPath = NULL;
|
|
WCHAR wszFile[cwcDWORDSPRINTF+5]; //format "requestid.cer"
|
|
VARIANT varRequestID;
|
|
|
|
VariantInit(&varRequestID);
|
|
|
|
|
|
hr = exitGetRequestAttribute(pServer, wszPROPEXITCERTFILE, &strCertFile);
|
|
if (S_OK != hr)
|
|
{
|
|
DBGPRINT((
|
|
fDebug,
|
|
"Exit:exitGetRequestAttribute(%ws): %x%hs\n",
|
|
wszPROPEXITCERTFILE,
|
|
hr,
|
|
CERTSRV_E_PROPERTY_EMPTY == hr? " EMPTY VALUE" : ""));
|
|
if (CERTSRV_E_PROPERTY_EMPTY == hr)
|
|
{
|
|
hr = S_OK;
|
|
}
|
|
goto error;
|
|
}
|
|
|
|
// build file name as "requestid.cer"
|
|
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
TRUE, // fRequest,
|
|
wszPROPREQUESTREQUESTID,
|
|
PROPTYPE_LONG,
|
|
&varRequestID);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszPROPREQUESTREQUESTID);
|
|
|
|
wsprintf(wszFile, L"%d.cer", V_I4(&varRequestID));
|
|
|
|
hr = _ExpandEnvironmentVariables(
|
|
L"%SystemRoot%\\System32\\" wszCERTENROLLSHAREPATH L"\\",
|
|
wszDir,
|
|
ARRAYSIZE(wszDir));
|
|
_JumpIfError(hr, error, "_ExpandEnvironmentVariables");
|
|
|
|
hr = ceBuildPathAndExt(wszDir, wszFile, NULL, &pwszPath);
|
|
_JumpIfError(hr, error, "ceBuildPathAndExt");
|
|
|
|
// open file & write binary cert out.
|
|
|
|
hFile = CreateFile(
|
|
pwszPath,
|
|
GENERIC_WRITE,
|
|
0, // dwShareMode
|
|
NULL, // lpSecurityAttributes
|
|
CREATE_NEW,
|
|
FILE_ATTRIBUTE_NORMAL,
|
|
NULL); // hTemplateFile
|
|
if (INVALID_HANDLE_VALUE == hFile)
|
|
{
|
|
hr = ceHLastError();
|
|
_JumpErrorStr(hr, error, "Exit:CreateFile", pwszPath);
|
|
}
|
|
if (!WriteFile(hFile, pbCert, cbCert, &cbWritten, NULL))
|
|
{
|
|
hr = ceHLastError();
|
|
_JumpErrorStr(hr, error, "Exit:WriteFile", pwszPath);
|
|
}
|
|
if (cbWritten != cbCert)
|
|
{
|
|
hr = STG_E_WRITEFAULT;
|
|
DBGPRINT((
|
|
fDebug,
|
|
"Exit:WriteFile(%ws): attempted %x, actual %x bytes: %x\n",
|
|
pwszPath,
|
|
cbCert,
|
|
cbWritten,
|
|
hr));
|
|
goto error;
|
|
}
|
|
|
|
error:
|
|
|
|
if (INVALID_HANDLE_VALUE != hFile)
|
|
{
|
|
CloseHandle(hFile);
|
|
}
|
|
if (NULL != pwszPath)
|
|
{
|
|
LocalFree(pwszPath);
|
|
}
|
|
if (NULL != strCertFile)
|
|
{
|
|
SysFreeString(strCertFile);
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::_NotifyNewCert -- Notify the exit module of a new certificate
|
|
//
|
|
//+--------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CCertExitSample::_NotifyNewCert(
|
|
/* [in] */ LONG Context)
|
|
{
|
|
HRESULT hr;
|
|
VARIANT varCert;
|
|
ICertServerExit *pServer = NULL;
|
|
|
|
VariantInit(&varCert);
|
|
|
|
// only call write fxns if server policy allows
|
|
|
|
if (m_dwExitPublishFlags & EXITPUB_FILE)
|
|
{
|
|
hr = CoCreateInstance(
|
|
CLSID_CCertServerExit,
|
|
NULL, // pUnkOuter
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICertServerExit,
|
|
(VOID **) &pServer);
|
|
_JumpIfError(hr, error, "Exit:CoCreateInstance");
|
|
|
|
hr = pServer->SetContext(Context);
|
|
_JumpIfError(hr, error, "Exit:SetContext");
|
|
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest,
|
|
wszPROPRAWCERTIFICATE,
|
|
PROPTYPE_BINARY,
|
|
&varCert);
|
|
_JumpIfErrorStr(
|
|
hr,
|
|
error,
|
|
"Exit:exitGetProperty",
|
|
wszPROPRAWCERTIFICATE);
|
|
|
|
if (VT_BSTR != varCert.vt)
|
|
{
|
|
hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA);
|
|
_JumpError(hr, error, "Exit:BAD cert var type");
|
|
}
|
|
|
|
hr = _WriteCertToFile(
|
|
pServer,
|
|
(BYTE const *) varCert.bstrVal,
|
|
SysStringByteLen(varCert.bstrVal));
|
|
_JumpIfError(hr, error, "_WriteCertToFile");
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
error:
|
|
VariantClear(&varCert);
|
|
if (NULL != pServer)
|
|
{
|
|
pServer->Release();
|
|
}
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::_NotifyCRLIssued -- Notify the exit module of a new certificate
|
|
//
|
|
//+--------------------------------------------------------------------------
|
|
|
|
HRESULT
|
|
CCertExitSample::_NotifyCRLIssued(
|
|
/* [in] */ LONG Context)
|
|
{
|
|
HRESULT hr;
|
|
ICertServerExit *pServer = NULL;
|
|
DWORD i;
|
|
VARIANT varBaseCRL;
|
|
VARIANT varDeltaCRL;
|
|
BOOL fDeltaCRLsDisabled;
|
|
|
|
VariantInit(&varBaseCRL);
|
|
VariantInit(&varDeltaCRL);
|
|
|
|
hr = CoCreateInstance(
|
|
CLSID_CCertServerExit,
|
|
NULL, // pUnkOuter
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICertServerExit,
|
|
(VOID **) &pServer);
|
|
_JumpIfError(hr, error, "Exit:CoCreateInstance");
|
|
|
|
hr = pServer->SetContext(Context);
|
|
_JumpIfError(hr, error, "Exit:SetContext");
|
|
|
|
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest,
|
|
wszPROPDELTACRLSDISABLED,
|
|
PROPTYPE_LONG,
|
|
&varBaseCRL);
|
|
_JumpIfErrorStr(
|
|
hr,
|
|
error,
|
|
"Exit:exitGetProperty",
|
|
wszPROPDELTACRLSDISABLED);
|
|
|
|
fDeltaCRLsDisabled = varBaseCRL.lVal;
|
|
|
|
// How many CRLs are there?
|
|
|
|
// Loop for each CRL
|
|
for (i = 0; i < m_cCACert; i++)
|
|
{
|
|
// array size for wsprintf("%s.%u")
|
|
#define MAX_CRL_PROP \
|
|
(max( \
|
|
max(ARRAYSIZE(wszPROPCRLSTATE), ARRAYSIZE(wszPROPRAWCRL)), \
|
|
ARRAYSIZE(wszPROPRAWDELTACRL)) + \
|
|
1 + cwcDWORDSPRINTF)
|
|
|
|
WCHAR wszCRLPROP[MAX_CRL_PROP];
|
|
|
|
// Verify the CRL State says we should update this CRL
|
|
|
|
wsprintf(wszCRLPROP, wszPROPCRLSTATE L".%u", i);
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest,
|
|
wszCRLPROP,
|
|
PROPTYPE_LONG,
|
|
&varBaseCRL);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszCRLPROP);
|
|
|
|
if (CA_DISP_VALID != varBaseCRL.lVal)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// Grab the raw base CRL
|
|
|
|
wsprintf(wszCRLPROP, wszPROPRAWCRL L".%u", i);
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest,
|
|
wszCRLPROP,
|
|
PROPTYPE_BINARY,
|
|
&varBaseCRL);
|
|
_JumpIfErrorStr(hr, error, "Exit:exitGetProperty", wszCRLPROP);
|
|
|
|
// Grab the raw delta CRL (which may not exist)
|
|
|
|
wsprintf(wszCRLPROP, wszPROPRAWDELTACRL L".%u", i);
|
|
hr = exitGetProperty(
|
|
pServer,
|
|
FALSE, // fRequest,
|
|
wszCRLPROP,
|
|
PROPTYPE_BINARY,
|
|
&varDeltaCRL);
|
|
_PrintIfErrorStr2(
|
|
hr,
|
|
"Exit:exitGetProperty",
|
|
wszCRLPROP,
|
|
fDeltaCRLsDisabled?
|
|
HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) : S_OK);
|
|
if (S_OK != hr && !fDeltaCRLsDisabled)
|
|
{
|
|
goto error;
|
|
}
|
|
|
|
// Publish the CRL(s) ...
|
|
}
|
|
|
|
hr = S_OK;
|
|
|
|
error:
|
|
if (NULL != pServer)
|
|
{
|
|
pServer->Release();
|
|
}
|
|
VariantClear(&varBaseCRL);
|
|
VariantClear(&varDeltaCRL);
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::Notify -- Notify the exit module of an event
|
|
//
|
|
// Returns S_OK.
|
|
//+--------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
CCertExitSample::Notify(
|
|
/* [in] */ LONG ExitEvent,
|
|
/* [in] */ LONG Context)
|
|
{
|
|
char *psz = "UNKNOWN EVENT";
|
|
HRESULT hr = S_OK;
|
|
|
|
switch (ExitEvent)
|
|
{
|
|
case EXITEVENT_CERTISSUED:
|
|
hr = _NotifyNewCert(Context);
|
|
psz = "certissued";
|
|
break;
|
|
|
|
case EXITEVENT_CERTPENDING:
|
|
psz = "certpending";
|
|
break;
|
|
|
|
case EXITEVENT_CERTDENIED:
|
|
psz = "certdenied";
|
|
break;
|
|
|
|
case EXITEVENT_CERTREVOKED:
|
|
psz = "certrevoked";
|
|
break;
|
|
|
|
case EXITEVENT_CERTRETRIEVEPENDING:
|
|
psz = "retrievepending";
|
|
break;
|
|
|
|
case EXITEVENT_CRLISSUED:
|
|
hr = _NotifyCRLIssued(Context);
|
|
psz = "crlissued";
|
|
break;
|
|
|
|
case EXITEVENT_SHUTDOWN:
|
|
psz = "shutdown";
|
|
break;
|
|
}
|
|
|
|
|
|
DBGPRINT((
|
|
fDebug,
|
|
"Exit:Notify(%hs=%x, ctx=%x) rc=%x\n",
|
|
psz,
|
|
ExitEvent,
|
|
Context,
|
|
hr));
|
|
return(hr);
|
|
}
|
|
|
|
|
|
STDMETHODIMP
|
|
CCertExitSample::GetDescription(
|
|
/* [retval][out] */ BSTR *pstrDescription)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
WCHAR sz[MAX_PATH];
|
|
|
|
assert(wcslen(wsz_SAMPLE_DESCRIPTION) < ARRAYSIZE(sz));
|
|
wcscpy(sz, wsz_SAMPLE_DESCRIPTION);
|
|
|
|
*pstrDescription = SysAllocString(sz);
|
|
if (NULL == *pstrDescription)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:SysAllocString");
|
|
}
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
//+--------------------------------------------------------------------------
|
|
// CCertExitSample::GetManageModule
|
|
//
|
|
// Returns S_OK on success.
|
|
//+--------------------------------------------------------------------------
|
|
|
|
STDMETHODIMP
|
|
CCertExitSample::GetManageModule(
|
|
/* [out, retval] */ ICertManageModule **ppManageModule)
|
|
{
|
|
HRESULT hr;
|
|
|
|
*ppManageModule = NULL;
|
|
hr = CoCreateInstance(
|
|
CLSID_CCertManageExitModuleSample,
|
|
NULL, // pUnkOuter
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_ICertManageModule,
|
|
(VOID **) ppManageModule);
|
|
_JumpIfError(hr, error, "CoCreateInstance");
|
|
|
|
error:
|
|
return(hr);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
STDMETHODIMP
|
|
CCertExitSample::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
int i;
|
|
static const IID *arr[] =
|
|
{
|
|
&IID_ICertExit,
|
|
};
|
|
|
|
for (i = 0; i < sizeof(arr)/sizeof(arr[0]); i++)
|
|
{
|
|
if (IsEqualGUID(*arr[i],riid))
|
|
{
|
|
return(S_OK);
|
|
}
|
|
}
|
|
return(S_FALSE);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
exitGetProperty(
|
|
IN ICertServerExit *pServer,
|
|
IN BOOL fRequest,
|
|
IN WCHAR const *pwszPropertyName,
|
|
IN DWORD PropType,
|
|
OUT VARIANT *pvarOut)
|
|
{
|
|
HRESULT hr;
|
|
BSTR strName = NULL;
|
|
|
|
VariantInit(pvarOut);
|
|
strName = SysAllocString(pwszPropertyName);
|
|
if (NULL == strName)
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
_JumpError(hr, error, "Exit:SysAllocString");
|
|
}
|
|
if (fRequest)
|
|
{
|
|
hr = pServer->GetRequestProperty(strName, PropType, pvarOut);
|
|
_JumpIfErrorStr2(
|
|
hr,
|
|
error,
|
|
"Exit:GetRequestProperty",
|
|
pwszPropertyName,
|
|
CERTSRV_E_PROPERTY_EMPTY);
|
|
}
|
|
else
|
|
{
|
|
hr = pServer->GetCertificateProperty(strName, PropType, pvarOut);
|
|
_JumpIfErrorStr2(
|
|
hr,
|
|
error,
|
|
"Exit:GetCertificateProperty",
|
|
pwszPropertyName,
|
|
CERTSRV_E_PROPERTY_EMPTY);
|
|
}
|
|
|
|
error:
|
|
if (NULL != strName)
|
|
{
|
|
SysFreeString(strName);
|
|
}
|
|
return(hr);
|
|
}
|
|
|