|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1995 - 1999
//
// File: view.cpp
//
//--------------------------------------------------------------------------
#include <pch.cpp>
#pragma hdrstop
#include <esent.h>
#include <certdb.h>
#include "csprop.h"
#define __dwFILE__ __dwFILE_CERTUTIL_VIEW_CPP__
#define wszQUEUE L"Queue"
#define wszLOG L"Log"
#define wszLOGFAIL L"LogFail"
#define wszREVOKED L"Revoked"
#define wszCOLONQUEUE L":" wszQUEUE
#define wszCOLONLOG L":" wszLOG
#define wszCOLONLOGFAIL L":" wszLOGFAIL
#define wszCOLONREVOKED L":" wszREVOKED
ICertDB *g_pdb = NULL;
WCHAR const g_wszAttrib[] = L"attrib"; WCHAR const g_wszExt[] = L"ext"; WCHAR const g_wszCRL[] = L"CRL";
WCHAR const *g_apwszAllowedPrefixes[] = { g_wszAttrib, g_wszExt, NULL };
BOOL cuDBIsShutDownInProgress() { return(NULL == g_pdb); }
HRESULT ParseToken( OUT WCHAR *awcBuf, IN DWORD cwcBuf, IN BOOL fMatchPrefix, OPTIONAL IN WCHAR const *pwszPrefix, OPTIONAL IN WCHAR const * const *apwszAllowedPrefixes, OPTIONAL OUT BOOL *pfAllColumns, OUT WCHAR const **ppwszColumn, IN OUT WCHAR const **ppwszNext);
WCHAR const * cuwszPropType( IN LONG PropType) { DWORD msgid;
switch (PropType) { case PROPTYPE_DATE: msgid = IDS_PROPTYPE_DATE; // "Date"
break;
case PROPTYPE_LONG: msgid = IDS_PROPTYPE_LONG; // "Long"
break;
case PROPTYPE_STRING: msgid = IDS_PROPTYPE_STRING; // "String"
break;
case PROPTYPE_BINARY: msgid = IDS_PROPTYPE_BINARY; // "Binary"
break;
default: msgid = IDS_QUESTIONMARKS; // "???"
break; } return(myLoadResourceString(msgid)); }
typedef struct _COLINFO { BSTR strCol; BSTR strColDisplay; LONG type; LONG maxlen; LONG indexed; } COLINFO;
VOID cuPrintSchemaEntry( OPTIONAL IN WCHAR const *pwszName, IN WCHAR const *pwszDisplayName, IN LONG Type, IN LONG cbMax) { // wprintf(L" %-28ws %-28ws %-6ws", ...);
// OR
// wprintf(L"%-30ws %-6ws", ...);
if (NULL != pwszName) { wprintf(L" "); myConsolePrintString(28, pwszName); wprintf(L" "); } myConsolePrintString(NULL != pwszName? 28 : 30, pwszDisplayName); wprintf(L" "); myConsolePrintString(6, cuwszPropType(PROPTYPE_MASK & Type));
if (0 != cbMax) { wprintf(L" %u", cbMax); } if (PROPFLAGS_INDEXED & Type) { wprintf(myLoadResourceString(IDS_INDEXED)); // " -- Indexed"
} wprintf(wszNewLine); }
HRESULT DisplaySchema( IN DISPATCHINTERFACE *pdiView, IN LONG cColOut, OPTIONAL IN OUT COLINFO *aColInfo, IN BOOL fResult) { HRESULT hr; LONG i; BOOL fMustReleaseColumn = FALSE; DISPATCHINTERFACE diViewColumn; BSTR strCol = NULL; BSTR strColDisplay = NULL; LONG type; LONG maxlen; LONG indexed;
if (!g_fCryptSilent) { wprintf(myLoadResourceString(IDS_SCHEMA_COLON)); // "Schema:"
wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_SCHEMA_COLUMNHEADERS)); // "Name..Type..."
wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_SCHEMA_COLUMNUNDERLINE)); // "____...____"
wprintf(wszNewLine); }
hr = View_EnumCertViewColumn( pdiView, fResult? CVRC_COLUMN_RESULT : CVRC_COLUMN_SCHEMA, &diViewColumn); _JumpIfError(hr, error, "View_EnumCertViewColumn");
fMustReleaseColumn = TRUE;
for (i = 0; ; i++) { LONG ielt;
hr = ViewColumn_Next(&diViewColumn, &ielt); if (S_FALSE == hr || (S_OK == hr && -1 == ielt)) { CSASSERT(-1 == ielt); CSASSERT(i == cColOut); hr = S_OK; break; } _JumpIfError(hr, error, "ViewColumn_Next"); CSASSERT(-1 != ielt); CSASSERT(i < cColOut);
hr = ViewColumn_GetName(&diViewColumn, &strCol); _JumpIfError(hr, error, "ViewColumn_GetName");
hr = ViewColumn_GetDisplayName(&diViewColumn, &strColDisplay); _JumpIfError(hr, error, "ViewColumn_GetDisplayName");
hr = ViewColumn_GetType(&diViewColumn, &type); _JumpIfError(hr, error, "ViewColumn_GetType");
hr = ViewColumn_GetMaxLength(&diViewColumn, &maxlen); _JumpIfError(hr, error, "ViewColumn_GetType");
hr = ViewColumn_IsIndexed(&diViewColumn, &indexed); _JumpIfError(hr, error, "ViewColumn_IsIndexed");
if (!g_fCryptSilent) { cuPrintSchemaEntry( strCol, strColDisplay, type | (indexed? PROPFLAGS_INDEXED : 0), maxlen); } if (NULL != aColInfo) { aColInfo[i].strCol = strCol; strCol = NULL; aColInfo[i].strColDisplay = strColDisplay; strColDisplay = NULL; aColInfo[i].type = type; aColInfo[i].maxlen = maxlen; aColInfo[i].indexed = indexed; } }
error: if (NULL != strCol) { SysFreeString(strCol); } if (NULL != strColDisplay) { SysFreeString(strColDisplay); } if (fMustReleaseColumn) { ViewColumn_Release(&diViewColumn); } return(hr); }
LONG *g_askip = NULL; LONG g_cskip = 0; LONG g_iskip = 0; BOOL g_fskip = FALSE;
LONG GetSkip( IN BOOL fAdvance) { LONG cskip = 0;
if (g_fskip) { if (g_iskip >= g_cskip) { g_iskip = 0; } cskip = g_askip[g_iskip]; if (fAdvance) { g_iskip++; } } return(cskip); }
HRESULT ParseSkipCounts( IN WCHAR const *pwszField) { HRESULT hr; LONG i; WCHAR const *pwszNext; WCHAR const *pwszColumn; WCHAR awc[MAX_PATH];
pwszNext = pwszField; for (i = 0; ; i++) { hr = ParseToken( awc, ARRAYSIZE(awc), FALSE, NULL, NULL, NULL, &pwszColumn, &pwszNext); if (S_FALSE == hr) { break; } _JumpIfError(hr, error, "ParseToken"); } if (0 != i) { g_askip = (LONG *) LocalAlloc(LMEM_FIXED, i * sizeof(LONG)); if (NULL == g_askip) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "no memory for skip counts array"); } g_cskip = i; g_iskip = 0;
pwszNext = pwszField; for (i = 0; ; i++) { hr = ParseToken( awc, ARRAYSIZE(awc), FALSE, NULL, NULL, NULL, &pwszColumn, &pwszNext); if (S_FALSE == hr) { break; } _JumpIfError(hr, error, "ParseToken");
hr = myGetSignedLong(pwszColumn, &g_askip[i]); _JumpIfError(hr, error, "myGetLong");
//wprintf(L"ParseToken: %u: skip = '%ws' %d\n", i, pwszColumn, g_askip[i]);
} CSASSERT(i == g_cskip); g_fskip = TRUE; } hr = S_OK;
error: return(hr); }
HRESULT ParseRestriction( IN WCHAR const *pwszField, OUT LONG *pColIndex, OUT LONG *pSeekOperator, OUT LONG *pSortOrder, OUT WCHAR **ppwszColName, OUT WCHAR **ppwszColValue) { HRESULT hr; DWORD i; LONG SortOrder; LONG SeekOperator; LONG SeekOperator2; WCHAR *pwszColName = NULL; WCHAR *pwszColValue = NULL;
*pColIndex = 0; *ppwszColName = NULL; *ppwszColValue = NULL;
SeekOperator = CVR_SEEK_GE; SeekOperator2 = CVR_SEEK_GE; // might be used inadvertantly
SortOrder = CVR_SORT_NONE; if (L'+' == *pwszField) { SortOrder = CVR_SORT_ASCEND; pwszField++; } else if (myIsMinusSign(*pwszField)) { SortOrder = CVR_SORT_DESCEND; pwszField++; } while (L' ' == *pwszField) { pwszField++; }
// Copy the column name into wszBuf, and advance the pointer
i = wcscspn(pwszField, L"<>=");
pwszColName = (WCHAR *) LocalAlloc(LMEM_FIXED, (i + 1) * sizeof(WCHAR)); if (NULL == pwszColName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
CopyMemory(pwszColName, pwszField, i * sizeof(WCHAR)); pwszField += i; while (0 < i && L' ' == pwszColName[i - 1]) { i--; } pwszColName[i] = L'\0';
switch (*pwszField) { case L'\0': SeekOperator = CVR_SEEK_NONE; break;
case L'<': SeekOperator = CVR_SEEK_LT; // "<"
SeekOperator2 = CVR_SEEK_LE; // "<="
break;
case L'>': SeekOperator = CVR_SEEK_GT; // ">"
SeekOperator2 = CVR_SEEK_GE; // ">="
break;
case L'=': SeekOperator = CVR_SEEK_EQ; // "="
SeekOperator2 = CVR_SEEK_EQ; // "=="
break; default: hr = E_INVALIDARG; _JumpError(hr, error, "bad seek operator"); } if (L'\0' != *pwszField) { if (L'=' == *++pwszField) { SeekOperator = SeekOperator2; pwszField++; } }
while (L' ' == *pwszField) { pwszField++; } i = wcslen(pwszField); if (0 != i) { pwszColValue = (WCHAR *) LocalAlloc( LMEM_FIXED, (i + 1) * sizeof(WCHAR)); if (NULL == pwszColValue) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
wcscpy(pwszColValue, pwszField); while (0 < i && L' ' == pwszColValue[i - 1]) { i--; } pwszColValue[i] = L'\0'; cuConvertEscapeSequences(pwszColValue); } if (NULL == pwszColValue) { if (0 == LSTRCMPIS(pwszColName, wszCOLONQUEUE)) { *pColIndex = CV_COLUMN_QUEUE_DEFAULT; } else if (0 == LSTRCMPIS(pwszColName, wszCOLONLOG)) { *pColIndex = CV_COLUMN_LOG_DEFAULT; } else if (0 == LSTRCMPIS(pwszColName, wszCOLONLOGFAIL)) { *pColIndex = CV_COLUMN_LOG_FAILED_DEFAULT; } else if (0 == LSTRCMPIS(pwszColName, wszCOLONREVOKED)) { *pColIndex = CV_COLUMN_LOG_REVOKED_DEFAULT; } else { hr = E_INVALIDARG; _JumpError(hr, error, "bad special column name"); } } else { *ppwszColName = pwszColName; *ppwszColValue = pwszColValue; pwszColName = NULL; pwszColValue = NULL; } *pSortOrder = SortOrder; *pSeekOperator = SeekOperator; hr = S_OK;
error: if (NULL != pwszColName) { LocalFree(pwszColName); } if (NULL != pwszColValue) { LocalFree(pwszColValue); } return(hr); }
HRESULT ParseSpecialColumnValue( IN WCHAR const *pwszColValue, IN LONG ColType, IN OUT LONG *pSeekOperator, IN OUT LONG *pSortOrder, OUT BOOL *pfOneRow, OUT LONG *plSkip) { HRESULT hr; BOOL fFirst;
*pfOneRow = FALSE; *plSkip = 0;
switch (*pwszColValue) { case '^': fFirst = TRUE; break;
case '$': fFirst = FALSE; break;
default: hr = S_OK; goto error; } while (L' ' == *++pwszColValue) ;
if (L'\0' != *pwszColValue) { BOOL fInvalid; switch (*pwszColValue) { case '+': fInvalid = !fFirst; break;
case '-': fInvalid = fFirst; break;
default: hr = E_INVALIDARG; _JumpErrorStr(hr, error, "expected signed skip count", pwszColValue); } if (fInvalid) { hr = E_INVALIDARG; _JumpError(hr, error, "skip to before start"); } while (L' ' == *++pwszColValue) ;
hr = myGetLong(pwszColValue, plSkip); _JumpIfError(hr, error, "bad numeric operand"); } if (CVR_SEEK_EQ != *pSeekOperator || CVR_SORT_NONE != *pSortOrder) { hr = E_INVALIDARG; _JumpError(hr, error, "bad special restriction"); } if (fFirst) { *pSortOrder = CVR_SORT_ASCEND; } else { *pSortOrder = CVR_SORT_DESCEND; } *pSeekOperator = CVR_SEEK_GE; *pfOneRow = TRUE; hr = S_OK;
error: return(hr); }
HRESULT SetViewRestriction( IN DISPATCHINTERFACE *pdiView, IN WCHAR const *pwszField, OUT BOOL *pfOneRow, OUT LONG *plSkip) { HRESULT hr; VARIANT var; LONG ColIndex; LONG ColType; BSTR strColName = NULL; LONG SeekOperator; LONG SortOrder; WCHAR *pwszColName = NULL; WCHAR *pwszColValue = NULL; BOOL fMustReleaseColumn = FALSE; DISPATCHINTERFACE diViewColumn;
VariantInit(&var); *pfOneRow = FALSE; *plSkip = 0;
hr = ParseRestriction( pwszField, &ColIndex, &SeekOperator, &SortOrder, &pwszColName, &pwszColValue); _JumpIfErrorStr(hr, error, "ParseRestriction", pwszField);
// no value to parse if a special column...
if (NULL == pwszColName) { CSASSERT(0 > ColIndex); } else { LONG ielt;
hr = View_GetColumnIndex( pdiView, CVRC_COLUMN_SCHEMA, pwszColName, &ColIndex); _JumpIfErrorStr(hr, error, "View_GetColumnIndex", pwszColName);
hr = View_EnumCertViewColumn( pdiView, CVRC_COLUMN_SCHEMA, &diViewColumn); _JumpIfError(hr, error, "View_EnumCertViewColumn");
fMustReleaseColumn = TRUE;
hr = ViewColumn_Skip(&diViewColumn, ColIndex); _JumpIfError(hr, error, "ViewColumn_Skip");
hr = ViewColumn_Next(&diViewColumn, &ielt); if (S_OK == hr && -1 == ielt) { hr = S_FALSE; } _JumpIfError(hr, error, "ViewColumn_Next");
hr = ViewColumn_GetName(&diViewColumn, &strColName); _JumpIfError(hr, error, "GetName");
hr = ViewColumn_GetType(&diViewColumn, &ColType); _JumpIfError(hr, error, "GetType");
hr = ParseSpecialColumnValue( pwszColValue, ColType, &SeekOperator, &SortOrder, pfOneRow, plSkip); _JumpIfError(hr, error, "ParseSpecialColumnValue");
switch (ColType) { case PROPTYPE_LONG: var.lVal = 0; if (!*pfOneRow) { hr = myGetSignedLong(pwszColValue, &var.lVal); _JumpIfError(hr, error, "bad numeric operand"); } var.vt = VT_I4; break;
case PROPTYPE_DATE: var.date = 0; if (!*pfOneRow) { hr = myWszLocalTimeToGMTDate(pwszColValue, &var.date); _JumpIfError(hr, error, "invalid date format"); } var.vt = VT_DATE; cuDumpDate(&var.date); break;
case PROPTYPE_STRING: { WCHAR const *pwsz = L""; var.bstrVal = NULL; if (!*pfOneRow) { pwsz = pwszColValue; } if (!ConvertWszToBstr(&var.bstrVal, pwsz, MAXDWORD)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "ConvertWszToBstr"); } var.vt = VT_BSTR; break; }
case PROPTYPE_BINARY: default: hr = E_INVALIDARG; _JumpError(hr, error, "not supported"); } } //wprintf(L"ColIndex=%x(%d) vt=%d\n", ColIndex, ColIndex, var.vt);
hr = View_SetRestriction( pdiView, ColIndex, // Restriction ColumnIndex
SeekOperator, SortOrder, &var); // pvarValue
_JumpIfError(hr, error, "View_SetRestriction");
error: if (NULL != pwszColName) { LocalFree(pwszColName); } if (NULL != pwszColValue) { LocalFree(pwszColValue); } if (fMustReleaseColumn) { ViewColumn_Release(&diViewColumn); } if (NULL != strColName) { SysFreeString(strColName); } VariantClear(&var); return(hr); }
HRESULT cuParseStrings( IN WCHAR const *pwszStrings, IN BOOL fMatchPrefix, OPTIONAL IN WCHAR const *pwszPrefix, OPTIONAL IN WCHAR const * const *apwszAllowedPrefixes, OUT WCHAR ***papwszStrings, OPTIONAL OUT BOOL *pfAllFields) { HRESULT hr; WCHAR const *pwszNext; WCHAR awc[MAX_PATH]; DWORD i; WCHAR const *pwszCurrent; WCHAR **ppwsz;
if (NULL != pfAllFields) { *pfAllFields = FALSE; } *papwszStrings = NULL;
pwszNext = pwszStrings; for (i = 0; ; i++) { hr = ParseToken( awc, ARRAYSIZE(awc), fMatchPrefix, pwszPrefix, apwszAllowedPrefixes, pfAllFields, &pwszCurrent, &pwszNext); if (S_FALSE == hr) { break; } _JumpIfError(hr, error, "ParseToken"); } if (0 != i) { *papwszStrings = (WCHAR **) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, (i + 1) * sizeof(WCHAR *)); if (NULL == *papwszStrings) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "no memory for string array"); }
ppwsz = *papwszStrings; pwszNext = pwszStrings; for ( ; 0 < i; i--) { hr = ParseToken( awc, ARRAYSIZE(awc), fMatchPrefix, pwszPrefix, apwszAllowedPrefixes, pfAllFields, &pwszCurrent, &pwszNext); CSASSERT(S_FALSE != hr); _JumpIfError(hr, error, "ParseToken");
hr = myDupString(pwszCurrent, ppwsz); _JumpIfError(hr, error, "myDupString");
ppwsz++; } *ppwsz = NULL; } hr = S_OK;
error: if (S_OK != hr) { cuFreeStringArray(*papwszStrings); *papwszStrings = NULL; } return(hr); }
HRESULT ParseViewRestrictions( IN WCHAR const *pwszRestrictions, OUT WCHAR ***papwszRestrictions) { HRESULT hr;
hr = cuParseStrings( pwszRestrictions, FALSE, NULL, NULL, papwszRestrictions, NULL); _JumpIfError(hr, error, "cuParseStrings");
error: return(hr); }
HRESULT ParseToken( OUT WCHAR *awcBuf, IN DWORD cwcBuf, IN BOOL fMatchPrefix, OPTIONAL IN WCHAR const *pwszPrefix, OPTIONAL IN WCHAR const * const *apwszAllowedPrefixes, OPTIONAL OUT BOOL *pfAllColumns, OUT WCHAR const **ppwszColumn, IN OUT WCHAR const **ppwszNext) { HRESULT hr; WCHAR const *pwsz; WCHAR *pwszT; WCHAR *pwszColumn; DWORD cwc; DWORD cwcPrefix = 0;
if (NULL != pwszPrefix) { cwcPrefix = wcslen(pwszPrefix); } while (TRUE) { // Grab the next comma-separated token, and trim white space.
awcBuf[0] = L'\0'; pwsz = *ppwszNext; while (L' ' == *pwsz) { pwsz++; } cwc = wcscspn(pwsz, L","); if (cwc >= cwcBuf) { hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); _JumpError(hr, error, "Buffer overflow"); } CopyMemory(awcBuf, pwsz, cwc * sizeof(WCHAR)); awcBuf[cwc] = L'\0';
pwsz += cwc; while (L',' == *pwsz) { pwsz++; } *ppwszNext = pwsz;
while (0 < cwc && L' ' == awcBuf[cwc - 1]) { awcBuf[--cwc] = L'\0'; }
if (0 == cwc) { if (L'\0' == *pwsz) { *ppwszColumn = NULL; hr = S_FALSE; _JumpError2(hr, error, "end of list", hr); } continue; } pwszColumn = awcBuf; // assume no prefix
if (fMatchPrefix) { // Look for a colon separator that delimits a matching prefix.
// The separator must precede any relational operators:
cwc = wcscspn(awcBuf, L"<>=:"); pwszT = &awcBuf[cwc];
if (L':' != *pwszT) { if (NULL != pwszPrefix) { continue; // prefix missing, but expected
} } else { pwszColumn = pwszT; *pwszColumn++ = L'\0'; while (L' ' == *pwszColumn) { pwszColumn++; } while (pwszT > awcBuf && L' ' == *(pwszT - 1)) { *--pwszT = L'\0'; }
if (NULL != apwszAllowedPrefixes) { WCHAR const * const *ppwsz; for (ppwsz = apwszAllowedPrefixes; NULL != *ppwsz; ppwsz++) { if (0 == mylstrcmpiS(awcBuf, *ppwsz)) { break; } } if (NULL == *ppwsz) { hr = E_INVALIDARG; _JumpErrorStr(hr, error, "bad prefix", awcBuf); } } if (NULL == pwszPrefix) { continue; // prefix not expected
} if (pwszT - awcBuf != (LONG) cwcPrefix) { continue; // prefix length doesn't match
} if (0 != mylstrcmpiS(awcBuf, pwszPrefix)) { continue; // prefix doesn't match
} } if (NULL != pfAllColumns && 0 == LSTRCMPIS(pwszColumn, L"all")) { *pfAllColumns = TRUE; continue; } } *ppwszColumn = pwszColumn; hr = S_OK; break; }
error: if (S_OK != hr && 0 < cwcBuf) { awcBuf[0] = L'\0'; } return(hr); }
HRESULT ParseViewColumns( IN WCHAR const *pwszColumns, IN WCHAR const *pwszPrefix, OPTIONAL IN WCHAR const * const *apwszAllowedPrefixes, OUT WCHAR ***papwszColumns, OUT BOOL *pfAllColumns) { HRESULT hr;
hr = cuParseStrings( pwszColumns, TRUE, pwszPrefix, apwszAllowedPrefixes, papwszColumns, pfAllColumns); _JumpIfError(hr, error, "cuParseStrings");
error: return(hr); }
VOID PrintRowIndex( IN LONG iRow, IN OUT BOOL *pfPrinted) { if (!*pfPrinted) { wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_FORMAT_ROWID), iRow); // "Row %u:"
wprintf(wszNewLine); *pfPrinted = TRUE; } }
VOID cuFreeStringArray( IN OUT WCHAR **apwsz) { WCHAR **ppwsz;
if (NULL != apwsz) { for (ppwsz = apwsz; NULL != *ppwsz; ppwsz++) { myZeroDataString(*ppwsz); // possible password data
LocalFree(*ppwsz); } LocalFree(apwsz); } }
VOID cuFreeStringArrayA( IN OUT char **apsz) { char **ppsz;
if (NULL != apsz) { for (ppsz = apsz; NULL != *ppsz; ppsz++) { LocalFree(*ppsz); } LocalFree(apsz); } }
VOID DumpLongValue( IN LONG longValue, IN WCHAR const *pwszColumnName) { long aidMsg[20]; DWORD cidMsg; DWORD i; WCHAR const *pwszError = NULL; WCHAR const *pwszMsg = NULL; WCHAR awchr[cwcHRESULTSTRING]; BOOL fDisplayNumeric = TRUE; BOOL fDisplayFlags = FALSE;
cidMsg = 0; if (0 == LSTRCMPIS( pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTDISPOSITION)) { switch (longValue) { case DB_DISP_ACTIVE: aidMsg[0] = IDS_DISP_ACTIVE; break; case DB_DISP_PENDING: aidMsg[0] = IDS_DISP_PENDING; break; case DB_DISP_FOREIGN: aidMsg[0] = IDS_DISP_FOREIGN_CERT; break; case DB_DISP_KRA_CERT: aidMsg[0] = IDS_DISP_KRA_CERT; break; case DB_DISP_CA_CERT: aidMsg[0] = IDS_DISP_CA_CERT; break; case DB_DISP_CA_CERT_CHAIN: aidMsg[0] = IDS_DISP_CA_CERT_CHAIN; break; case DB_DISP_ISSUED: aidMsg[0] = IDS_DISP_ISSUED; break; case DB_DISP_REVOKED: aidMsg[0] = IDS_DISP_REVOKED; break; case DB_DISP_ERROR: aidMsg[0] = IDS_DISP_ERROR; break; case DB_DISP_DENIED: aidMsg[0] = IDS_DISP_DENIED; break; default: aidMsg[0] = IDS_QUESTIONMARKS; break; } cidMsg = 1; } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTFLAGS)) { if (CR_FLG_RENEWAL & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_RENEWAL; } if (CR_FLG_FORCETELETEX & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_FORCETELETEX; } if (CR_FLG_FORCEUTF8 & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_FORCEUTF8; } if (CR_FLG_CAXCHGCERT & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_CAXCHGCERT; } if (CR_FLG_ENROLLONBEHALFOF & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_ENROLLONBEHALFOF; } if (CR_FLG_SUBJECTUNMODIFIED & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_SUBJECTUNMODIFIED; } if (CR_FLG_VALIDENCRYPTEDKEYHASH & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_VALIDENCRYPTEDKEYHASH; } if (CR_FLG_PUBLISHERROR & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_PUBLISHERROR; } if (CR_FLG_CACROSSCERT & longValue) { aidMsg[cidMsg++] = IDS_REQFLAGS_CACROSSCERT; } } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTTYPE)) { switch (CR_IN_FORMATMASK & longValue) { case CR_IN_FORMATANY: aidMsg[0] = IDS_REQTYPE_ANY; break; case CR_IN_PKCS10: aidMsg[0] = IDS_REQTYPE_PKCS10; break; case CR_IN_KEYGEN: aidMsg[0] = IDS_REQTYPE_KEYGEN; break; case CR_IN_PKCS7: aidMsg[0] = IDS_REQTYPE_PKCS7; break; case CR_IN_CMC: aidMsg[0] = IDS_REQTYPE_CMC; break; default: aidMsg[0] = IDS_REQTYPE_UNKNOWN; break; } cidMsg = 1; if (CR_IN_CRLS & longValue) { aidMsg[cidMsg++] = IDS_REQTYPE_CRLS; } if (CR_IN_FULLRESPONSE & longValue) { aidMsg[cidMsg++] = IDS_REQTYPE_FULLRESPONSE; } } else if (0 == LSTRCMPIS( pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTSTATUSCODE) || 0 == LSTRCMPIS(pwszColumnName, wszPROPCRLPUBLISHSTATUSCODE)) { pwszError = myGetErrorMessageText(longValue, FALSE); wprintf(L" %ws -- %ws", myHResultToString(awchr, longValue), pwszError); fDisplayNumeric = FALSE; } else if (0 == LSTRCMPIS( pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTREVOKEDREASON)) { aidMsg[0] = cuidCRLReason(longValue); cidMsg = 1; } else { fDisplayFlags = TRUE; }
if (fDisplayNumeric) { wprintf(L" 0x%x", longValue); if (0 > longValue || 9 < longValue) { wprintf(L" (%d)", longValue); } } if (0 != cidMsg) { WCHAR const *pwszComma = myLoadResourceString(IDS_SEPARATOR); // ", "
wprintf(L" -- "); for (i = 0; i < cidMsg; i++) { wprintf( L"%ws%ws", 0 == i? L"" : pwszComma, myLoadResourceString(aidMsg[i])); } } if (0 == LSTRCMPIS(pwszColumnName, wszPROPEXTFLAGS)) { wprintf(L" -- %ws", cuwszFromExtFlags(longValue)); } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPCERTIFICATEISSUERNAMEID) || 0 == LSTRCMPIS(pwszColumnName, wszPROPCRLNAMEID)) { cuPrintPossibleObjectIdName(TEXT(szOID_CERTSRV_CA_VERSION)); wprintf( L" %u.%u", CANAMEIDTOICERT(longValue), CANAMEIDTOIKEY(longValue)); } wprintf(wszNewLine); if (fDisplayFlags) { cuRegPrintDwordValue(FALSE, pwszColumnName, pwszColumnName, longValue); } if (NULL != pwszError) { LocalFree(const_cast<WCHAR *>(pwszError)); } }
HRESULT GetBinaryColumnFormat( IN WCHAR const *pwszColumnName, OUT LONG *pFormat) { LONG Format = CV_OUT_BINARY;
if (0 == LSTRCMPIS( pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTRAWREQUEST)) { Format = CV_OUT_BASE64REQUESTHEADER; } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPRAWCERTIFICATE) || 0 == LSTRCMPIS( pwszColumnName, wszPROPREQUESTDOT wszPROPREQUESTRAWOLDCERTIFICATE) || 0 == LSTRCMPIS(pwszColumnName, wszPROPCERTIFICATERAWSMIMECAPABILITIES)) { Format = CV_OUT_BASE64HEADER; } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPCRLRAWCRL)) { Format = CV_OUT_BASE64X509CRLHEADER; } else if (0 == LSTRCMPIS(pwszColumnName, wszPROPCERTIFICATERAWPUBLICKEY)) { Format = CV_OUT_HEXADDR; } else { Format = CV_OUT_HEXASCIIADDR; } *pFormat = Format; return(S_OK); }
VOID DumpBinaryValue( IN WCHAR const *pwszColName, OPTIONAL IN WCHAR const *pwszObjId, IN LONG Format, IN BYTE const *pb, IN DWORD cb, OPTIONAL IN WCHAR const *pwszStringValue) { wprintf(wszNewLine); if (NULL == pwszObjId || 0 != LSTRCMPIS(pwszColName, wszPROPEXTRAWVALUE) || !cuDumpFormattedExtension(pwszObjId, pb, cb) || g_fVerbose) { if (NULL != pwszStringValue) { cuPrintCRLFString(NULL, pwszStringValue); wprintf(wszNewLine); } else { DumpHex( DH_NOADDRESS | (CV_OUT_HEX == Format? DH_NOASCIIHEX : 0), pb, cb); } } if (g_fVerbose && (CV_OUT_BASE64HEADER == Format || CV_OUT_BASE64REQUESTHEADER == Format || CV_OUT_BASE64X509CRLHEADER == Format)) { BOOL fVerboseOld = g_fVerbose;
if (g_fVerbose) { g_fVerbose--; } cuDumpAsnBinary(pb, cb, MAXDWORD); g_fVerbose = fVerboseOld; wprintf(wszNewLine); } }
BOOL ShouldDisplay( IN WCHAR const *pwszName, IN BOOL fDisplay, IN WCHAR const * const *apwsz) { if (!fDisplay) { WCHAR const * const *ppwsz;
for (ppwsz = apwsz; NULL != *ppwsz; ppwsz++) { if (0 == mylstrcmpiL(pwszName, *ppwsz)) { fDisplay = TRUE; break; } } } return(fDisplay); }
typedef struct _DBSTATS { DWORD cTotal; DWORD cbTotal; DWORD cbMax; } DBSTATS;
VOID UpdateStats( IN OUT DBSTATS *pstats, IN DWORD cbProp) { if (0 != cbProp) { pstats->cTotal++; pstats->cbTotal += cbProp; if (pstats->cbMax < cbProp) { pstats->cbMax = cbProp; } //wprintf(L"c=%u cb=%x(%x)\n", pstats->cTotal, pstats->cbTotal, cbProp);
} }
VOID CombineStats( IN OUT DBSTATS *pstats, IN DBSTATS const *pstats2) { pstats->cTotal += pstats2->cTotal; pstats->cbTotal += pstats2->cbTotal; if (pstats->cbMax < pstats2->cbMax) { pstats->cbMax = pstats2->cbMax; } }
VOID DumpStats( IN DBSTATS const *pstats, IN DWORD idStats) { wprintf( myLoadResourceString(IDS_VIEW_STATS), // "%u %ws, Total Size = %u, Max Size = %u, Ave Size = %u",
pstats->cTotal, myLoadResourceString(idStats), pstats->cbTotal, pstats->cbMax, 0 != pstats->cTotal? pstats->cbTotal / pstats->cTotal : 0); wprintf(wszNewLine); }
VOID DumpViewStats( IN DWORD cRowTotal, IN DBSTATS const *pstatsRowProperties, IN DBSTATS const *pstatsAttributes, IN DBSTATS const *pstatsExtensions) { if (!g_fCryptSilent) { DBSTATS statsSum;
wprintf(wszNewLine); wprintf( myLoadResourceString(IDS_VIEW_ROWS), // "%u Rows"
cRowTotal); wprintf(wszNewLine);
DumpStats(pstatsRowProperties, IDS_VIEW_ROWPROPERTIES); // "Row Properties"
DumpStats(pstatsAttributes, IDS_VIEW_ATTRIBUTES); // "Request Attributes"
DumpStats(pstatsExtensions, IDS_VIEW_EXTENSIONS); // "Certificate Extensions"
statsSum = *pstatsRowProperties; CombineStats(&statsSum, pstatsAttributes); CombineStats(&statsSum, pstatsExtensions);
DumpStats(&statsSum, IDS_VIEW_TOTALFIELDS); // "Total Fields"
} }
#define VDQ_NONE 0
#define VDQ_SCHEMA 1
#define VDQ_QUEUE 2
#define VDQ_LOG 3
#define VDQ_LOGFAIL 4
#define VDQ_REVOKED 5
HRESULT verbViewDump( IN WCHAR const *pwszOption, IN WCHAR const *pwszTable, IN WCHAR const *pwszSkipCounts, IN WCHAR const *pwszField3, IN WCHAR const *pwszField4) { HRESULT hr; BOOL fSchema = g_wszSchema == pwszOption; DWORD vdq = VDQ_NONE; LONG cvColDefault = 0; DISPATCHINTERFACE diView; DISPATCHINTERFACE diViewColumn; DISPATCHINTERFACE diViewRow; DISPATCHINTERFACE diViewAttribute; DISPATCHINTERFACE diViewExtension; BOOL fMustRelease = FALSE; BOOL fMustReleaseColumn = FALSE; BOOL fMustReleaseAttribute = FALSE; BOOL fMustReleaseExtension = FALSE; BOOL fMustReleaseRow = FALSE; LONG i; LONG cColFull; LONG cColOut; COLINFO *aColInfo = NULL; LONG iRow; LONG RowIndex; LONG iCol; LONG ColIndex; LONG iAttribute; LONG AttributeIndex; LONG iExtension; LONG ExtensionIndex; BSTR strName = NULL; BSTR strObjId = NULL; BSTR strValue = NULL; BSTR strValueBinary = NULL; WCHAR const *pwszExtensionFormat; WCHAR **apwszRestrictions = NULL; WCHAR **apwszColumns = NULL; WCHAR **apwszAttributes = NULL; WCHAR **apwszExtensions = NULL; WCHAR **ppwsz; BOOL fOneRow = FALSE; LONG lSkip = 0; BOOL fAllColumns; BOOL fAllAttributes = FALSE; BOOL fAllExtensions = FALSE; BOOL fSkip; DWORD cbProp; DWORD cRowTotal = 0; DBSTATS statsRowProperties; DBSTATS statsAttributes; DBSTATS statsExtensions; DWORD cvrcTable = CVRC_TABLE_REQCERT; WCHAR const *pwszDefaultRestriction = NULL;
if (NULL != pwszTable) { if (0 == mylstrcmpiS(pwszTable, g_wszSchema)) { fSchema = TRUE; } else if (0 == LSTRCMPIS(pwszTable, wszQUEUE)) { vdq = VDQ_QUEUE; pwszDefaultRestriction = wszCOLONQUEUE; cvColDefault = CV_COLUMN_QUEUE_DEFAULT; } else if (0 == LSTRCMPIS(pwszTable, wszLOG)) { vdq = VDQ_LOG; pwszDefaultRestriction = wszCOLONLOG; cvColDefault = CV_COLUMN_LOG_DEFAULT; } else if (0 == LSTRCMPIS(pwszTable, wszLOGFAIL)) { vdq = VDQ_LOGFAIL; pwszDefaultRestriction = wszCOLONLOGFAIL; cvColDefault = CV_COLUMN_LOG_DEFAULT; } else if (0 == LSTRCMPIS(pwszTable, wszREVOKED)) { vdq = VDQ_REVOKED; pwszDefaultRestriction = wszCOLONREVOKED; cvColDefault = CV_COLUMN_LOG_REVOKED_DEFAULT; } else if (0 == LSTRCMPIS(pwszTable, g_wszExt)) { cvrcTable = CVRC_TABLE_EXTENSIONS; //cvColDefault = CV_COLUMN_EXTENSION_DEFAULT;
} else if (0 == LSTRCMPIS(pwszTable, g_wszAttrib)) { cvrcTable = CVRC_TABLE_ATTRIBUTES; //cvColDefault = CV_COLUMN_ATTRIBUTE_DEFAULT;
} else if (0 == LSTRCMPIS(pwszTable, g_wszCRL)) { cvrcTable = CVRC_TABLE_CRL; //cvColDefault = CV_COLUMN_CRL_DEFAULT;
} else if (NULL == pwszSkipCounts && iswdigit(*pwszTable)) { pwszSkipCounts = pwszTable; } else { hr = E_INVALIDARG; _JumpError(hr, error, "bad view/table name"); } }
if (NULL != pwszSkipCounts) { hr = ParseSkipCounts(pwszSkipCounts); _JumpIfError(hr, error, "ParseSkipCounts"); }
hr = View_Init(g_DispatchFlags, &diView); _JumpIfError(hr, error, "View_Init");
fMustRelease = TRUE;
hr = View_OpenConnection(&diView, g_pwszConfig); _JumpIfError(hr, error, "View_OpenConnection");
if (CVRC_TABLE_REQCERT != cvrcTable) { hr = View2_SetTable(&diView, cvrcTable); _JumpIfError(hr, error, "View2_SetTable"); }
if (NULL != g_pwszRestrict) { hr = ParseViewRestrictions(g_pwszRestrict, &apwszRestrictions); _JumpIfError(hr, error, "ParseViewRestrictions");
if (NULL == apwszRestrictions) { hr = E_POINTER; // would have AV'd anyway
_JumpError(hr, error, "apwszRestrictions==NULL"); }
for (ppwsz = apwszRestrictions; NULL != *ppwsz; ppwsz++) { BOOL f; LONG l;
hr = SetViewRestriction(&diView, *ppwsz, &f, &l); _JumpIfErrorStr(hr, error, "SetViewRestriction", *ppwsz);
if (f) { fOneRow = TRUE; lSkip = l; } } } else if (NULL != pwszDefaultRestriction) { hr = SetViewRestriction(&diView, pwszDefaultRestriction, &fOneRow, &lSkip); _JumpIfError(hr, error, "SetViewRestriction"); }
// If not a special default view, and no output columns were specified
// for the requests+certs table, include all attributes and extensions.
if (NULL == pwszDefaultRestriction && NULL == g_pwszOut && CVRC_TABLE_REQCERT == cvrcTable) { fAllAttributes = TRUE; fAllExtensions = TRUE; }
hr = View_GetColumnCount(&diView, CVRC_COLUMN_SCHEMA, &cColFull); _JumpIfError(hr, error, "View_GetColumnCount");
if (NULL != g_pwszOut) { hr = ParseViewColumns( g_pwszOut, NULL, NULL, &apwszColumns, &fAllColumns); _JumpIfError(hr, error, "ParseViewColumns");
hr = ParseViewColumns( g_pwszOut, g_wszAttrib, g_apwszAllowedPrefixes, &apwszAttributes, &fAllAttributes); _JumpIfError(hr, error, "ParseViewColumns");
hr = ParseViewColumns( g_pwszOut, g_wszExt, NULL, &apwszExtensions, &fAllExtensions); _JumpIfError(hr, error, "ParseViewColumns");
if (NULL == apwszColumns) { if (!g_fReverse) { hr = View_SetResultColumnCount(&diView, 0); _JumpIfError(hr, error, "View_SetResultColumnCount"); } } else { for (ppwsz = apwszColumns; NULL != *ppwsz; ppwsz++) ;
hr = View_SetResultColumnCount( &diView, SAFE_SUBTRACT_POINTERS(ppwsz, apwszColumns)); _JumpIfError(hr, error, "View_SetResultColumnCount");
for (ppwsz = apwszColumns; NULL != *ppwsz; ppwsz++) { hr = View_GetColumnIndex( &diView, CVRC_COLUMN_SCHEMA, *ppwsz, &ColIndex); _JumpIfErrorStr(hr, error, "View_GetColumnIndex", *ppwsz);
hr = View_SetResultColumn(&diView, ColIndex); _JumpIfError(hr, error, "View_SetResultColumn"); } } } else if (NULL == pwszDefaultRestriction) { if (g_fReverse) { hr = View_SetResultColumnCount(&diView, cColFull + 1); _JumpIfError(hr, error, "View_SetResultColumnCount");
hr = View_SetResultColumn(&diView, 0); _JumpIfError(hr, error, "View_SetResultColumn(0)");
for (i = cColFull; i > 0; i--) { hr = View_SetResultColumn(&diView, i - 1); _JumpIfError(hr, error, "View_SetResultColumn"); } } else { hr = View_SetResultColumnCount(&diView, cColFull); _JumpIfError(hr, error, "View_SetResultColumnCount");
for (i = 0; i < cColFull; i++) { hr = View_SetResultColumn(&diView, i); _JumpIfError(hr, error, "View_SetResultColumn"); } } } else { // Use the default set of columns for the specified special view.
CSASSERT(0 > cvColDefault);
hr = View_SetResultColumnCount(&diView, cvColDefault); _JumpIfError(hr, error, "View_SetResultColumnCount"); }
hr = View_OpenView(&diView, &diViewRow); _JumpIfError(hr, error, "View_OpenView"); fMustReleaseRow = TRUE;
hr = View_GetColumnCount(&diView, CVRC_COLUMN_RESULT, &cColOut); _JumpIfError(hr, error, "View_GetColumnCount");
aColInfo = (COLINFO *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, cColOut * sizeof(aColInfo[0])); if (NULL == aColInfo) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "no memory for column info array"); }
if (fSchema) { hr = DisplaySchema(&diView, cColFull, NULL, FALSE); _JumpIfError(hr, error, "DisplaySchema");
goto error; }
if (0 != cColOut) { hr = DisplaySchema(&diView, cColOut, aColInfo, TRUE); _JumpIfError(hr, error, "DisplaySchema"); }
ZeroMemory(&statsRowProperties, sizeof(statsRowProperties)); ZeroMemory(&statsAttributes, sizeof(statsAttributes)); ZeroMemory(&statsExtensions, sizeof(statsExtensions));
hr = ViewRow_Skip(&diViewRow, lSkip); _JumpIfError(hr, error, "ViewRow_Skip");
for (iRow = 1; ; iRow++) { BOOL fRowPrinted; BOOL fHeaderPrinted; BOOL fExtraNewLine; LONG cskip;
if (NULL != strObjId) { SysFreeString(strObjId); strObjId = NULL; } cskip = GetSkip(TRUE); switch (cskip) { case 0: break;
case 101: hr = ViewRow_Reset(&diViewRow); _JumpIfError(hr, error, "ViewRow_Reset");
iRow = 1; break;
case 102: { DISPATCHINTERFACE diViewRowClone;
hr = ViewRow_Clone(&diViewRow, &diViewRowClone); _JumpIfError(hr, error, "ViewRow_Clone");
ViewRow_Release(&diViewRow); diViewRow = diViewRowClone; // structure assignment
goto done; }
case 103: goto done;
default: hr = ViewRow_Skip(&diViewRow, cskip); _JumpIfError(hr, error, "ViewRow_Skip");
iRow += cskip; }
hr = ViewRow_Next(&diViewRow, &RowIndex); if (S_FALSE == hr || (S_OK == hr && -1 == RowIndex)) { LONG MaxIndex;
hr = ViewRow_GetMaxIndex(&diViewRow, &MaxIndex); _JumpIfError(hr, error, "ViewRow_GetMaxIndex");
if (!g_fCryptSilent) { wprintf( L"\n%ws: %u\n", myLoadResourceString(IDS_MAXINDEX), // "Maximum Row Index"
MaxIndex); } if (101 == GetSkip(FALSE)) { continue; } break; } _JumpIfError(hr, error, "ViewRow_Next"); CSASSERT(RowIndex == iRow + lSkip);
cRowTotal++; fRowPrinted = FALSE; fExtraNewLine = FALSE;
if (fMustReleaseColumn) { ViewColumn_Release(&diViewColumn); fMustReleaseColumn = FALSE; }
hr = ViewRow_EnumCertViewColumn(&diViewRow, &diViewColumn); _JumpIfError(hr, error, "ViewRow_EnumCertViewColumn");
fMustReleaseColumn = TRUE;
for (iCol = 0; ; iCol++) { LONG Format; LONG longValue; DATE dateValue; VOID *pretval;
if (NULL != strValue) { SysFreeString(strValue); strValue = NULL; } if (NULL != strValueBinary) { SysFreeString(strValueBinary); strValueBinary = NULL; } hr = ViewColumn_Next(&diViewColumn, &ColIndex); if (S_FALSE == hr || (S_OK == hr && -1 == ColIndex)) { break; } _JumpIfError(hr, error, "ViewColumn_Next"); CSASSERT(ColIndex == iCol);
hr = ViewColumn_GetType(&diViewColumn, &i); _JumpIfError(hr, error, "GetType");
CSASSERT(i == aColInfo[iCol].type);
PrintRowIndex(iRow, &fRowPrinted); fExtraNewLine = TRUE;
wprintf(L" %ws:", aColInfo[iCol].strColDisplay);
Format = CV_OUT_BINARY; switch (aColInfo[iCol].type) { case PROPTYPE_LONG: pretval = &longValue; break;
case PROPTYPE_DATE: pretval = &dateValue; break;
case PROPTYPE_STRING: pretval = &strValue; break;
case PROPTYPE_BINARY: pretval = &strValue; hr = GetBinaryColumnFormat(aColInfo[iCol].strCol, &Format); _JumpIfError(hr, error, "GetBinaryColumnFormat");
break;
default: hr = E_FAIL; _JumpError(hr, error, "bad proptype"); } hr = ViewColumn_GetValue( &diViewColumn, Format, aColInfo[iCol].type, pretval); if (S_OK != hr) { wprintf(L" "); wprintf(myLoadResourceString(IDS_PROP_EMPTY)); // "EMPTY"
wprintf(wszNewLine); _PrintIfErrorStr2( hr, "ViewColumn_GetValue", aColInfo[iCol].strColDisplay, CERTSRV_E_PROPERTY_EMPTY); } else {
cbProp = 0; switch (aColInfo[iCol].type) { case PROPTYPE_LONG: DumpLongValue(longValue, aColInfo[iCol].strCol); cbProp = sizeof(LONG); break;
case PROPTYPE_DATE: cuDumpDate(&dateValue); cbProp = sizeof(DATE); break;
case PROPTYPE_BINARY: if (CV_OUT_BINARY != Format) { hr = ViewColumn_GetValue( &diViewColumn, CV_OUT_BINARY, PROPTYPE_BINARY, &strValueBinary); _JumpIfError(hr, error, "ViewColumn_GetValue"); } else { strValueBinary = strValue; strValue = NULL; } cbProp = SysStringByteLen(strValueBinary); DumpBinaryValue( aColInfo[iCol].strCol, strObjId, Format, (BYTE *) strValueBinary, cbProp, strValue); break;
case PROPTYPE_STRING: wprintf(L" \""); cuPrintCRLFString(NULL, strValue); wprintf(L"\""); cuPrintPossibleObjectIdName(strValue); wprintf(wszNewLine); if (g_fVerbose) { DumpHex( 0, (BYTE *) strValue, SysStringByteLen(strValue)); wprintf(wszNewLine); } cbProp = wcslen(strValue) * sizeof(WCHAR); if (0 == LSTRCMPIS( aColInfo[iCol].strCol, wszPROPEXTNAME)) { if (NULL != strObjId) { SysFreeString(strObjId); } strObjId = SysAllocString(strValue); } break; } UpdateStats(&statsRowProperties, cbProp); } }
fSkip = TRUE; if (fAllAttributes || NULL != apwszAttributes) { // Enumerate Request Attributes
hr = ViewRow_EnumCertViewAttribute(&diViewRow, 0, &diViewAttribute); if (CERTSRV_E_PROPERTY_EMPTY == hr) { _PrintError2(hr, "ViewRow_EnumCertViewAttribute", hr); } else { _JumpIfError(hr, error, "ViewRow_EnumCertViewAttribute");
fSkip = FALSE; fMustReleaseAttribute = TRUE; } }
if (!fSkip) { fHeaderPrinted = FALSE;
for (iAttribute = 0; ; iAttribute++) { hr = ViewAttribute_Next(&diViewAttribute, &AttributeIndex); if (S_FALSE == hr || (S_OK == hr && -1 == AttributeIndex)) { break; } _JumpIfError(hr, error, "ViewAttribute_Next"); CSASSERT(AttributeIndex == iAttribute);
hr = ViewAttribute_GetName(&diViewAttribute, &strName); _JumpIfError(hr, error, "GetName");
if (ShouldDisplay(strName, fAllAttributes, apwszAttributes)) { if (!fHeaderPrinted) { PrintRowIndex(iRow, &fRowPrinted); if (fExtraNewLine) { wprintf(wszNewLine); } wprintf( L" %ws\n", myLoadResourceString(IDS_REQUEST_ATTRIBUTES)); // "Request Attributes:"
fHeaderPrinted = TRUE; fExtraNewLine = TRUE; }
if (NULL != strValue) { SysFreeString(strValue); strValue = NULL; } hr = ViewAttribute_GetValue(&diViewAttribute, &strValue); _JumpIfError(hr, error, "GetValue");
wprintf(L" %ws: \"%ws\"\n", strName, strValue);
UpdateStats( &statsAttributes, (wcslen(strName) + wcslen(strValue)) * sizeof(WCHAR) + sizeof(LONG)); // for RequestId
} } ViewAttribute_Release(&diViewAttribute); fMustReleaseAttribute = FALSE; }
fSkip = TRUE; if (fAllExtensions || NULL != apwszExtensions) { // Enumerate Certificate Extensions
hr = ViewRow_EnumCertViewExtension(&diViewRow, 0, &diViewExtension); if (CERTSRV_E_PROPERTY_EMPTY == hr) { _PrintError2(hr, "ViewRow_EnumCertViewExtension", hr); } else { _JumpIfError(hr, error, "ViewRow_EnumCertViewExtension");
fSkip = FALSE; fMustReleaseExtension = TRUE; } }
if (!fSkip) { fHeaderPrinted = FALSE;
pwszExtensionFormat = myLoadResourceString(IDS_FORMAT_EXTENSION); // "%ws: Flags = %x%ws, Length = %x"
for (iExtension = 0; ; iExtension++) { LONG ExtFlags;
hr = ViewExtension_Next(&diViewExtension, &ExtensionIndex); if (S_FALSE == hr || (S_OK == hr && -1 == ExtensionIndex)) { break; } _JumpIfError(hr, error, "ViewExtension_Next"); CSASSERT(ExtensionIndex == iExtension);
hr = ViewExtension_GetName(&diViewExtension, &strName); _JumpIfError(hr, error, "GetName");
if (ShouldDisplay(strName, fAllExtensions, apwszExtensions)) { DWORD cbValue;
if (!fHeaderPrinted) { PrintRowIndex(iRow, &fRowPrinted); if (fExtraNewLine) { wprintf(wszNewLine); } wprintf( L" %ws\n", myLoadResourceString(IDS_CERTIFICATE_EXTENSIONS)); // "Certificate Extensions:"
fHeaderPrinted = TRUE; }
hr = ViewExtension_GetFlags(&diViewExtension, &ExtFlags); _JumpIfError(hr, error, "GetFlags");
if (NULL != strValue) { SysFreeString(strValue); strValue = NULL; } hr = ViewExtension_GetValue( &diViewExtension, PROPTYPE_BINARY, CV_OUT_BINARY, &strValue); if (CERTSRV_E_PROPERTY_EMPTY != hr) { _JumpIfError(hr, error, "GetValue"); } cbValue = NULL == strValue? 0 : SysStringByteLen(strValue);
wprintf(g_wszPad4); wprintf( pwszExtensionFormat, strName, ExtFlags, cuwszFromExtFlags(ExtFlags), cbValue); wprintf(wszNewLine);
if (0 == cbValue) { wprintf(g_wszPad4); wprintf(myLoadResourceString(IDS_PROP_EMPTY)); // "EMPTY"
wprintf(wszNewLine); } else { if (!cuDumpFormattedExtension( strName, (BYTE const *) strValue, SysStringByteLen(strValue)) || g_fVerbose) { wprintf(wszNewLine); DumpHex( DH_NOTABPREFIX | 4, (BYTE const *) strValue, SysStringByteLen(strValue)); } } wprintf(wszNewLine);
UpdateStats( &statsExtensions, wcslen(strName) * sizeof(WCHAR) + cbValue + // for ext
sizeof(LONG) + // for RequestId
sizeof(ExtFlags)); // for ExtensionFlags
} } ViewExtension_Release(&diViewExtension); fMustReleaseExtension = FALSE; } if (fOneRow) { break; } }
done: DumpViewStats( cRowTotal, &statsRowProperties, &statsAttributes, &statsExtensions); hr = S_OK;
error: if (NULL != aColInfo) { for (i = 0; i < cColOut; i++) { if (NULL != aColInfo[i].strCol) { SysFreeString(aColInfo[i].strCol); } if (NULL != aColInfo[i].strColDisplay) { SysFreeString(aColInfo[i].strColDisplay); } } LocalFree(aColInfo); }
cuFreeStringArray(apwszRestrictions); cuFreeStringArray(apwszColumns); cuFreeStringArray(apwszAttributes); cuFreeStringArray(apwszExtensions);
if (NULL != strObjId) { SysFreeString(strObjId); } if (NULL != strName) { SysFreeString(strName); } if (NULL != strValue) { SysFreeString(strValue); } if (NULL != strValueBinary) { SysFreeString(strValueBinary); } if (fMustReleaseAttribute) { ViewAttribute_Release(&diViewAttribute); } if (fMustReleaseExtension) { ViewExtension_Release(&diViewExtension); } if (fMustReleaseColumn) { ViewColumn_Release(&diViewColumn); } if (fMustReleaseRow) { ViewRow_Release(&diViewRow); } if (fMustRelease) { View_Release(&diView); } return(hr); }
HRESULT DBShutDown( IN ICertDB *pdb) { HRESULT hr;
CSASSERT(NULL != pdb); hr = pdb->ShutDown(0); pdb->Release(); return(hr); }
// Control-C handler to shut down DB
BOOL cuDBAbortShutDown( IN DWORD dwCtrlType) { HRESULT hr; ICertDB *pdb;
EnterCriticalSection(&g_DBCriticalSection); pdb = g_pdb; g_pdb = NULL; if (NULL != pdb) { DBShutDown(pdb); SetConsoleCtrlHandler(cuDBAbortShutDown, FALSE); } LeaveCriticalSection(&g_DBCriticalSection); return(TRUE); }
HRESULT DBOpen( IN WCHAR const *pwszAuthority, IN BOOL fReadOnly, OUT ICertDB **ppdb) { HRESULT hr = S_OK; DWORD cb; DWORD i; HKEY hkey = NULL; WCHAR awszDatabase[MAX_PATH]; WCHAR awszLogDir[MAX_PATH]; WCHAR awszSystemDir[MAX_PATH]; WCHAR awszTempDir[MAX_PATH]; DWORD DBFlags;
WCHAR *pawszDirBuf[4] = { awszDatabase, awszLogDir, awszSystemDir, awszTempDir };
WCHAR *pawszRegNames[4] = { wszREGDBDIRECTORY, wszREGDBLOGDIRECTORY, wszREGDBSYSDIRECTORY, wszREGDBTEMPDIRECTORY };
// get info from registry
hr = RegOpenKey(HKEY_LOCAL_MACHINE, wszREGKEYCONFIGPATH, &hkey); _JumpIfError(hr, error, "RegOpenKey(CAName)");
for (i = 0; i < 4; i++) { cb = sizeof(WCHAR) * MAX_PATH; hr = RegQueryValueEx( hkey, pawszRegNames[i], NULL, NULL, (BYTE *) pawszDirBuf[i], &cb); _JumpIfError(hr, error, "RegQueryValueEx(DB*Dir)"); } if (wcslen(awszDatabase) + 1 + wcslen(pwszAuthority) + wcslen(wszDBFILENAMEEXT) >= ARRAYSIZE(awszDatabase)) { hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); _JumpErrorStr(hr, error, "awszDatabase", pwszAuthority); } wcscat(awszDatabase, L"\\"); wcscat(awszDatabase, pwszAuthority); wcscat(awszDatabase, wszDBFILENAMEEXT);
cb = sizeof(DBFlags); hr = RegQueryValueEx( hkey, wszREGDBFLAGS, NULL, NULL, (BYTE *) &DBFlags, &cb); if (S_OK != hr) { _PrintErrorStr(hr, "RegQueryValueEx", wszREGDBFLAGS); DBFlags = DBFLAGS_DEFAULT; } DBFlags &= ~DBFLAGS_READONLY;
wprintf( myLoadResourceString(IDS_FORMAT_OPENING_DB), // "Opening Database %ws"
awszDatabase); wprintf(wszNewLine);
hr = CoCreateInstance( CLSID_CCertDB, NULL, // pUnkOuter
CLSCTX_INPROC_SERVER, IID_ICertDB, (VOID **) ppdb); _JumpIfError(hr, error, "CoCreateInstance(ICertDB)");
if (fReadOnly) { DBFlags |= DBFLAGS_READONLY; } else if (g_fForce) { DBFlags |= DBFLAGS_CREATEIFNEEDED; } hr = (*ppdb)->Open( DBFlags, 2, // cSession
L"certutil.exe", // pwszEventSource
awszDatabase, // pwszDBFile
awszLogDir, // pwszLogDir
awszSystemDir, // pwszSystemDir
awszTempDir); // pwszTempDir
_JumpIfError(hr, error, "ICertDB::Open");
error: if (S_OK != hr) { if (NULL != *ppdb) { (*ppdb)->Release(); *ppdb = NULL; } } if (NULL != hkey) { RegCloseKey(hkey); } return(hr); }
HRESULT cuDBOpen( IN WCHAR const *pwszAuthority, IN BOOL fReadOnly, OUT ICertDB **ppdb) { HRESULT hr; WCHAR *pwszSanitizedCA = NULL;
hr = mySanitizeName(pwszAuthority, &pwszSanitizedCA); _JumpIfError(hr, error, "mySanitizeName");
SetConsoleCtrlHandler(NULL, TRUE); // ignore CTL-C during cuDBOpen
hr = DBOpen(pwszSanitizedCA, fReadOnly, ppdb); if (S_OK != hr) { cuPrintError(IDS_DB_OPEN_FAILURE, hr); if (myJetHResult(JET_errFileAccessDenied) == hr) { wprintf(myLoadResourceString(IDS_DB_ACCESS_STOP_SERVER)); wprintf(wszNewLine); } else { wprintf(myLoadResourceString(IDS_DB_ACCESS_INSTALL_SERVER)); // "Ensure the server is correctly installed and retry."
wprintf(wszNewLine); } _JumpError(hr, error, "DBOpen"); } g_pdb = *ppdb; SetConsoleCtrlHandler(cuDBAbortShutDown, TRUE); SetConsoleCtrlHandler(NULL, FALSE); // allow CTL-C
error: if (NULL != pwszSanitizedCA) { LocalFree(pwszSanitizedCA); } return(hr); }
CERTDBCOLUMN g_adcRequests[50]; DWORD g_cdcRequests;
CERTDBCOLUMN g_adcCertificates[50]; DWORD g_cdcCertificates;
HRESULT DBLoadSchema( IN ICertDB *pdb) { HRESULT hr; IEnumCERTDBCOLUMN *penum = NULL; CERTDBCOLUMN acol[2]; DWORD ccol; DWORD i; CERTDBCOLUMN *pdc; CERTDBCOLUMN const *pdcEnd; CERTDBCOLUMN *pdcReq = g_adcRequests; CERTDBCOLUMN *pdcCert = g_adcCertificates; DWORD *pcdc;
hr = pdb->EnumCertDBColumn(CVRC_TABLE_REQCERT, &penum); _JumpIfError(hr, error, "EnumCertDBColumn");
while (TRUE) { hr = penum->Next(ARRAYSIZE(acol), acol, &ccol); if (S_FALSE != hr) { _JumpIfError(hr, error, "Next"); } for (i = 0; i < ccol; i++) { if (0 == _wcsnicmp( wszPROPREQUESTDOT, acol[i].pwszName, WSZARRAYSIZE(wszPROPREQUESTDOT))) { pdc = pdcReq++; pcdc = &g_cdcRequests; pdcEnd = &g_adcRequests[ARRAYSIZE(g_adcRequests) - 1]; } else { pdc = pdcCert++; pcdc = &g_cdcCertificates; pdcEnd = &g_adcCertificates[ARRAYSIZE(g_adcCertificates) - 1]; } if (pdc >= pdcEnd) { //wprintf(L"Property Name Table overflow\n");
hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); _JumpError(hr, error, "Property Name Table overflow"); } *pdc = acol[i]; (*pcdc)++; } if (S_FALSE == hr) { break; } } hr = S_OK;
error: if (NULL != penum) { penum->Release(); } return(hr); }
HRESULT DBLookupColumnInfo1( IN CERTDBCOLUMN const *pdc, IN DWORD ColIndex, OUT CERTDBCOLUMN const **ppdc) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
*ppdc = NULL; for ( ; NULL != pdc->pwszName; pdc++) { if (pdc->Index == ColIndex) { *ppdc = pdc; hr = S_OK; break; } }
//error:
return(hr); }
HRESULT DBLookupColumnInfo( IN DWORD ColIndex, OUT CERTDBCOLUMN const **ppdc, OUT DWORD *pdwTable) { HRESULT hr;
hr = DBLookupColumnInfo1( g_adcRequests, ColIndex, ppdc); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { _JumpIfError(hr, error, "DBLookupColumnInfo1");
*pdwTable = PROPTABLE_REQUEST; } else { hr = DBLookupColumnInfo1( g_adcCertificates, ColIndex, ppdc); *pdwTable = PROPTABLE_CERTIFICATE; } _JumpIfError(hr, error, "DBLookupColumnInfo1");
error: return(hr); }
HRESULT DBDumpColumn( IN CERTDBCOLUMN const *pdc) { HRESULT hr;
cuPrintSchemaEntry( pdc->pwszName, pdc->pwszDisplayName, pdc->Type, pdc->cbMax); hr = S_OK;
//error:
return(hr); }
HRESULT DBDumpSchema1( IN CERTDBCOLUMN const *pdc) { HRESULT hr; CERTDBCOLUMN const *pdcEnd;
for ( ; NULL != pdc->pwszName; pdc++) { hr = DBDumpColumn(pdc); _JumpIfError(hr, error, "DBDumpColumn"); } hr = S_OK;
error: return(hr); }
HRESULT DBDumpSchema( IN ICertDB *pdb, OPTIONAL IN DWORD const *pcol, IN DWORD ccol) { HRESULT hr; DWORD acol[100]; DWORD i;
if (1 == ccol && NULL != pcol && 0 > (LONG) *pcol) { hr = pdb->GetDefaultColumnSet(*pcol, ARRAYSIZE(acol), acol, &ccol); _JumpIfError(hr, error, "GetDefaultColumnSet");
if (ARRAYSIZE(acol) == ccol) { hr = HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW); _JumpError(hr, error, "GetDefaultColumnSet"); } pcol = acol; }
wprintf(myLoadResourceString(IDS_SCHEMA_COLON)); // "Schema:"
wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_SCHEMA_COLUMNHEADERS)); // "Name..Type..."
wprintf(wszNewLine); wprintf(myLoadResourceString(IDS_SCHEMA_COLUMNUNDERLINE)); // "____...____"
wprintf(wszNewLine);
if (NULL != pcol) { for (i = 0; i < ccol; i++) { CERTDBCOLUMN const *pdc; DWORD dwTable;
hr = DBLookupColumnInfo(pcol[i], &pdc, &dwTable); _JumpIfError(hr, error, "DBLookupColumnInfo");
hr = DBDumpColumn(pdc); _JumpIfError(hr, error, "DBDumpColumn"); } } else { hr = DBDumpSchema1(g_adcRequests); _JumpIfError(hr, error, "DBDumpSchema1");
hr = DBDumpSchema1(g_adcCertificates); _JumpIfError(hr, error, "DBDumpSchema1"); } hr = S_OK;
error: return(hr); }
VOID DBFreeSchema1( IN CERTDBCOLUMN const *pdc, IN DWORD cdc) { CERTDBCOLUMN const *pdcEnd;
for (pdcEnd = &pdc[cdc]; pdc < pdcEnd; pdc++) { if (NULL != pdc->pwszName) { CoTaskMemFree(pdc->pwszName); } if (NULL != pdc->pwszDisplayName) { CoTaskMemFree(pdc->pwszDisplayName); } } }
VOID DBFreeSchema() { DBFreeSchema1(g_adcRequests, g_cdcRequests); DBFreeSchema1(g_adcCertificates, g_cdcCertificates); }
HRESULT DBGetColumnInfo1( IN CERTDBCOLUMN const *pdc, IN WCHAR const *pwszColName, OUT WCHAR const **ppwszColNameActual, OUT DWORD *pColIndex, OUT LONG *pColType) { HRESULT hr = HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
*ppwszColNameActual = NULL; for ( ; NULL != pdc->pwszName; pdc++) { if (0 == mylstrcmpiL(pwszColName, pdc->pwszName)) { *ppwszColNameActual = pdc->pwszName; } else if (NULL != pdc->pwszDisplayName && 0 == mylstrcmpiL(pwszColName, pdc->pwszDisplayName)) { *ppwszColNameActual = pdc->pwszDisplayName; } else { continue; } *pColIndex = pdc->Index; *pColType = pdc->Type; hr = S_OK; break; }
//error:
return(hr); }
HRESULT DBGetColumnInfo( IN ICertDB *pdb, IN WCHAR const *pwszColName, OUT WCHAR const **ppwszColNameActual, OUT DWORD *pColIndex, OUT LONG *pColType) { HRESULT hr; WCHAR *pwsz; WCHAR *pwszRequestColName = NULL;
hr = DBGetColumnInfo1( g_adcRequests, pwszColName, ppwszColNameActual, pColIndex, pColType); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { _JumpIfError(hr, error, "DBGetColumnInfo1"); } else { DBGPRINT((DBG_SS_CERTUTILI, "DBGetColumnInfo1(req, %ws) = %x\n", pwszColName, hr)); hr = DBGetColumnInfo1( g_adcCertificates, pwszColName, ppwszColNameActual, pColIndex, pColType); if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) != hr) { _JumpIfError(hr, error, "DBGetColumnInfo1"); } else { DBGPRINT((DBG_SS_CERTUTILI, "DBGetColumnInfo1(cert, %ws) = %x\n", pwszColName, hr)); pwsz = wcschr(pwszColName, L'.'); if (NULL == pwsz) { pwszRequestColName = (WCHAR *) LocalAlloc( LMEM_FIXED, (WSZARRAYSIZE(wszPROPREQUESTDOT) + wcslen(pwszColName) + 1) * sizeof(WCHAR)); if (NULL == pwszRequestColName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } wcscpy(pwszRequestColName, wszPROPREQUESTDOT); wcscat(pwszRequestColName, pwszColName); hr = DBGetColumnInfo1( g_adcRequests, pwszRequestColName, ppwszColNameActual, pColIndex, pColType); DBGPRINT((DBG_SS_CERTUTILI, "DBGetColumnInfo1(req, %ws) = %x\n", pwszRequestColName, hr)); } } _JumpIfError(hr, error, "DBGetColumnInfo1"); }
error: if (NULL != pwszRequestColName) { LocalFree(pwszRequestColName); } return(hr); }
HRESULT cuDBPrintProperty( OPTIONAL IN ICertDBRow *prow, IN DWORD Type, IN WCHAR const *pwszColName, IN WCHAR const *pwszDisplayName, OPTIONAL IN BYTE const *pbValue, IN DWORD cbValue, OUT DWORD *pcbValue) { HRESULT hr; DWORD cb = 0; BYTE *pb = NULL; LONG Format; WCHAR *pwszOut = NULL;
EnterCriticalSection(&g_DBCriticalSection); *pcbValue = 0; if (cuDBIsShutDownInProgress()) { hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); _JumpError(hr, error, "cuDBIsShutDownInProgress"); } wprintf(L" %ws:", pwszDisplayName); if (NULL == pbValue) { cb = 0; hr = prow->GetProperty(pwszColName, Type, NULL, &cb, pb); if (S_OK == hr) { pb = (BYTE *) LocalAlloc(LMEM_FIXED, cb); if (NULL == pb) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } hr = prow->GetProperty(pwszColName, Type, NULL, &cb, pb); } if (S_OK != hr) { wprintf(L" "); if (CERTSRV_E_PROPERTY_EMPTY != hr) { cuPrintError(IDS_FORMAT_ERROR, hr); // "error = %ws"
_JumpError(hr, error, "GetProperty"); } wprintf(myLoadResourceString(IDS_PROP_EMPTY)); // "EMPTY"
wprintf(wszNewLine); cb = 0; } else { pbValue = pb; cbValue = cb; } } if (NULL != pbValue) { switch (PROPTYPE_MASK & Type) { case PROPTYPE_LONG: DumpLongValue(*(DWORD *) pbValue, pwszColName); break;
case PROPTYPE_DATE: hr = cuDumpFileTime(0, NULL, (FILETIME const *) pbValue); _JumpIfError(hr, error, "cuDumpFileTime"); break;
case PROPTYPE_BINARY: hr = GetBinaryColumnFormat(pwszColName, &Format); _JumpIfError(hr, error, "GetBinaryColumnFormat");
if (CV_OUT_BINARY != Format) { CSASSERT(CV_OUT_BASE64HEADER == CRYPT_STRING_BASE64HEADER); CSASSERT(CV_OUT_BASE64 == CRYPT_STRING_BASE64); CSASSERT( CV_OUT_BASE64REQUESTHEADER == CRYPT_STRING_BASE64REQUESTHEADER); CSASSERT(CV_OUT_HEX == CRYPT_STRING_HEX); CSASSERT(CV_OUT_HEXASCII == CRYPT_STRING_HEXASCII); CSASSERT(CV_OUT_HEXADDR == CRYPT_STRING_HEXADDR); CSASSERT(CV_OUT_HEXASCIIADDR == CRYPT_STRING_HEXASCIIADDR);
hr = myCryptBinaryToString( pbValue, cbValue, Format, &pwszOut); _JumpIfError(hr, error, "myCryptBinaryToString"); } DumpBinaryValue( pwszColName, NULL, // pwszObjId
Format, pbValue, cbValue, pwszOut); break;
case PROPTYPE_STRING: wprintf(L" \""); cuPrintCRLFString(NULL, (WCHAR const *) pbValue); wprintf(L"\""); cuPrintPossibleObjectIdName((WCHAR const *) pbValue); wprintf(wszNewLine); break; } } *pcbValue = cb; hr = S_OK;
error: LeaveCriticalSection(&g_DBCriticalSection); if (NULL != pb) { LocalFree(pb); } if (NULL != pwszOut) { LocalFree(pwszOut); } return(hr); }
HRESULT DBPrintRow( IN ICertDB *pdb, IN DWORD iRow, IN DWORD RowId, OPTIONAL IN CERTDBRESULTROW const *pResultRow, OPTIONAL IN DWORD const *acol, IN DWORD ccol, IN BOOL fAllColumns, IN OUT DBSTATS *pstatsRowProperties, OPTIONAL IN WCHAR const * const *apwszAttributes, IN BOOL fAllAttributes, IN OUT DBSTATS *pstatsAttributes, OPTIONAL IN WCHAR const * const *apwszExtensions, IN BOOL fAllExtensions, IN OUT DBSTATS *pstatsExtensions) { HRESULT hr; ICertDBRow *prow = NULL; DWORD ReqId; CERTDBCOLUMN const *pdc; LONG cskip; IEnumCERTDBNAME *penum = NULL; ULONG celtFetched; CERTDBNAME cdbn; BYTE abValue[64+1024]; DWORD dwTable; DWORD i; DWORD cb;
BOOL fRowPrinted = FALSE; BOOL fExtraNewLine = FALSE; BOOL fHeaderPrinted;
cdbn.pwszName = NULL;
hr = pdb->OpenRow( PROPOPEN_READONLY | PROPTABLE_REQCERT, RowId, NULL, &prow); _JumpIfError2(hr, error, "OpenRow", CERTSRV_E_PROPERTY_EMPTY);
prow->GetRowId(&ReqId);
if (NULL != pResultRow) { #if 0
wprintf( L"Row %u: ReqId=%u, ccol=%u, type=%x, index=%x, cb=%u, value=%u\n", iRow, pResultRow->rowid, pResultRow->ccol, pResultRow->acol[0].Type, pResultRow->acol[0].Index, pResultRow->acol[0].cbValue, *(DWORD *) pResultRow->acol[0].pbValue); #endif
for (i = 0; i < pResultRow->ccol; i++) { CERTDBRESULTCOLUMN *pcol = &pResultRow->acol[i];
hr = DBLookupColumnInfo(pcol->Index, &pdc, &dwTable); _JumpIfError(hr, error, "DBLookupColumnInfo");
CSASSERT(pcol->Type == pdc->Type);
PrintRowIndex(iRow, &fRowPrinted); fExtraNewLine = TRUE;
hr = cuDBPrintProperty( prow, dwTable | pcol->Type, pdc->pwszName, pdc->pwszDisplayName, pcol->pbValue, pcol->cbValue, &cb); _JumpIfError(hr, error, "cuDBPrintProperty");
UpdateStats(pstatsRowProperties, cb); } } else if (NULL != acol) { for (i = 0; i < ccol; i++) { PrintRowIndex(iRow, &fRowPrinted); fExtraNewLine = TRUE;
hr = DBLookupColumnInfo(acol[i], &pdc, &dwTable); _JumpIfError(hr, error, "DBLookupColumnInfo");
hr = cuDBPrintProperty( prow, dwTable | pdc->Type, pdc->pwszName, pdc->pwszDisplayName, NULL, // pbValue
0, // cbValue
&cb); _JumpIfError(hr, error, "cuDBPrintProperty");
UpdateStats(pstatsRowProperties, cb); } } else if (fAllColumns) { PrintRowIndex(iRow, &fRowPrinted); fExtraNewLine = TRUE;
for (pdc = g_adcRequests; NULL != pdc->pwszName; pdc++) { hr = cuDBPrintProperty( prow, PROPTABLE_REQUEST | pdc->Type, pdc->pwszName, pdc->pwszDisplayName, NULL, // pbValue
0, // cbValue
&cb); _JumpIfError(hr, error, "cuDBPrintProperty");
UpdateStats(pstatsRowProperties, cb); }
wprintf(wszNewLine); wprintf(L" "); wprintf(myLoadResourceString(IDS_CERT_PROPERTIES)); // "Certificate Properties:"
wprintf(wszNewLine);
for (pdc = g_adcCertificates; NULL != pdc->pwszName; pdc++) { hr = cuDBPrintProperty( prow, PROPTABLE_CERTIFICATE | pdc->Type, pdc->pwszName, pdc->pwszDisplayName, NULL, // pbValue
0, // cbValue
&cb); _JumpIfError(hr, error, "cuDBPrintProperty");
UpdateStats(pstatsRowProperties, cb); } wprintf(wszNewLine); }
if (fAllAttributes || NULL != apwszAttributes) { fHeaderPrinted = FALSE;
hr = prow->EnumCertDBName(CIE_TABLE_ATTRIBUTES, &penum); _JumpIfError(hr, error, "EnumCertDBName");
while (TRUE) { hr = penum->Next(1, &cdbn, &celtFetched); if (S_FALSE == hr) { break; } _JumpIfError(hr, error, "Next");
CSASSERT(1 == celtFetched); CSASSERT(NULL != cdbn.pwszName);
if (ShouldDisplay(cdbn.pwszName, fAllAttributes, apwszAttributes)) { if (!fHeaderPrinted) { PrintRowIndex(iRow, &fRowPrinted); if (fExtraNewLine) { wprintf(wszNewLine); } wprintf( L" %ws\n", myLoadResourceString(IDS_REQUEST_ATTRIBUTES)); // "Request Attributes:"
fHeaderPrinted = TRUE; fExtraNewLine = TRUE; } hr = cuDBPrintProperty( prow, PROPTABLE_ATTRIBUTE | PROPTYPE_STRING, cdbn.pwszName, cdbn.pwszName, NULL, // pbValue
0, // cbValue
&cb); // returned cbValue
_JumpIfError(hr, error, "cuDBPrintProperty");
UpdateStats( pstatsAttributes, wcslen(cdbn.pwszName) * sizeof(WCHAR) + cb + sizeof(LONG)); // for RequestId
} CoTaskMemFree(cdbn.pwszName); cdbn.pwszName = NULL; } penum->Release(); penum = NULL; }
if (fAllExtensions || NULL != apwszExtensions) { fHeaderPrinted = FALSE;
hr = prow->EnumCertDBName(CIE_TABLE_EXTENSIONS, &penum); _JumpIfError(hr, error, "EnumCertDBName");
while (TRUE) { DWORD ExtFlags;
hr = penum->Next(1, &cdbn, &celtFetched); if (S_FALSE == hr) { break; } _JumpIfError(hr, error, "Next");
CSASSERT(1 == celtFetched); CSASSERT(NULL != cdbn.pwszName);
if (ShouldDisplay(cdbn.pwszName, fAllExtensions, apwszExtensions)) { if (!fHeaderPrinted) { PrintRowIndex(iRow, &fRowPrinted); if (fExtraNewLine) { wprintf(wszNewLine); } wprintf( L" %ws\n", myLoadResourceString(IDS_CERTIFICATE_EXTENSIONS)); // "Certificate Extensions:"
fHeaderPrinted = TRUE; } cb = sizeof(abValue); hr = prow->GetExtension(cdbn.pwszName, &ExtFlags, &cb, abValue); _JumpIfError(hr, error, "GetExtension");
wprintf(g_wszPad4); wprintf( myLoadResourceString(IDS_FORMAT_EXTENSION), // "%ws: Flags = %x%ws, Length = %x"
cdbn.pwszName, ExtFlags, cuwszFromExtFlags(ExtFlags), cb); wprintf(wszNewLine);
if (!cuDumpFormattedExtension(cdbn.pwszName, abValue, cb) || g_fVerbose) { wprintf(wszNewLine); DumpHex(DH_NOTABPREFIX | 4, abValue, cb); } wprintf(wszNewLine);
UpdateStats( pstatsExtensions, wcslen(cdbn.pwszName) * sizeof(WCHAR) + cb + // for ext
sizeof(LONG) + // for RequestId
sizeof(ExtFlags)); // for ExtensionFlags
} CoTaskMemFree(cdbn.pwszName); cdbn.pwszName = NULL; } } hr = S_OK;
error: if (NULL != cdbn.pwszName) { CoTaskMemFree(cdbn.pwszName); } if (NULL != penum) { penum->Release(); } if (NULL != prow) { prow->Release(); } return(hr); }
WCHAR const * wszSeekOperator( IN LONG SeekOperator) { WCHAR const *pwsz; static WCHAR s_wszBuf[10 + cwcDWORDSPRINTF];
switch (CVR_SEEK_MASK & SeekOperator) { case CVR_SEEK_NONE: pwsz = L"None"; break; case CVR_SEEK_EQ: pwsz = L"=="; break; case CVR_SEEK_LT: pwsz = L"<"; break; case CVR_SEEK_LE: pwsz = L"<="; break; case CVR_SEEK_GE: pwsz = L">="; break; case CVR_SEEK_GT: pwsz = L">"; break; default: wsprintf(s_wszBuf, L"???=%x", SeekOperator); pwsz = s_wszBuf; break; } if (s_wszBuf != pwsz && (CVR_SEEK_NODELTA & SeekOperator)) { wcscpy(s_wszBuf, pwsz); wcscat(s_wszBuf, L",NoDelta"); pwsz = s_wszBuf; }
return(pwsz); }
WCHAR const * wszSortOperator( IN LONG SortOrder) { WCHAR const *pwsz; static WCHAR s_wszBuf[10 + cwcDWORDSPRINTF];
switch (SortOrder) { case CVR_SORT_NONE: pwsz = L"None"; break; case CVR_SORT_ASCEND: pwsz = L"Ascend"; break; case CVR_SORT_DESCEND: pwsz = L"Descend"; break; default: wsprintf(s_wszBuf, L"???=%x", SortOrder); pwsz = s_wszBuf; break; } return(pwsz); }
HRESULT DBParseRestriction( IN ICertDB *pdb, IN WCHAR const *pwszRestriction, OUT CERTVIEWRESTRICTION *pcvr, OUT BOOL *pfOneRow, OUT LONG *plSkip) { HRESULT hr; LONG ColType; WCHAR *pwszColName = NULL; WCHAR *pwszColValue = NULL; WCHAR const *pwszColNameActual; LONG lVal; DATE date; BYTE const *pb;
*pfOneRow = FALSE; *plSkip = 0;
hr = ParseRestriction( pwszRestriction, (LONG *) &pcvr->ColumnIndex, &pcvr->SeekOperator, &pcvr->SortOrder, &pwszColName, &pwszColValue); _JumpIfErrorStr(hr, error, "ParseRestriction", pwszRestriction);
// no value to parse if a special column...
if (NULL == pwszColName) { CSASSERT(0 > (LONG) pcvr->ColumnIndex); pcvr->cbValue = 0; pb = NULL; // no source data
pwszColNameActual = L""; } else { hr = DBGetColumnInfo( pdb, pwszColName, &pwszColNameActual, &pcvr->ColumnIndex, &ColType); _JumpIfErrorStr(hr, error, "DBGetColumnInfo", pwszColName);
hr = ParseSpecialColumnValue( pwszColValue, PROPTYPE_MASK & ColType, &pcvr->SeekOperator, &pcvr->SortOrder, pfOneRow, plSkip); _JumpIfError(hr, error, "ParseSpecialColumnValue");
switch (PROPTYPE_MASK & ColType) { case PROPTYPE_LONG: lVal = 0; if (!*pfOneRow) { hr = myGetSignedLong(pwszColValue, &lVal); _JumpIfError(hr, error, "bad numeric operand"); } pb = (BYTE const *) &lVal; pcvr->cbValue = sizeof(lVal); break;
case PROPTYPE_DATE: date = 0; if (!*pfOneRow) { hr = myWszLocalTimeToGMTDate(pwszColValue, &date); _JumpIfError(hr, error, "invalid date format"); } pb = (BYTE const *) &date; pcvr->cbValue = sizeof(date); cuDumpDate(&date); break;
case PROPTYPE_STRING: { WCHAR const *pwsz = L"";
if (!*pfOneRow) { pwsz = pwszColValue; } pb = (BYTE const *) pwsz; pcvr->cbValue = (wcslen(pwsz) + 1) * sizeof(WCHAR); break; }
case PROPTYPE_BINARY: default: hr = E_INVALIDARG; _JumpError(hr, error, "not supported"); } }
pcvr->pbValue = (BYTE *) LocalAlloc(LMEM_FIXED, pcvr->cbValue); if (NULL == pcvr->pbValue) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (NULL != pb) { CopyMemory(pcvr->pbValue, pb, pcvr->cbValue); }
#ifdef DBG_CERTSRV_DEBUG_PRINT
WCHAR wszSkip[cwcDWORDSPRINTF];
wszSkip[0] = L'\0'; if (0 != *plSkip) { wsprintf(wszSkip, L"%d", *plSkip); } #endif // DBG_CERTSRV_DEBUG_PRINT
DBGPRINT(( DBG_SS_CERTUTILI, "Restriction: Col=%ws Index=%x Seek='%ws'%ws Sort=%ws cb=%x, pb=%x\n", pwszColNameActual, pcvr->ColumnIndex, wszSeekOperator(pcvr->SeekOperator), wszSkip, wszSortOperator(pcvr->SortOrder), pcvr->cbValue, pcvr->pbValue)); DBGDUMPHEX((DBG_SS_CERTUTILI, 0, pcvr->pbValue, pcvr->cbValue));
error: if (NULL != pwszColName) { LocalFree(pwszColName); } if (NULL != pwszColValue) { LocalFree(pwszColValue); } return(hr); }
HRESULT verbDBDump( IN WCHAR const *pwszOption, IN WCHAR const *pwszRequestId, IN WCHAR const *pwszArg2, IN WCHAR const *pwszArg3, IN WCHAR const *pwszArg4) { HRESULT hr; WCHAR const *pwsz; ICertDB *pdb = NULL; ICertDBRow *prow = NULL; IEnumCERTDBRESULTROW *penum = NULL; DWORD i; DWORD imin = 1; DWORD RequestId; LONG cskip; WCHAR **apwszRestrictions = NULL; WCHAR **apwszColumns = NULL; WCHAR **apwszAttributes = NULL; WCHAR **apwszExtensions = NULL; WCHAR **ppwsz; BOOL fOneRow = FALSE; LONG lSkip = 0; BOOL fAllColumns; BOOL fAllAttributes; BOOL fAllExtensions; CERTVIEWRESTRICTION *acvr = NULL; DWORD ccvr; DWORD *acol = NULL; DWORD ccol; CERTDBRESULTROW arow[35]; DWORD crow; BOOL fReleaseRows = FALSE; DWORD iRow; DBSTATS statsRowProperties; DBSTATS statsAttributes; DBSTATS statsExtensions;
ZeroMemory(&statsRowProperties, sizeof(statsRowProperties)); ZeroMemory(&statsAttributes, sizeof(statsAttributes)); ZeroMemory(&statsExtensions, sizeof(statsExtensions));
if (NULL != pwszRequestId) { if (L'+' == *pwszRequestId) { hr = ParseSkipCounts(&pwszRequestId[1]); _JumpIfError(hr, error, "ParseSkipCounts"); } else { hr = myGetLong(pwszRequestId, (LONG *) &RequestId); _JumpIfError(hr, error, "RequestId must be a number");
imin = RequestId; fOneRow = TRUE; } } pwsz = wcschr(g_pwszConfig, L'\\'); if (NULL != pwsz) { pwsz++; } else { pwsz = g_pwszConfig; }
hr = cuDBOpen(pwsz, TRUE, &pdb); _JumpIfError(hr, error, "cuDBOpen");
hr = DBLoadSchema(pdb); _JumpIfError(hr, error, "DBLoadSchema");
if (1 < g_fVerbose) { hr = DBDumpSchema(pdb, NULL, 0); _JumpIfError(hr, error, "DBDumpSchema"); }
ccvr = 0; if (NULL != g_pwszRestrict) { hr = ParseViewRestrictions(g_pwszRestrict, &apwszRestrictions); _JumpIfError(hr, error, "ParseViewRestrictions");
for (ppwsz = apwszRestrictions; NULL != *ppwsz; ppwsz++) ; ccvr = (DWORD) (ppwsz - apwszRestrictions); acvr = (CERTVIEWRESTRICTION *) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, ccvr * sizeof(acvr[0])); if (NULL == acvr) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
for (i = 0; i < ccvr; i++) { BOOL f; LONG l;
hr = DBParseRestriction(pdb, apwszRestrictions[i], &acvr[i], &f, &l); _JumpIfErrorStr( hr, error, "DBParseRestriction", apwszRestrictions[i]);
if (f) { fOneRow = TRUE; lSkip = l; } } }
ccol = 0; fAllColumns = TRUE; fAllAttributes = TRUE; fAllExtensions = TRUE; if (NULL != g_pwszOut) { fAllAttributes = FALSE; fAllExtensions = FALSE;
hr = ParseViewColumns( g_pwszOut, NULL, NULL, &apwszColumns, &fAllColumns); _JumpIfError(hr, error, "ParseViewColumns");
if (NULL != apwszColumns) { for (ppwsz = apwszColumns; NULL != *ppwsz; ppwsz++) ;
ccol = (DWORD) (ppwsz - apwszColumns); }
hr = ParseViewColumns( g_pwszOut, g_wszAttrib, g_apwszAllowedPrefixes, &apwszAttributes, &fAllAttributes); _JumpIfError(hr, error, "ParseViewColumns");
hr = ParseViewColumns( g_pwszOut, g_wszExt, NULL, &apwszExtensions, &fAllExtensions); _JumpIfError(hr, error, "ParseViewColumns"); }
if (fAllColumns) { ccol = g_cdcRequests + g_cdcCertificates; } if (0 != ccol) { acol = (DWORD *) LocalAlloc(LMEM_FIXED, ccol * sizeof(acol[0])); if (NULL == acol) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); }
if (fAllColumns) { for (i = 0; i < ccol; i++) { CERTDBCOLUMN const *pdc;
pdc = (i < g_cdcRequests)? &g_adcRequests[i] : &g_adcCertificates[i - g_cdcRequests]; acol[i] = pdc->Index; } } else { CSASSERT(NULL != apwszColumns); for (i = 0; i < ccol; i++) { WCHAR const *pwszColNameActual; LONG ColType;
hr = DBGetColumnInfo( pdb, apwszColumns[i], &pwszColNameActual, &acol[i], &ColType); _JumpIfErrorStr(hr, error, "DBGetColumnInfo", apwszColumns[i]); } } } if (!g_fCryptSilent) { hr = DBDumpSchema(pdb, acol, ccol); _JumpIfError(hr, error, "DBDumpSchema"); } if (NULL != g_pwszRestrict) { BOOL fNoMore; LONG lIndex;
hr = pdb->OpenView(ccvr, acvr, ccol, acol, 0x0, &penum); _JumpIfError(hr, error, "OpenView");
hr = penum->Skip(lSkip, &lIndex); _JumpIfError(hr, error, "Skip");
iRow = 1; fNoMore = FALSE; while (!fNoMore) { hr = penum->Next( NULL, (ULONG)(fOneRow? 1 : ARRAYSIZE(arow)), arow, &crow); if (S_FALSE == hr) { hr = S_OK; fNoMore = TRUE; } _JumpIfError(hr, error, "Next");
fReleaseRows = TRUE;
//wprintf(L"celtFetched = %u\n", crow);
for (i = 0; i < crow; i++, iRow++) { hr = DBPrintRow( pdb, iRow, arow[i].rowid, &arow[i], NULL, // acol
0, // ccol
FALSE, // fAllColumns
&statsRowProperties, apwszAttributes, fAllAttributes, &statsAttributes, apwszExtensions, fAllExtensions, &statsExtensions); _JumpIfError(hr, error, "DBPrintRow"); }
if (fNoMore) { CSASSERT(ARRAYSIZE(arow) > crow); CSASSERT(i == crow); CSASSERT(arow[i].rowid == ~arow[i].ccol); wprintf( L"\n%ws: %u\n", myLoadResourceString(IDS_MAXINDEX), // "Maximum Row Index"
arow[i].rowid); }
hr = penum->ReleaseResultRow(crow, arow); _JumpIfError(hr, error, "ReleaseResultRow");
fReleaseRows = FALSE;
if (fOneRow) { break; } } } else { DWORD imax;
iRow = 1; imax = fOneRow? imin + 1 : MAXDWORD; for (i = imin; i < imax; i++, iRow++) { hr = DBPrintRow( pdb, iRow, i, // RowId
NULL, // pResultRow
acol, ccol, fAllColumns, &statsRowProperties, apwszAttributes, fAllAttributes, &statsAttributes, apwszExtensions, fAllExtensions, &statsExtensions); if (CERTSRV_E_PROPERTY_EMPTY == hr) // RowId doesn't exist
{ hr = S_OK; break; } _JumpIfError(hr, error, "DBPrintRow"); } } DumpViewStats( iRow - 1, &statsRowProperties, &statsAttributes, &statsExtensions);
error: cuFreeStringArray(apwszRestrictions); cuFreeStringArray(apwszColumns); cuFreeStringArray(apwszAttributes); cuFreeStringArray(apwszExtensions);
if (NULL != acvr) { for (i = 0; i < ccvr; i++) { if (NULL != acvr[i].pbValue) { LocalFree(acvr[i].pbValue); } } LocalFree(acvr); } if (NULL != acol) { LocalFree(acol); } DBFreeSchema();
if (fReleaseRows) { hr = penum->ReleaseResultRow(crow, arow); _JumpIfError(hr, error, "ReleaseResultRow"); }
// Take critical section to make sure we wait for CTL-C DB shutdown.
EnterCriticalSection(&g_DBCriticalSection); if (cuDBIsShutDownInProgress()) { if (myJetHResult(JET_errTermInProgress) == hr) { hr = HRESULT_FROM_WIN32(ERROR_CANCELLED); } } else { if (NULL != penum) { penum->Release(); } if (NULL != prow) { prow->Release(); } } LeaveCriticalSection(&g_DBCriticalSection); cuDBAbortShutDown(0); return(hr); }
|