//+-------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1996 - 1999 // // File: view.cpp // // Contents: CertView implementation // //--------------------------------------------------------------------------- #include "pch.cpp" #pragma hdrstop #include "csprop.h" #include "csdisp.h" #include "column.h" #include "row.h" #include "view.h" #define __dwFILE__ __dwFILE_CERTVIEW_VIEW_CPP__ WCHAR const g_wszRequestDot[] = wszPROPREQUESTDOT; #if DBG_CERTSRV LONG g_cCertView; LONG g_cCertViewTotal; #endif #define CV_COLUMN_CHUNK 66 //+-------------------------------------------------------------------------- // _cbcolNominal -- Return nominal size for DB column data, based on type. // // Assume string binary columns are less than full: //+-------------------------------------------------------------------------- __inline LONG _cbcolNominal( IN LONG Type, IN LONG cbMax) { LONG divisor = 1; switch (PROPTYPE_MASK & Type) { case PROPTYPE_STRING: divisor = 2; break; // one-half full? case PROPTYPE_BINARY: divisor = 4; break; // one-quarter full? } return(cbMax / divisor); } //+-------------------------------------------------------------------------- // CCertView::CCertView -- constructor //+-------------------------------------------------------------------------- CCertView::CCertView() { DBGCODE(InterlockedIncrement(&g_cCertView)); DBGCODE(InterlockedIncrement(&g_cCertViewTotal)); ZeroMemory(&m_aaaColumn, sizeof(m_aaaColumn)); m_fOpenConnection = FALSE; m_dwServerVersion = 0; m_pICertAdminD = NULL; m_aColumnResult = NULL; m_aDBColumnResult = NULL; m_pwszAuthority = NULL; m_fAddOk = FALSE; m_fOpenView = FALSE; m_fServerOpenView = FALSE; m_aRestriction = NULL; m_fTableSet = FALSE; m_icvTable = ICVTABLE_REQCERT; m_cvrcTable = CVRC_TABLE_REQCERT; m_pwszServerName = NULL; ZeroMemory(&m_aapwszColumnDisplayName, sizeof(m_aapwszColumnDisplayName)); } //+-------------------------------------------------------------------------- // CCertView::~CCertView -- destructor // // free memory associated with this instance //+-------------------------------------------------------------------------- CCertView::~CCertView() { DBGCODE(InterlockedDecrement(&g_cCertView)); #if DBG_CERTSRV if (m_dwRef > 1) { DBGPRINT(( DBG_SS_CERTVIEWI, "%hs has %d instances left over\n", "CCertView", m_dwRef)); } #endif _Cleanup(); } //+-------------------------------------------------------------------------- // CCertView::_Cleanup // // free memory associated with this instance //+-------------------------------------------------------------------------- VOID CCertView::_Cleanup() { LONG i; myCloseDComConnection((IUnknown **) &m_pICertAdminD, &m_pwszServerName); m_dwServerVersion = 0; m_fOpenConnection = FALSE; if (NULL != m_aColumnResult) { LocalFree(m_aColumnResult); m_aColumnResult = NULL; } if (NULL != m_aDBColumnResult) { LocalFree(m_aDBColumnResult); m_aDBColumnResult = NULL; } for (i = 0; i < ICVTABLE_MAX; i++) { if (NULL != m_aaaColumn[i]) { CERTDBCOLUMN **ppcol; for ( ppcol = m_aaaColumn[i]; ppcol < &m_aaaColumn[i][m_acaColumn[i]]; ppcol++) { if (NULL != *ppcol) { LocalFree(*ppcol); } } LocalFree(m_aaaColumn[i]); m_aaaColumn[i] = NULL; } } if (NULL != m_aRestriction) { for (i = 0; i < m_cRestriction; i++) { if (NULL != m_aRestriction[i].pbValue) { LocalFree(m_aRestriction[i].pbValue); } } LocalFree(m_aRestriction); m_aRestriction = NULL; } if (NULL != m_pwszAuthority) { LocalFree(m_pwszAuthority); m_pwszAuthority = NULL; } for (i = 0; i < ICVTABLE_MAX; i++) { if (NULL != m_aapwszColumnDisplayName[i]) { LocalFree(m_aapwszColumnDisplayName[i]); m_aapwszColumnDisplayName[i] = NULL; } } } HRESULT CCertView::_ValidateFlags( IN BOOL fSchemaOnly, IN DWORD Flags) { HRESULT hr = E_INVALIDARG; if (~CVRC_COLUMN_MASK & Flags) { _JumpError(hr, error, "invalid bits"); } switch (CVRC_COLUMN_MASK & Flags) { case CVRC_COLUMN_RESULT: case CVRC_COLUMN_VALUE: if (fSchemaOnly) { _JumpError(hr, error, "RESULT/VALUE"); } break; case CVRC_COLUMN_SCHEMA: break; default: _JumpError(hr, error, "bad column"); } if (!m_fOpenConnection || (CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & Flags) && !m_fOpenView)) { hr = E_UNEXPECTED; _JumpError(hr, error, "Unexpected"); } hr = S_OK; error: return(hr); } HRESULT CCertView::_SetTable( IN LONG ColumnIndex) // CVRC_TABLE_* or CV_COLUMN_*_DEFAULT { HRESULT hr; LONG cvrcTable; LONG icvTable; if (0 > ColumnIndex) { switch (ColumnIndex) { case CV_COLUMN_LOG_DEFAULT: case CV_COLUMN_LOG_FAILED_DEFAULT: case CV_COLUMN_LOG_REVOKED_DEFAULT: case CV_COLUMN_QUEUE_DEFAULT: icvTable = ICVTABLE_REQCERT; cvrcTable = CVRC_TABLE_REQCERT; break; case CV_COLUMN_EXTENSION_DEFAULT: icvTable = ICVTABLE_EXTENSION; cvrcTable = CVRC_TABLE_EXTENSIONS; break; case CV_COLUMN_ATTRIBUTE_DEFAULT: icvTable = ICVTABLE_ATTRIBUTE; cvrcTable = CVRC_TABLE_ATTRIBUTES; break; case CV_COLUMN_CRL_DEFAULT: icvTable = ICVTABLE_CRL; cvrcTable = CVRC_TABLE_CRL; break; default: hr = E_INVALIDARG; _JumpError(hr, error, "bad negative ColumnIndex"); } } else { if (~CVRC_TABLE_MASK & ColumnIndex) { hr = E_INVALIDARG; _JumpError(hr, error, "invalid bits"); } switch (ColumnIndex) { case CVRC_TABLE_REQCERT: icvTable = ICVTABLE_REQCERT; break; case CVRC_TABLE_EXTENSIONS: icvTable = ICVTABLE_EXTENSION; break; case CVRC_TABLE_ATTRIBUTES: icvTable = ICVTABLE_ATTRIBUTE; break; case CVRC_TABLE_CRL: icvTable = ICVTABLE_CRL; break; default: hr = E_INVALIDARG; _JumpError(hr, error, "bad table"); } cvrcTable = CVRC_TABLE_MASK & ColumnIndex; } if (m_fTableSet) { if (icvTable != m_icvTable || cvrcTable != m_cvrcTable) { DBGPRINT(( DBG_SS_CERTVIEW, "_SetTable: cvrcTable=%x <- %x\n", m_cvrcTable, cvrcTable)); hr = E_INVALIDARG; _JumpError(hr, error, "mixed tables"); } } else { m_icvTable = icvTable; m_cvrcTable = cvrcTable; m_fTableSet = TRUE; DBGPRINT((DBG_SS_CERTVIEWI, "_SetTable(cvrcTable=%x)\n", m_cvrcTable)); } hr = S_OK; error: return(hr); } STDMETHODIMP CCertView::SetTable( /* [in] */ LONG Table) // CVRC_TABLE_* { HRESULT hr; hr = _VerifyServerVersion(2); _JumpIfError(hr, error, "_VerifyServerVersion"); if (0 > Table) { hr = E_INVALIDARG; _JumpError(hr, error, "Table"); } if (m_fTableSet) { hr = E_UNEXPECTED; _JumpError(hr, error, "Already set"); } hr = _SetTable(Table); _JumpIfError(hr, error, "_SetTable"); error: return(hr); } HRESULT CCertView::GetTable( OUT LONG *pcvrcTable) { HRESULT hr; if (NULL == pcvrcTable) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *pcvrcTable = m_cvrcTable; hr = S_OK; error: return(hr); } HRESULT CCertView::FindColumn( IN LONG Flags, // CVRC_COLUMN_* IN LONG ColumnIndex, OUT CERTDBCOLUMN const **ppColumn, // localized for server OPTIONAL OUT WCHAR const **ppwszDisplayName) // localized for client { HRESULT hr; DWORD i; DBGCODE(LONG ColumnIndexArg = ColumnIndex); if (NULL == ppColumn) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *ppColumn = NULL; hr = _ValidateFlags(FALSE, Flags); _JumpIfError(hr, error, "_ValidateFlags"); hr = E_INVALIDARG; if (CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & Flags)) { if (m_cColumnResult <= ColumnIndex) { DBGPRINT(( DBG_SS_CERTVIEW, "FindColumn(Flags=%x, ColumnIndex=%x, m_cColumnResult=%x)\n", Flags, ColumnIndex, m_cColumnResult)); _JumpError(hr, error, "Result ColumnIndex"); } ColumnIndex = m_aColumnResult[ColumnIndex]; } if (ColumnIndex >= m_acColumn[m_icvTable]) { _JumpError(hr, error, "ColumnIndex"); } i = ColumnIndex / CV_COLUMN_CHUNK; if (i >= m_acaColumn[m_icvTable]) { _JumpError(hr, error, "ColumnIndex2"); } *ppColumn = &m_aaaColumn[m_icvTable][i][ColumnIndex % CV_COLUMN_CHUNK]; CSASSERT(NULL != m_aapwszColumnDisplayName[m_icvTable]); CSASSERT(NULL != m_aapwszColumnDisplayName[m_icvTable][ColumnIndex]); if (NULL != ppwszDisplayName) { *ppwszDisplayName = m_aapwszColumnDisplayName[m_icvTable][ColumnIndex]; } DBGPRINT(( DBG_SS_CERTVIEWI, "FindColumn(Flags=%x, ColumnIndex=%x->%x) --> Type=%x Index=%x %ws/%ws\n", Flags, ColumnIndexArg, ColumnIndex, (*ppColumn)->Type, (*ppColumn)->Index, (*ppColumn)->pwszName, m_aapwszColumnDisplayName[m_icvTable][ColumnIndex])); hr = S_OK; error: return(hr); } HRESULT CCertView::_SaveColumnInfo( IN LONG icvTable, IN DWORD celt, IN CERTTRANSBLOB const *pctbColumn) { HRESULT hr; DWORD cbNew; CERTDBCOLUMN *peltNew = NULL; CERTDBCOLUMN *pelt; CERTTRANSDBCOLUMN *ptelt; CERTTRANSDBCOLUMN *pteltEnd; BYTE *pbNext; BYTE *pbEnd; CERTDBCOLUMN **ppColumn; if (NULL == pctbColumn) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } cbNew = pctbColumn->cb + celt * (sizeof(*pelt) - sizeof(*ptelt)); peltNew = (CERTDBCOLUMN *) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cbNew); if (NULL == peltNew) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } pteltEnd = &((CERTTRANSDBCOLUMN *) pctbColumn->pb)[celt]; if ((BYTE *) pteltEnd > &pctbColumn->pb[pctbColumn->cb]) { hr = HRESULT_FROM_WIN32(ERROR_INVALID_DATA); _JumpError(hr, error, "bad marshalled data"); } pelt = peltNew; pbNext = (BYTE *) &peltNew[celt]; pbEnd = (BYTE *) Add2Ptr(peltNew, cbNew); for (ptelt = (CERTTRANSDBCOLUMN *) pctbColumn->pb; ptelt < pteltEnd; ptelt++, pelt++) { pelt->Type = ptelt->Type; pelt->Index = ptelt->Index; pelt->cbMax = ptelt->cbMax; hr = CopyMarshalledString( pctbColumn, ptelt->obwszName, pbEnd, &pbNext, &pelt->pwszName); _JumpIfError(hr, error, "CopyMarshalledString"); hr = CopyMarshalledString( pctbColumn, ptelt->obwszDisplayName, pbEnd, &pbNext, &pelt->pwszDisplayName); _JumpIfError(hr, error, "CopyMarshalledString"); } CSASSERT(pbNext == pbEnd); ppColumn = (CERTDBCOLUMN **) LocalAlloc( LMEM_FIXED, (m_acaColumn[icvTable] + 1) * sizeof(m_aaaColumn[0])); if (NULL == ppColumn) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc ppColumn"); } if (NULL != m_aaaColumn[icvTable]) { CopyMemory( ppColumn, m_aaaColumn[icvTable], m_acaColumn[icvTable] * sizeof(m_aaaColumn[0])); LocalFree(m_aaaColumn[icvTable]); } m_aaaColumn[icvTable] = ppColumn; m_aaaColumn[icvTable][m_acaColumn[icvTable]] = peltNew; peltNew = NULL; m_acaColumn[icvTable]++; m_acColumn[icvTable] += celt; hr = S_OK; error: if (NULL != peltNew) { LocalFree(peltNew); } return(hr); } HRESULT CCertView::_LoadSchema( IN LONG icvTable, IN LONG cvrcTable) { HRESULT hr; DWORD icol; DWORD ccol; CERTTRANSBLOB ctbColumn; ctbColumn.pb = NULL; icol = 0; CSASSERT(icvTable < ICVTABLE_MAX); do { ccol = CV_COLUMN_CHUNK; __try { if (CVRC_TABLE_REQCERT == cvrcTable) { hr = m_pICertAdminD->EnumViewColumn( m_pwszAuthority, icol, ccol, &ccol, &ctbColumn); } else { CSASSERT(S_OK == _VerifyServerVersion(2)); hr = m_pICertAdminD->EnumViewColumnTable( m_pwszAuthority, cvrcTable, icol, ccol, &ccol, &ctbColumn); } } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } if (S_FALSE != hr) { _JumpIfError( hr, error, CVRC_TABLE_REQCERT == cvrcTable? "EnumViewColumn" : "EnumViewColumnTable"); } myRegisterMemAlloc(ctbColumn.pb, ctbColumn.cb, CSM_MIDLUSERALLOC); hr = _SaveColumnInfo(icvTable, ccol, &ctbColumn); _JumpIfError(hr, error, "_SaveColumnInfo"); CoTaskMemFree(ctbColumn.pb); ctbColumn.pb = NULL; icol += ccol; } while (CV_COLUMN_CHUNK == ccol); m_aapwszColumnDisplayName[icvTable] = (WCHAR const **) LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT, m_acColumn[icvTable] * sizeof(m_aapwszColumnDisplayName[icvTable][0])); if (NULL == m_aapwszColumnDisplayName[icvTable]) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } for (icol = 0; icol < (DWORD) m_acColumn[icvTable]; icol++) { CERTDBCOLUMN const *pColumn; CSASSERT(icol / CV_COLUMN_CHUNK < m_acaColumn[icvTable]); pColumn = &m_aaaColumn[icvTable][icol / CV_COLUMN_CHUNK][icol % CV_COLUMN_CHUNK]; hr = myGetColumnDisplayName( pColumn->pwszName, &m_aapwszColumnDisplayName[icvTable][icol]); if (E_INVALIDARG == hr) { _PrintErrorStr(hr, "myGetColumnDisplayName", pColumn->pwszName); m_aapwszColumnDisplayName[icvTable][icol] = pColumn->pwszName; hr = S_OK; } _JumpIfError(hr, error, "myGetColumnDisplayName"); } hr = S_OK; error: if (NULL != ctbColumn.pb) { CoTaskMemFree(ctbColumn.pb); } return(hr); } STDMETHODIMP CCertView::OpenConnection( /* [in] */ BSTR const strConfig) { HRESULT hr; DWORD i; WCHAR const *pwszAuthority; BOOL fTeardownOnError = FALSE; static LONG s_aTable[ICVTABLE_MAX] = { CVRC_TABLE_REQCERT, // ICVTABLE_REQCERT CVRC_TABLE_EXTENSIONS, // ICVTABLE_EXTENSION CVRC_TABLE_ATTRIBUTES, // ICVTABLE_ATTRIBUTE CVRC_TABLE_CRL, // ICVTABLE_CRL }; if (NULL == strConfig) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } if (m_fOpenConnection) { hr = E_UNEXPECTED; _JumpError(hr, error, "Connected"); } fTeardownOnError = TRUE; m_dwServerVersion = 0; hr = myOpenAdminDComConnection( strConfig, &pwszAuthority, &m_pwszServerName, &m_dwServerVersion, &m_pICertAdminD); _JumpIfError(hr, error, "myOpenAdminDComConnection"); CSASSERT (0 != m_dwServerVersion); hr = myDupString(pwszAuthority, &m_pwszAuthority); _JumpIfError(hr, error, "myDupString"); ZeroMemory(&m_acaColumn, sizeof(m_acaColumn)); ZeroMemory(&m_acColumn, sizeof(m_acColumn)); m_cRestriction = 0; m_aRestriction = (CERTVIEWRESTRICTION *) LocalAlloc(LMEM_FIXED, 0); if (NULL == m_aRestriction) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } m_fOpenConnection = TRUE; for (i = 0; i < ICVTABLE_MAX; i++) { if (m_dwServerVersion >= 2 || ICVTABLE_REQCERT == i) { hr = _LoadSchema(i, s_aTable[i]); _JumpIfError(hr, error, "_LoadSchema"); } } hr = S_OK; error: if (S_OK != hr && fTeardownOnError) { _Cleanup(); } return(_SetErrorInfo(hr, L"CCertView::OpenConnection")); } //+-------------------------------------------------------------------------- // CCertView::_VerifyServerVersion -- verify server version // //+-------------------------------------------------------------------------- HRESULT CCertView::_VerifyServerVersion( IN DWORD RequiredVersion) { HRESULT hr; if (!m_fOpenConnection) { hr = HRESULT_FROM_WIN32(ERROR_ONLY_IF_CONNECTED); _JumpError(hr, error, "Not connected"); } if (m_dwServerVersion < RequiredVersion) { hr = RPC_E_VERSION_MISMATCH; _JumpError(hr, error, "old server"); } hr = S_OK; error: return(hr); } STDMETHODIMP CCertView::EnumCertViewColumn( /* [in] */ LONG fResultColumn, // CVRC_COLUMN_* /* [out, retval] */ IEnumCERTVIEWCOLUMN **ppenum) { HRESULT hr; IEnumCERTVIEWCOLUMN *penum = NULL; if (NULL == ppenum) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *ppenum = NULL; penum = new CEnumCERTVIEWCOLUMN; if (NULL == penum) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "new CEnumCERTVIEWCOLUMN"); } hr = ((CEnumCERTVIEWCOLUMN *) penum)->Open(fResultColumn, -1, this, NULL); _JumpIfError(hr, error, "Open"); *ppenum = penum; penum = NULL; hr = S_OK; error: if (NULL != penum) { penum->Release(); } return(_SetErrorInfo(hr, L"CCertView::EnumCertViewColumn")); } STDMETHODIMP CCertView::GetColumnCount( /* [in] */ LONG fResultColumn, // CVRC_COLUMN_* /* [out, retval] */ LONG __RPC_FAR *pcColumn) { HRESULT hr; if (NULL == pcColumn) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } hr = _ValidateFlags(FALSE, fResultColumn); _JumpIfError(hr, error, "_ValidateFlags"); *pcColumn = CVRC_COLUMN_SCHEMA != (CVRC_COLUMN_MASK & fResultColumn)? m_cColumnResult : m_acColumn[m_icvTable]; error: return(_SetErrorInfo(hr, L"CCertView::GetColumnCount")); } STDMETHODIMP CCertView::GetColumnIndex( /* [in] */ LONG fResultColumn, // CVRC_COLUMN_* /* [in] */ BSTR const strColumnName, /* [out, retval] */ LONG *pColumnIndex) { HRESULT hr; CERTDBCOLUMN const *pColumn; WCHAR const *pwsz; WCHAR *pwszAlloc = NULL; WCHAR const *pwszDisplayName; LONG icol; LONG i; if (NULL == strColumnName || NULL == pColumnIndex) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } pwsz = strColumnName; hr = _ValidateFlags(FALSE, fResultColumn); _JumpIfError(hr, error, "_ValidateFlags"); // First pass: i == 0 -- compare against unlocalized column name // Second pass: i == 1 -- compare against localized column name // Third pass: i == 2 -- compare Request.pwsz against unlocalized colname for (i = 0; ; i++) { if (1 < i) { if (ICVTABLE_REQCERT != m_icvTable || NULL != wcschr(pwsz, L'.')) { hr = E_INVALIDARG; _JumpErrorStr(hr, error, "Bad Column Name", strColumnName); } pwszAlloc = (WCHAR *) LocalAlloc( LMEM_FIXED, wcslen(pwsz) * sizeof(WCHAR) + sizeof(g_wszRequestDot)); if (NULL == pwszAlloc) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } wcscpy(pwszAlloc, g_wszRequestDot); wcscat(pwszAlloc, pwsz); pwsz = pwszAlloc; } for (icol = 0; icol < m_acColumn[m_icvTable]; icol++) { hr = FindColumn(fResultColumn, icol, &pColumn, &pwszDisplayName); _JumpIfErrorStr(hr, error, "FindColumn", strColumnName); CSASSERT(NULL != pColumn); CSASSERT(NULL != pColumn->pwszName); CSASSERT(NULL != pColumn->pwszDisplayName); // localized for server CSASSERT(NULL != pwszDisplayName); // localized for client if (0 == lstrcmpi( pwsz, 1 == i? pwszDisplayName : pColumn->pwszName)) { break; } } if (icol < m_acColumn[m_icvTable]) { break; } } *pColumnIndex = icol; hr = S_OK; error: if (NULL != pwszAlloc) { LocalFree(pwszAlloc); } return(_SetErrorInfo(hr, L"CCertView::GetColumnIndex")); } STDMETHODIMP CCertView::SetResultColumnCount( /* [in] */ LONG cResultColumn) { HRESULT hr; DWORD cColumnDefault; CERTTRANSBLOB ctbColumnDefault; ctbColumnDefault.pb = NULL; hr = E_UNEXPECTED; if (!m_fOpenConnection) { _JumpError(hr, error, "No Connection"); } if (NULL != m_aColumnResult) { _JumpError(hr, error, "2nd call"); } if (!m_fTableSet) { hr = _SetTable(CVRC_TABLE_REQCERT); _JumpIfError(hr, error, "_SetTable"); } m_cbcolResultNominalTotal = 0; m_fAddOk = TRUE; if (0 > cResultColumn) { m_fAddOk = FALSE; __try { hr = m_pICertAdminD->GetViewDefaultColumnSet( m_pwszAuthority, cResultColumn, &cColumnDefault, &ctbColumnDefault); } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } _JumpIfError(hr, error, "GetViewDefaultColumnSet"); myRegisterMemAlloc( ctbColumnDefault.pb, ctbColumnDefault.cb, CSM_MIDLUSERALLOC); cResultColumn = cColumnDefault; CSASSERT(NULL != ctbColumnDefault.pb); CSASSERT(cResultColumn * sizeof(DWORD) == ctbColumnDefault.cb); } else { cResultColumn &= CVRC_COLUMN_MASK; } m_aColumnResult = (LONG *) LocalAlloc( LMEM_FIXED, cResultColumn * sizeof(m_aColumnResult[0])); if (NULL == m_aColumnResult) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Result Column array"); } m_aDBColumnResult = (DWORD *) LocalAlloc( LMEM_FIXED, cResultColumn * sizeof(m_aDBColumnResult[0])); if (NULL == m_aDBColumnResult) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "Result DB Column array"); } m_cColumnResultMax = cResultColumn; m_cColumnResult = 0; if (!m_fAddOk) { LONG i; DWORD const *pIndex; pIndex = (DWORD const *) ctbColumnDefault.pb; for (i = 0; i < cResultColumn; pIndex++, i++) { LONG icol; CERTDBCOLUMN const *pColumn; for (icol = 0; icol < m_acColumn[m_icvTable]; icol++) { hr = FindColumn( CVRC_COLUMN_SCHEMA, icol, &pColumn, NULL); _JumpIfError(hr, error, "FindColumn"); if (*pIndex == pColumn->Index) { m_aDBColumnResult[i] = *pIndex; m_aColumnResult[i] = icol; m_cbcolResultNominalTotal += _cbcolNominal(pColumn->Type, pColumn->cbMax); break; } } if (icol >= m_acColumn[m_icvTable]) { hr = E_INVALIDARG; _JumpError(hr, error, "ColumnIndex"); } } m_cColumnResult = cResultColumn; } hr = S_OK; error: if (NULL != ctbColumnDefault.pb) { CoTaskMemFree(ctbColumnDefault.pb); } return(_SetErrorInfo(hr, L"CCertView::SetResultColumnCount")); } STDMETHODIMP CCertView::SetResultColumn( /* [in] */ LONG ColumnIndex) { HRESULT hr; CERTDBCOLUMN const *pColumn; if (m_fOpenView || !m_fAddOk || m_cColumnResultMax <= m_cColumnResult) { hr = E_UNEXPECTED; _JumpError(hr, error, "Unexpected"); } if (!m_fTableSet) { hr = _SetTable(CVRC_TABLE_REQCERT); _JumpIfError(hr, error, "_SetTable"); } if (m_acColumn[m_icvTable] <= ColumnIndex) { hr = E_INVALIDARG; _JumpError(hr, error, "ColumnIndex"); } m_aColumnResult[m_cColumnResult] = ColumnIndex; hr = FindColumn( CVRC_COLUMN_SCHEMA, ColumnIndex, &pColumn, NULL); _JumpIfError(hr, error, "FindColumn"); m_aDBColumnResult[m_cColumnResult] = pColumn->Index; m_cbcolResultNominalTotal += _cbcolNominal(pColumn->Type, pColumn->cbMax); m_cColumnResult++; error: return(_SetErrorInfo(hr, L"CCertView::SetResultColumn")); } STDMETHODIMP CCertView::SetRestriction( /* [in] */ LONG ColumnIndex, /* [in] */ LONG SeekOperator, /* [in] */ LONG SortOrder, /* [in] */ VARIANT __RPC_FAR const *pvarValue) { HRESULT hr; CERTDBCOLUMN const *pColumn; CERTVIEWRESTRICTION cvr; CERTVIEWRESTRICTION *pcvr; ZeroMemory(&cvr, sizeof(cvr)); hr = E_UNEXPECTED; if (!m_fOpenConnection) { _JumpError(hr, error, "No Connection"); } if (!m_fTableSet) { hr = _SetTable(CVRC_TABLE_REQCERT); _JumpIfError(hr, error, "_SetTable"); } if (0 > ColumnIndex) { cvr.ColumnIndex = ColumnIndex; CSASSERT(CVR_SEEK_NONE == cvr.SeekOperator); CSASSERT(CVR_SORT_NONE == cvr.SortOrder); CSASSERT(NULL == cvr.pbValue); CSASSERT(0 == cvr.cbValue); hr = S_OK; } else { if (NULL == pvarValue) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } hr = FindColumn( CVRC_COLUMN_SCHEMA, CVRC_COLUMN_MASK & ColumnIndex, &pColumn, NULL); _JumpIfError(hr, error, "FindColumn"); switch (SeekOperator) { case CVR_SEEK_EQ: case CVR_SEEK_LT: case CVR_SEEK_LE: case CVR_SEEK_GE: case CVR_SEEK_GT: case CVR_SEEK_NONE: //case CVR_SEEK_SET: break; default: hr = E_INVALIDARG; _JumpError(hr, error, "Seek Operator"); } switch (SortOrder) { case CVR_SORT_NONE: case CVR_SORT_ASCEND: case CVR_SORT_DESCEND: break; default: hr = E_INVALIDARG; _JumpError(hr, error, "Sort Order"); } hr = myMarshalVariant( pvarValue, pColumn->Type, &cvr.cbValue, &cvr.pbValue); _JumpIfError(hr, error, "myMarshalVariant"); cvr.ColumnIndex = pColumn->Index; cvr.SeekOperator = SeekOperator; cvr.SortOrder = SortOrder; } pcvr = (CERTVIEWRESTRICTION *) LocalAlloc( LMEM_FIXED, (m_cRestriction + 1) * sizeof(*pcvr)); if (NULL == pcvr) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (NULL != m_aRestriction) { CopyMemory(pcvr, m_aRestriction, m_cRestriction * sizeof(*pcvr)); LocalFree(m_aRestriction); } CopyMemory(&pcvr[m_cRestriction], &cvr, sizeof(cvr)); cvr.pbValue = NULL; m_aRestriction = pcvr; m_cRestriction++; error: if (NULL != cvr.pbValue) { LocalFree(cvr.pbValue); } return(_SetErrorInfo(hr, L"CCertView::SetRestriction")); } STDMETHODIMP CCertView::OpenView( /* [out] */ IEnumCERTVIEWROW **ppenum) { HRESULT hr; IEnumCERTVIEWROW *penum = NULL; if (NULL == ppenum) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *ppenum = NULL; hr = E_UNEXPECTED; if (!m_fOpenConnection) { _JumpError(hr, error, "No Connection"); } if (m_fOpenView) { _JumpError(hr, error, "2nd call"); } penum = new CEnumCERTVIEWROW; if (NULL == penum) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "new CEnumCERTVIEWROW"); } hr = ((CEnumCERTVIEWROW *) penum)->Open(this); _JumpIfError(hr, error, "Open"); *ppenum = penum; m_fAddOk = FALSE; m_fOpenView = TRUE; hr = S_OK; error: if (S_OK != hr && NULL != penum) { penum->Release(); } return(_SetErrorInfo(hr, L"CCertView::OpenView")); } HRESULT CCertView::SetViewColumns( OUT LONG *pcbrowResultNominal) { HRESULT hr; LONG icol; if (NULL == pcbrowResultNominal) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } if (m_fServerOpenView) { hr = E_UNEXPECTED; _JumpError(hr, error, "View Already Open"); } if (!m_fTableSet) { hr = _SetTable(CVRC_TABLE_REQCERT); _JumpIfError(hr, error, "_SetTable"); } if (NULL == m_aDBColumnResult) { hr = SetResultColumnCount(m_acColumn[m_icvTable]); _JumpIfError(hr, error, "SetResultColumnCount"); for (icol = 0; icol < m_acColumn[m_icvTable]; icol++) { hr = SetResultColumn(icol); _JumpIfError(hr, error, "SetResultColumn"); } } *pcbrowResultNominal = sizeof(CERTDBRESULTROW) + sizeof(CERTDBRESULTCOLUMN) * m_cColumnResultMax + m_cbcolResultNominalTotal; hr = S_OK; error: return(hr); } HRESULT CCertView::EnumView( IN LONG cskip, IN ULONG celt, OUT ULONG *pceltFetched, OUT LONG *pieltNext, OUT LONG *pcbResultRows, OUT CERTTRANSDBRESULTROW const **ppResultRows) { HRESULT hr; CERTTRANSBLOB ctbResultRows; if (NULL == ppResultRows || NULL == pceltFetched || NULL == pieltNext || NULL == pcbResultRows) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } *ppResultRows = NULL; if (!m_fOpenConnection) { hr = E_UNEXPECTED; _JumpError(hr, error, "No Connection"); } DBGPRINT(( DBG_SS_CERTVIEWI, "%hs: ielt=%d cskip=%d celt=%d\n", m_fServerOpenView? "EnumView" : "OpenView", m_fServerOpenView? m_ielt : 1, cskip, celt)); if (!m_fServerOpenView) { if (m_cColumnResultMax != m_cColumnResult) { hr = E_UNEXPECTED; _JumpError(hr, error, "Missing Result Columns"); } m_ielt = 1; __try { hr = m_pICertAdminD->OpenView( m_pwszAuthority, m_cRestriction, m_aRestriction, m_cColumnResultMax, m_aDBColumnResult, m_ielt + cskip, celt, pceltFetched, &ctbResultRows); m_fServerOpenView = TRUE; } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } if (S_FALSE != hr) { _JumpIfError(hr, error, "OpenView"); } } else { __try { hr = m_pICertAdminD->EnumView( m_pwszAuthority, m_ielt + cskip, celt, pceltFetched, &ctbResultRows); } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } if (S_FALSE != hr) { _JumpIfError(hr, error, "EnumView"); } } myRegisterMemAlloc(ctbResultRows.pb, ctbResultRows.cb, CSM_MIDLUSERALLOC); DBGPRINT(( DBG_SS_CERTVIEWI, "%hs: *pceltFetched=%d -> %d @ielt=%d -> %d\n", m_fServerOpenView? "EnumView" : "OpenView", celt, *pceltFetched, m_ielt + cskip, m_ielt + cskip + *pceltFetched)); m_ielt += cskip + *pceltFetched; *pieltNext = m_ielt; DBGPRINT(( DBG_SS_CERTVIEWI, "EnumView: celtFetched=%d ieltNext=%d cb=%d hr=%x\n", *pceltFetched, *pieltNext, ctbResultRows.cb, hr)); *pcbResultRows = ctbResultRows.cb; *ppResultRows = (CERTTRANSDBRESULTROW const *) ctbResultRows.pb; error: return(hr); } HRESULT CCertView::EnumAttributesOrExtensions( IN DWORD RowId, IN DWORD Flags, OPTIONAL IN WCHAR const *pwszLast, IN DWORD celt, OUT DWORD *pceltFetched, CERTTRANSBLOB *pctbOut) { HRESULT hr; if (NULL == pceltFetched || NULL == pctbOut) { hr = E_POINTER; _JumpError(hr, error, "NULL parm"); } if (!m_fOpenConnection) { hr = E_UNEXPECTED; _JumpError(hr, error, "No Connection"); } __try { hr = m_pICertAdminD->EnumAttributesOrExtensions( m_pwszAuthority, RowId, Flags, pwszLast, celt, pceltFetched, pctbOut); } __except(hr = myHEXCEPTIONCODE(), EXCEPTION_EXECUTE_HANDLER) { } if (S_FALSE != hr) { _JumpIfError(hr, error, "EnumAttributesOrExtensions"); } myRegisterMemAlloc(pctbOut->pb, pctbOut->cb, CSM_MIDLUSERALLOC); error: return(hr); } HRESULT CCertView::_SetErrorInfo( IN HRESULT hrError, IN WCHAR const *pwszDescription) { CSASSERT(FAILED(hrError) || S_OK == hrError || S_FALSE == hrError); if (FAILED(hrError)) { HRESULT hr; hr = DispatchSetErrorInfo( hrError, pwszDescription, wszCLASS_CERTVIEW, &IID_ICertView); CSASSERT(hr == hrError); } return(hrError); }