|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: misc.cpp
//
//--------------------------------------------------------------------------
#include <stdafx.h>
#include <float.h>
#include "certsrv.h"
#include "misc.h"
#include "clibres.h"
#include "setupids.h"
#include "csresstr.h"
#include <activeds.h>
#include <dsgetdc.h>
#include <lm.h>
#include <common.ver>
#include "urls.h"
#include "csdisp.h"
#define __dwFILE__ __dwFILE_CERTMMC_MISC_CPP__
bool operator==( const struct _QUERY_RESTRICTION& lhs, const struct _QUERY_RESTRICTION& rhs) { return 0==_wcsicmp(lhs.szField, rhs.szField) && lhs.iOperation==rhs.iOperation && variant_t(&lhs.varValue)==variant_t(&rhs.varValue); }
PQUERY_RESTRICTION QueryRestrictionFound( PQUERY_RESTRICTION pQR, PQUERY_RESTRICTION pQRListHead) { while(pQRListHead) { if(*pQR==*pQRListHead) return pQRListHead; pQRListHead = pQRListHead->pNext; } return NULL; }
// returns (if cstr.IsEmpty()) ? NULL : cstr)
LPCWSTR GetNullMachineName(CString* pcstr) { LPCWSTR szMachine = (pcstr->IsEmpty()) ? NULL : (LPCWSTR)*pcstr; return szMachine; }
BOOL FIsCurrentMachine(LPCWSTR str) { BOOL fIsCurrentMachine = FALSE; LPWSTR szName1 = NULL, szName2 = NULL; DWORD dwErr;
dwErr = myGetComputerNames(&szName1, &szName2); _JumpIfError(dwErr, error, "myGetComputerNames");
if ((str != NULL) && (wcslen(str) > 2) && (str[0] == '\\') && (str[1] == '\\') ) str = &str[2]; // skip whackwhack
// if machine specified as not current machine
if ( (NULL == str) || (str[0] == '\0') || (0 == mylstrcmpiL(str, szName1)) || (0 == mylstrcmpiL(str, szName2)) ) fIsCurrentMachine = TRUE;
error:
if (szName1) LocalFree(szName1); if (szName2) LocalFree(szName2);
return fIsCurrentMachine; }
/////////////////////////////////////////
// fxns to load/save cstrings to a streams
STDMETHODIMP CStringLoad(CString& cstr, IStream *pStm) { ASSERT(pStm); HRESULT hr;
DWORD cbSize=0;
// get cbSize (bytes)
hr = ReadOfSize(pStm, &cbSize, sizeof(cbSize)); _JumpIfError(hr, Ret, "ReadOfSize cbSize");
// get string
hr = ReadOfSize( pStm, cstr.GetBuffer(cbSize/sizeof(WCHAR)-1), // less terminator, GetBuffer adds 1 for it
cbSize); cstr.ReleaseBuffer(); // not clear why we do this...
_JumpIfError(hr, Ret, "Read cstr.GetBuffer");
if(!cstr.IsZeroTerminated()) { hr = ERROR_FILE_CORRUPT; _JumpError(hr, Ret, "zero terminated string expected"); }
Ret: return hr; }
STDMETHODIMP CStringSave( CString& cstr, IStream *pStm, BOOL /* fClearDirty */ ) { ASSERT(pStm); HRESULT hr;
// Write the string (null cstr will return 0 chars, output nullstr "")
DWORD cbSize = (cstr.GetLength()+1)*sizeof(WCHAR);
// write size in bytes
hr = WriteOfSize(pStm, &cbSize, sizeof(cbSize)); _JumpIfError(hr, error, "WriteOfSize cbSize");
// write string (null cstr will return 0 chars, output nullstr "")
hr = WriteOfSize(pStm, (LPWSTR)(LPCWSTR)cstr, cbSize); _JumpIfError(hr, error, "Write cstr");
error: return hr; }
STDMETHODIMP CStringGetSizeMax(CString& cstr, int* piSize) { *piSize = sizeof(DWORD); *piSize += (cstr.GetLength()+1)* sizeof(WCHAR);
return S_OK; }
STDMETHODIMP VariantLoad(VARIANT& var, IStream *pStm) { HRESULT hr; VARIANT varTmp; DWORD dwSize;
VariantInit(&varTmp); VariantInit(&var);
// get target variant type
hr = ReadOfSize(pStm, &var.vt, sizeof(var.vt)); _JumpIfError(hr, error, "Read type");
// get cb
hr = ReadOfSize(pStm, &dwSize, sizeof(DWORD)); _JumpIfError(hr, error, "Read cb");
varTmp.vt = VT_BSTR; varTmp.bstrVal = SysAllocStringByteLen(NULL, dwSize); _JumpIfOutOfMemory(hr, error, varTmp.bstrVal);
// get pb
hr = ReadOfSize(pStm, varTmp.bstrVal, dwSize); _JumpIfError(hr, error, "Read pb");
// change type to target type var.vt
hr = VariantChangeType(&var, &varTmp, 0, var.vt); _JumpIfError(hr, error, "VariantChangeType");
error: VariantClear(&varTmp);
return hr; }
STDMETHODIMP VariantSave( VARIANT& var, IStream *pStm, BOOL /* fClearDirty */ ) { HRESULT hr; DWORD dwSize;
VARIANT varTmp; VariantInit(&varTmp);
// write variant type
hr = WriteOfSize(pStm, &var.vt, sizeof(var.vt)); _JumpIfError(hr, error, "Write type");
// convert to bstr
hr = VariantChangeType(&varTmp, &var, 0, VT_BSTR); _JumpIfError(hr, error, "VariantChangeType");
// write cb
dwSize = SysStringByteLen(varTmp.bstrVal); hr = WriteOfSize(pStm, &dwSize, sizeof(DWORD)); _JumpIfError(hr, error, "Write cb"); // write pb
hr = WriteOfSize(pStm, varTmp.bstrVal, dwSize); _JumpIfError(hr, error, "Write pb");
error: VariantClear(&varTmp);
return hr; }
STDMETHODIMP VariantGetSizeMax(VARIANT& var, int* piSize) { HRESULT hr;
VARIANT varTmp; VariantInit(&varTmp);
// write var type, cb
*piSize = sizeof(var.vt) + sizeof(DWORD);
// write pb len: convert to bstr
hr = VariantChangeType(&varTmp, &var, 0, VT_BSTR); _JumpIfError(hr, error, "VariantChangeType");
*piSize += SysStringByteLen(varTmp.bstrVal); error: VariantClear(&varTmp);
return hr; }
DWORD AllocAndReturnConfigValue(HKEY hKey, LPCWSTR szConfigEntry, PBYTE* ppbOut, DWORD* pcbOut, DWORD* pdwType) { DWORD dwRet;
dwRet = RegQueryValueExW( hKey, szConfigEntry, NULL, pdwType, NULL, pcbOut); _JumpIfError(dwRet, Ret, "RegQueryValueExW");
ASSERT(ppbOut != NULL); *ppbOut = new BYTE[*pcbOut]; if (NULL == *ppbOut) { dwRet = (DWORD) E_OUTOFMEMORY; _JumpError(dwRet, Ret, "new"); } dwRet = RegQueryValueExW( hKey, szConfigEntry, NULL, pdwType, *ppbOut, pcbOut); if (dwRet != ERROR_SUCCESS) { delete [] *ppbOut; *ppbOut = NULL; _JumpError(dwRet, Ret, "RegQueryValueExW"); } Ret:
return dwRet; }
//////////////////////////////////////////////////////////////////
// given an error code and a console pointer, will pop error dlg
void DisplayCertSrvErrorWithContext(HWND hwnd, DWORD dwErr, UINT iRscContext) { CString cstrContext; cstrContext.LoadString(iRscContext);
DisplayCertSrvErrorWithContext(hwnd, dwErr, (LPCWSTR)cstrContext); }
void DisplayCertSrvErrorWithContext(HWND hwnd, DWORD dwErr, LPCWSTR szContext) { CString cstrTitle, cstrFullText; cstrTitle.LoadString(IDS_MSG_TITLE);
cstrFullText = szContext;
if (dwErr != ERROR_SUCCESS) { if (!cstrFullText.IsEmpty()) cstrFullText += L"\n\n";
WCHAR const *pwszError = myGetErrorMessageText(dwErr, TRUE);
cstrFullText += pwszError;
// Free the buffer
if (NULL != pwszError) { LocalFree(const_cast<WCHAR *>(pwszError)); } }
::MessageBoxW(hwnd, cstrFullText, cstrTitle, MB_OK| (S_OK!=dwErr?MB_ICONERROR:MB_ICONINFORMATION)); }
void DisplayGenericCertSrvError(HWND hwnd, DWORD dwErr) { DisplayCertSrvErrorWithContext(hwnd, dwErr, (UINT)0); }
void DisplayGenericCertSrvError(LPCONSOLE pConsole, DWORD dwErr) { ASSERT(pConsole);
WCHAR const *pwszError = myGetErrorMessageText(dwErr, TRUE);
// ...
// Display the string.
CString cstrTitle; cstrTitle.LoadString(IDS_MSG_TITLE); pConsole->MessageBoxW(pwszError, cstrTitle, MB_OK, NULL); // Free the buffer.
if (NULL != pwszError) { LocalFree(const_cast<WCHAR *>(pwszError)); } }
enum ENUM_PERIOD DurationEnumFromNonLocalizedString(LPCWSTR szPeriod) { if (0 == LSTRCMPIS(szPeriod, wszPERIODYEARS)) return ENUM_PERIOD_YEARS; if (0 == LSTRCMPIS(szPeriod, wszPERIODMONTHS)) return ENUM_PERIOD_MONTHS; if (0 == LSTRCMPIS(szPeriod, wszPERIODWEEKS)) return ENUM_PERIOD_WEEKS; if (0 == LSTRCMPIS(szPeriod, wszPERIODDAYS)) return ENUM_PERIOD_DAYS; if (0 == LSTRCMPIS(szPeriod, wszPERIODHOURS)) return ENUM_PERIOD_HOURS; if (0 == LSTRCMPIS(szPeriod, wszPERIODMINUTES)) return ENUM_PERIOD_MINUTES; if (0 == LSTRCMPIS(szPeriod, wszPERIODSECONDS)) return ENUM_PERIOD_SECONDS;
return ENUM_PERIOD_INVALID; }
BOOL StringFromDurationEnum(int iEnum, CString* pcstr, BOOL fLocalized) { if (NULL == pcstr) return FALSE;
switch (iEnum) { case(ENUM_PERIOD_YEARS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Years; else *pcstr = wszPERIODYEARS; break; case(ENUM_PERIOD_MONTHS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Months; else *pcstr = wszPERIODMONTHS; break; case(ENUM_PERIOD_WEEKS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Weeks; else *pcstr = wszPERIODWEEKS; break; case(ENUM_PERIOD_DAYS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Days; else *pcstr = wszPERIODDAYS; break; case(ENUM_PERIOD_HOURS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Hours; else *pcstr = wszPERIODHOURS; break; case(ENUM_PERIOD_MINUTES): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Minutes; else *pcstr = wszPERIODMINUTES; break; case(ENUM_PERIOD_SECONDS): if (fLocalized) *pcstr = g_pResources->m_szPeriod_Seconds; else *pcstr = wszPERIODSECONDS; break; }
if (! (pcstr->IsEmpty()) ) return TRUE;
return FALSE; }
LPCWSTR OperationToStr(int iOperation) { switch(iOperation) { case CVR_SEEK_EQ: return L"="; case CVR_SEEK_LT: return L"<"; case CVR_SEEK_LE: return L"<="; case CVR_SEEK_GE: return L">="; case CVR_SEEK_GT: return L">"; } return NULL; }
int StrToOperation(LPCWSTR szOperation) { if (0 == wcscmp(szOperation, L"=")) return CVR_SEEK_EQ; else if (0 == wcscmp(szOperation, L"<")) return CVR_SEEK_LT; else if (0 == wcscmp(szOperation, L"<=")) return CVR_SEEK_LE; else if (0 == wcscmp(szOperation, L">=")) return CVR_SEEK_GE; else if (0 == wcscmp(szOperation, L">")) return CVR_SEEK_GT;
return 0; }
// returns localized string time (even for date!)
BOOL MakeDisplayStrFromDBVariant(VARIANT* pvt, VARIANT* pvOut) { HRESULT hr; VariantInit(pvOut); LPWSTR szLocalTime = NULL;
ASSERT(pvt); ASSERT(pvOut); if ((NULL == pvt) || (NULL == pvOut)) return FALSE;
if (pvt->vt == VT_DATE) { hr = myGMTDateToWszLocalTime( &pvt->date, FALSE, &szLocalTime); _JumpIfError(hr, error, "myGMTDateToWszLocalTime"); pvOut->bstrVal = ::SysAllocString(szLocalTime); _JumpIfOutOfMemory(hr, error, pvOut->bstrVal);
pvOut->vt = VT_BSTR; } else { hr = VariantChangeType(pvOut, pvt, 0, VT_BSTR); _JumpIfError(hr, error, "VariantChangeType"); }
error: if (szLocalTime) LocalFree(szLocalTime);
return (pvOut->vt == VT_BSTR); }
DWORD CryptAlgToStr(CString* pcstrAlgName, LPCWSTR szProv, DWORD dwProvType, DWORD dwAlg) { DWORD dwRet; HCRYPTPROV hCrypt = NULL; DWORD Flags = CRYPT_FIRST; DWORD cb; PROV_ENUMALGS Alg; pcstrAlgName->Empty();
if (!CryptAcquireContext( &hCrypt, NULL, szProv, dwProvType, CRYPT_VERIFYCONTEXT)) { dwRet = GetLastError(); _JumpError(dwRet, Ret, "CryptAcquireContext"); }
while (TRUE) { cb = sizeof(Alg); if (!CryptGetProvParam(hCrypt, PP_ENUMALGS, (BYTE *) &Alg, &cb, Flags)) break;
if (Alg.aiAlgid == dwAlg) { *pcstrAlgName = Alg.szName; break; } Flags = 0; }
dwRet = ERROR_SUCCESS; Ret:
if (hCrypt) CryptReleaseContext(hCrypt, 0);
return dwRet; }
LPCWSTR FindUnlocalizedColName(LPCWSTR strColumn) { HRESULT hr = S_OK; LPCWSTR szTrial = NULL;
for(DWORD dwIndex=0; (S_OK == hr); dwIndex++) { hr = myGetColumnName( dwIndex, FALSE, // unlocalized
&szTrial); _PrintIfError(hr, "myGetColumnName"); if ((S_OK == hr) && (NULL != szTrial)) { if (0 == wcscmp(strColumn, szTrial)) return szTrial; } } return NULL; }
// given field, op, variant, copies into data struct
PQUERY_RESTRICTION NewQueryRestriction(LPCWSTR szField, UINT iOp, VARIANT* pvarValue) { DWORD dwLen = sizeof(QUERY_RESTRICTION); dwLen += WSZ_BYTECOUNT(szField);
PQUERY_RESTRICTION pNew = (QUERY_RESTRICTION*)LocalAlloc(LPTR, dwLen); if (NULL == pNew) return NULL;
PBYTE pCurWrite = ((PBYTE)pNew) + sizeof(QUERY_RESTRICTION) ; pNew->szField = (LPWSTR)pCurWrite; wcscpy(pNew->szField, szField);
pNew->iOperation = iOp;
// copy data pointed to by pvarValue
CopyMemory(&pNew->varValue, pvarValue, sizeof(VARIANT));
// good enough except for string -- alloc for it
if (VT_BSTR == pvarValue->vt) { pNew->varValue.bstrVal = SysAllocString(pvarValue->bstrVal); if (NULL == pNew->varValue.bstrVal) { // failed!
FreeQueryRestriction(pNew); pNew = NULL; } }
return pNew; }
void FreeQueryRestriction(PQUERY_RESTRICTION pQR) { VariantClear(&pQR->varValue); LocalFree(pQR); }
void FreeQueryRestrictionList(PQUERY_RESTRICTION pQR) { PQUERY_RESTRICTION pTmp; while(pQR) { pTmp = pQR->pNext; FreeQueryRestriction(pQR); pQR = pTmp; } }
void ListInsertAtEnd(void** ppList, void* pElt) { if (pElt != NULL) { // he's always at the end of the list
((PELT_PTR)pElt)->pNext = NULL; void* pCurPtr = *ppList;
if (*ppList == NULL) { *ppList = pElt; } else { while( ((PELT_PTR)pCurPtr)->pNext != NULL ) { pCurPtr = ((PELT_PTR)pCurPtr)->pNext; }
((PELT_PTR)pCurPtr)->pNext = (PELT_PTR) pElt; } }
return; }
// dwIndex should be zero at first, then passed in for each consecutive call
LPWSTR RegEnumKeyContaining( HKEY hBaseKey, LPCWSTR szContainsString, DWORD* pdwIndex) { HRESULT hr = S_OK; LPWSTR szBuf = NULL; DWORD cbBuf = 0, cbBufUsed; FILETIME ft; ASSERT(pdwIndex);
hr = RegQueryInfoKey( hBaseKey, NULL, NULL, // classes
NULL, // reserved
NULL, // cSubkeys
&cbBuf, // maxsubkeylen in chars (not counting null term)
NULL, // max class len
NULL, // num values
NULL, // max value name len
NULL, // max value len
NULL, // sec descr
NULL // last filetime
); _JumpIfError(hr, Ret, "RegQueryInfoKey");
cbBuf += 1; cbBuf *= sizeof(WCHAR); szBuf = (LPWSTR)LocalAlloc(LMEM_FIXED, cbBuf); _JumpIfOutOfMemory(hr, Ret, szBuf);
for (; ; (*pdwIndex)++) { // tell api how much memory we have (incl NULL char)
cbBufUsed = cbBuf;
hr = RegEnumKeyEx( hBaseKey, *pdwIndex, szBuf, &cbBufUsed, // doesn't get updated in small buffer case?!
NULL, NULL, NULL, &ft); _JumpIfError2(hr, Ret, "RegEnumKeyEx", ERROR_NO_MORE_ITEMS); // we have data, check if it is one we're interested in
if (NULL != wcsstr(szBuf, szContainsString)) break; }
// don't point at this one again
(*pdwIndex)++; hr = S_OK;
Ret: if (S_OK != hr) { LocalFree(szBuf); szBuf = NULL; }
return ( szBuf ); }
DISPLAYSTRING_EXPANSION g_displayStrings[11] = { { wszFCSAPARM_SERVERDNSNAME, IDS_TOKEN_SERVERDNSNAME, IDS_TOKENDESC_SERVERDNSNAME }, //%1
{ wszFCSAPARM_SERVERSHORTNAME, IDS_TOKEN_SERVERSHORTNAME, IDS_TOKENDESC_SERVERSHORTNAME }, //%2
{ wszFCSAPARM_SANITIZEDCANAME, IDS_TOKEN_SANITIZEDCANAME, IDS_TOKENDESC_SANITIZEDCANAME }, //%3
{ wszFCSAPARM_CERTFILENAMESUFFIX, IDS_TOKEN_CERTFILENAMESUFFIX, IDS_TOKENDESC_CERTFILENAMESUFFIX }, //%4
{ L"", IDS_DESCR_UNKNOWN, IDS_DESCR_UNKNOWN }, // %5 not available
{ wszFCSAPARM_CONFIGDN, IDS_TOKEN_CONFIGDN, IDS_TOKENDESC_CONFIGDN }, //%6
{ wszFCSAPARM_SANITIZEDCANAMEHASH, IDS_TOKEN_SANITIZEDCANAMEHASH, IDS_TOKENDESC_SANITIZEDCANAMEHASH }, //%7
{ wszFCSAPARM_CRLFILENAMESUFFIX, IDS_TOKEN_CRLFILENAMESUFFIX, IDS_TOKENDESC_CRLFILENAMESUFFIX }, //%8
{ wszFCSAPARM_CRLDELTAFILENAMESUFFIX, IDS_TOKEN_CRLDELTAFILENAMESUFFIX,IDS_TOKENDESC_CRLDELTAFILENAMESUFFIX}, //%9
{ wszFCSAPARM_DSCRLATTRIBUTE, IDS_TOKEN_DSCRLATTRIBUTE, IDS_TOKENDESC_DSCRLATTRIBUTE }, //%10
{ wszFCSAPARM_DSCACERTATTRIBUTE, IDS_TOKEN_DSCACERTATTRIBUTE, IDS_TOKENDESC_DSCACERTATTRIBUTE }, //%11
};
/////////////////////////////////////////
// fxns to load resources automatically
CLocalizedResources *g_pResources = NULL;
CLocalizedResources::CLocalizedResources() { m_fLoaded = FALSE; }
BOOL CLocalizedResources::Load() { if (!m_fLoaded) { HINSTANCE hRsrc = AfxGetResourceHandle();
myVerifyResourceStrings(g_hInstance);
// Load strings from resources
m_ColumnHead_Name.LoadString(IDS_COLUMN_NAME); m_ColumnHead_Size.LoadString(IDS_COLUMN_SIZE); m_ColumnHead_Type.LoadString(IDS_COLUMN_TYPE); m_ColumnHead_Description.LoadString(IDS_COLUMN_DESCRIPTION);
m_DescrStr_CA.LoadString(IDS_DESCR_CA); m_DescrStr_Unknown.LoadString(IDS_DESCR_UNKNOWN);
m_szFilterApplied.LoadString(IDS_STATUSBAR_FILTER_APPLIED); m_szSortedAscendingTemplate.LoadString(IDS_STATUSBAR_SORTEDBY_ASCEND); m_szSortedDescendingTemplate.LoadString(IDS_STATUSBAR_SORTEDBY_DESCEND); m_szStoppedServerMsg.LoadString(IDS_STOPPED_SERVER_MSG); m_szStatusBarErrorFormat.LoadString(IDS_STATUSBAR_ERRORTEMPLATE);
m_szRevokeReason_Unspecified.LoadString(IDS_CRL_REASON_UNSPECIFIED); m_szRevokeReason_KeyCompromise.LoadString(IDS_CRL_REASON_KEY_COMPROMISE); m_szRevokeReason_CaCompromise.LoadString(IDS_CRL_REASON_CA_COMPROMISE); m_szRevokeReason_Affiliation.LoadString(IDS_CRL_REASON_AFFILIATION_CHANGED); m_szRevokeReason_Superseded.LoadString(IDS_CRL_REASON_SUPERSEDED); m_szRevokeReason_Cessatation.LoadString(IDS_CRL_REASON_CESSATION_OF_OPERATION); m_szRevokeReason_CertHold.LoadString(IDS_CRL_REASON_CERTIFICATE_HOLD); m_szRevokeReason_RemoveFromCRL.LoadString(IDS_CRL_REASON_REMOVE_FROM_CRL);
m_szPeriod_Seconds.LoadString(IDS_PERIOD_SECONDS); m_szPeriod_Minutes.LoadString(IDS_PERIOD_MINUTES); m_szPeriod_Hours.LoadString(IDS_PERIOD_HOURS); m_szPeriod_Days.LoadString(IDS_PERIOD_DAYS); m_szPeriod_Weeks.LoadString(IDS_PERIOD_WEEKS); m_szPeriod_Months.LoadString(IDS_PERIOD_MONTHS); m_szPeriod_Years.LoadString(IDS_PERIOD_YEARS);
m_szYes.LoadString(IDS_YES);
// Load the bitmaps from the dll
m_bmpSvrMgrToolbar1.LoadBitmap(IDB_TOOLBAR_SVRMGR1);
// load view strings to struct members, point to struct members
int i;
// viewResult items
for(i=0; ((viewResultItems[i].item.strName != NULL) && (viewResultItems[i].item.strStatusBarText != NULL)); i++) { LoadString(hRsrc, viewResultItems[i].uiString1, viewResultItems[i].szString1, ARRAYSIZE(viewResultItems[i].szString1)); viewResultItems[i].item.strName = viewResultItems[i].szString1;
LoadString(hRsrc, viewResultItems[i].uiString2, viewResultItems[i].szString2, ARRAYSIZE(viewResultItems[i].szString2)); viewResultItems[i].item.strStatusBarText = viewResultItems[i].szString2; } // taskResultItemsSingleSel
for(i=0; ((taskResultItemsSingleSel[i].myitem.item.strName != NULL) && (taskResultItemsSingleSel[i].myitem.item.strStatusBarText != NULL)); i++) { LoadString(hRsrc, taskResultItemsSingleSel[i].myitem.uiString1, taskResultItemsSingleSel[i].myitem.szString1, ARRAYSIZE(taskResultItemsSingleSel[i].myitem.szString1)); taskResultItemsSingleSel[i].myitem.item.strName = taskResultItemsSingleSel[i].myitem.szString1;
LoadString(hRsrc, taskResultItemsSingleSel[i].myitem.uiString2, taskResultItemsSingleSel[i].myitem.szString2, ARRAYSIZE(taskResultItemsSingleSel[i].myitem.szString2)); taskResultItemsSingleSel[i].myitem.item.strStatusBarText = taskResultItemsSingleSel[i].myitem.szString2; }
// task start/stop
for(i=0; ((taskStartStop[i].item.strName != NULL) && (taskStartStop[i].item.strStatusBarText != NULL)); i++) { LoadString(hRsrc, taskStartStop[i].uiString1, taskStartStop[i].szString1, ARRAYSIZE(taskStartStop[i].szString1)); taskStartStop[i].item.strName = taskStartStop[i].szString1;
LoadString(hRsrc, taskStartStop[i].uiString2, taskStartStop[i].szString2, ARRAYSIZE(taskStartStop[i].szString2)); taskStartStop[i].item.strStatusBarText = taskStartStop[i].szString2; }
// taskitems
for(i=0; ((taskItems[i].myitem.item.strName != NULL) && (taskItems[i].myitem.item.strStatusBarText != NULL)); i++) { LoadString(hRsrc, taskItems[i].myitem.uiString1, taskItems[i].myitem.szString1, ARRAYSIZE(taskItems[i].myitem.szString1)); taskItems[i].myitem.item.strName = taskItems[i].myitem.szString1;
LoadString(hRsrc, taskItems[i].myitem.uiString2, taskItems[i].myitem.szString2, ARRAYSIZE(taskItems[i].myitem.szString2)); taskItems[i].myitem.item.strStatusBarText = taskItems[i].myitem.szString2; }
// topitems
for(i=0; ((topItems[i].myitem.item.strName != NULL) && (topItems[i].myitem.item.strStatusBarText != NULL)); i++) { LoadString(hRsrc, topItems[i].myitem.uiString1, topItems[i].myitem.szString1, ARRAYSIZE(topItems[i].myitem.szString1)); topItems[i].myitem.item.strName = topItems[i].myitem.szString1;
LoadString(hRsrc, topItems[i].myitem.uiString2, topItems[i].myitem.szString2, ARRAYSIZE(topItems[i].myitem.szString2)); topItems[i].myitem.item.strStatusBarText = topItems[i].myitem.szString2; }
for (i=0; ((SvrMgrToolbar1Buttons[i].item.lpButtonText != NULL) && (SvrMgrToolbar1Buttons[i].item.lpTooltipText != NULL)); i++) { LoadString(hRsrc, SvrMgrToolbar1Buttons[i].uiString1, SvrMgrToolbar1Buttons[i].szString1, ARRAYSIZE(SvrMgrToolbar1Buttons[i].szString1)); SvrMgrToolbar1Buttons[i].item.lpButtonText = SvrMgrToolbar1Buttons[i].szString1;
LoadString(hRsrc, SvrMgrToolbar1Buttons[i].uiString2, SvrMgrToolbar1Buttons[i].szString2, ARRAYSIZE(SvrMgrToolbar1Buttons[i].szString2)); SvrMgrToolbar1Buttons[i].item.lpTooltipText = SvrMgrToolbar1Buttons[i].szString2; }
// load replacement tokens
for (i=0; i<DISPLAYSTRINGS_TOKEN_COUNT; i++) { g_displayStrings[i].pcstrExpansionString = new CString; if (g_displayStrings[i].pcstrExpansionString != NULL) g_displayStrings[i].pcstrExpansionString->LoadString(g_displayStrings[i].uTokenID);
g_displayStrings[i].pcstrExpansionStringDescr = new CString; if (g_displayStrings[i].pcstrExpansionStringDescr != NULL) g_displayStrings[i].pcstrExpansionStringDescr->LoadString(g_displayStrings[i].uTokenDescrID); }
m_fLoaded = TRUE; }
return m_fLoaded; }
CLocalizedResources::~CLocalizedResources() { m_fLoaded = FALSE;
for (int i=0; i<DISPLAYSTRINGS_TOKEN_COUNT; i++) { if (g_displayStrings[i].pcstrExpansionString) delete g_displayStrings[i].pcstrExpansionString;
if (g_displayStrings[i].pcstrExpansionStringDescr) delete g_displayStrings[i].pcstrExpansionStringDescr; }
}
HRESULT ReadOfSize(IStream* pStm, void* pbData, ULONG cbData) { HRESULT hr; ULONG nBytesRead; hr = pStm->Read(pbData, cbData, &nBytesRead); if ((hr == S_OK) && (nBytesRead != cbData)) hr = HRESULT_FROM_WIN32(ERROR_HANDLE_EOF); return hr; }
HRESULT WriteOfSize(IStream* pStm, void* pbData, ULONG cbData) { HRESULT hr; ULONG nBytesWritten; hr = pStm->Write(pbData, cbData, &nBytesWritten); if ((hr == S_OK) && (nBytesWritten != cbData)) hr = HRESULT_FROM_WIN32(ERROR_HANDLE_DISK_FULL); return hr; }
HRESULT myOIDToName( IN WCHAR const *pwszObjId, OUT LPWSTR* pszName) { HRESULT hr = S_OK; WCHAR const *pwszName1 = L""; WCHAR const *pwszName2; WCHAR *pwszT = NULL; WCHAR rgwchName[64]; if (pszName == NULL) { hr = E_POINTER; _JumpError(hr, error, "pszName NULL"); }
pwszT = (LPWSTR) LocalAlloc(LMEM_FIXED, (1 + 1 + wcslen(pwszObjId)) * sizeof(WCHAR)); if (NULL == pwszT) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "no memory for skip counts array"); } wcscpy(&pwszT[1], pwszObjId); *pwszT = L'+'; pwszName1 = myGetOIDName(pwszT); // Group OID lookup
*pwszT = L'-'; pwszName2 = myGetOIDName(pwszT); // Generic OID lookup
if (0 == mylstrcmpiL(pwszName1, pwszName2)) { pwszName2 = L""; // display only one if they're the same
} if (L'\0' == *pwszName1) { pwszName1 = pwszName2; pwszName2 = L""; } if (L'\0' != *pwszName2 && ARRAYSIZE(rgwchName) > wcslen(pwszName1) + wcslen(pwszName2) + 3) { wcscpy(rgwchName, pwszName1); wcscat(rgwchName, L" " wszLPAREN); wcscat(rgwchName, pwszName2); wcscat(rgwchName, wszRPAREN); pwszName1 = rgwchName; }
*pszName = (LPWSTR)LocalAlloc(LMEM_FIXED, (wcslen(pwszName1)+1)*sizeof(WCHAR)); if (NULL == *pszName) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "pszName"); } wcscpy(*pszName, pwszName1); error: if (NULL != pwszT) { LocalFree(pwszT); }
return hr; }
#include "csdisp.h"
HRESULT myDumpFormattedObject( IN WCHAR const *pwszObjId, IN BYTE const *pbObject, IN DWORD cbObject, OUT LPWSTR* ppwszFormatted) { HRESULT hr = S_OK; char * pszObjId = NULL; DWORD cbFormatted;
if (ppwszFormatted == NULL) { hr = E_POINTER; _JumpError(hr, error, "NULL param"); } if (!ConvertWszToSz(&pszObjId, pwszObjId, -1)) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "ConvertWszToSz"); }
// format the object using the installed formatting function
if (!CryptFormatObject( X509_ASN_ENCODING, 0, CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX, NULL, pszObjId, pbObject, cbObject, NULL, &cbFormatted)) { hr = myHLastError(); _JumpIfError(hr, error, "CryptFormatObject"); } *ppwszFormatted = (WCHAR *) LocalAlloc(LMEM_FIXED, cbFormatted); if (NULL == *ppwszFormatted) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "LocalAlloc"); } if (!CryptFormatObject( X509_ASN_ENCODING, 0, CRYPT_FORMAT_STR_MULTI_LINE | CRYPT_FORMAT_STR_NO_HEX, NULL, pszObjId, pbObject, cbObject, *ppwszFormatted, &cbFormatted)) { hr = myHLastError(); _JumpError(hr, error, "CryptFormatObject"); }
/*
if (g_fVerbose) { if (0 == strcmp(szOID_SUBJECT_ALT_NAME, pszObjId) || 0 == strcmp(szOID_SUBJECT_ALT_NAME2, pszObjId) || 0 == strcmp(szOID_ISSUER_ALT_NAME, pszObjId) || 0 == strcmp(szOID_ISSUER_ALT_NAME2, pszObjId)) { DumpAltName(pbObject, cbObject); } } */ error: if (HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) == hr || CRYPT_E_ASN1_BADTAG == hr) { // fix up nonfatal errors
CString cstrUnknown; cstrUnknown.LoadString(IDS_UNKNOWN_EXTENSION); hr = myDupString((LPCWSTR)cstrUnknown, ppwszFormatted); _PrintIfError(hr, "myDupString failure"); }
if (pszObjId) LocalFree(pszObjId);
return hr; }
void InplaceStripControlChars(WCHAR* szString) { // remove \r and \n AND \t formatting through end-of-string
if (NULL != szString) { while (*szString != L'\0') { switch(*szString) { case L'\r': case L'\n': case L'\t': *szString = L' '; break; } szString++; } } }
HANDLE EnablePrivileges(LPCWSTR ppcwszPrivileges[], ULONG cPrivileges) { BOOL fResult = FALSE; HANDLE hToken = INVALID_HANDLE_VALUE; HANDLE hOriginalThreadToken = INVALID_HANDLE_VALUE; PTOKEN_PRIVILEGES ptp; ULONG nBufferSize;
// Note that TOKEN_PRIVILEGES includes a single LUID_AND_ATTRIBUTES
nBufferSize = sizeof(TOKEN_PRIVILEGES) + (cPrivileges - 1)*sizeof(LUID_AND_ATTRIBUTES); ptp = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, nBufferSize); if (!ptp) return INVALID_HANDLE_VALUE; //
// Initialize the Privileges Structure
//
ptp->PrivilegeCount = cPrivileges; for (ULONG i = 0; i < cPrivileges; i++) { fResult = LookupPrivilegeValue(NULL, ppcwszPrivileges[i], &ptp->Privileges[i].Luid); if (!fResult) break; ptp->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED; }
if(fResult) { //
// Open the Token
//
hToken = hOriginalThreadToken = INVALID_HANDLE_VALUE; fResult = OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken); if (fResult) hOriginalThreadToken = hToken; // Remember the thread token
else fResult = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &hToken); }
if (fResult) { HANDLE hNewToken;
//
// Duplicate that Token
//
fResult = DuplicateTokenEx(hToken, TOKEN_IMPERSONATE | TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, NULL, // PSECURITY_ATTRIBUTES
SecurityImpersonation, // SECURITY_IMPERSONATION_LEVEL
TokenImpersonation, // TokenType
&hNewToken); // Duplicate token
if (fResult) { //
// Add new privileges
//
fResult = AdjustTokenPrivileges(hNewToken, // TokenHandle
FALSE, // DisableAllPrivileges
ptp, // NewState
0, // BufferLength
NULL, // PreviousState
NULL); // ReturnLength
if (fResult) { //
// Begin impersonating with the new token
//
fResult = SetThreadToken(NULL, hNewToken); }
CloseHandle(hNewToken); } }
// If something failed, don't return a token
if (!fResult) hOriginalThreadToken = INVALID_HANDLE_VALUE;
// Close the original token if we aren't returning it
if (hOriginalThreadToken == INVALID_HANDLE_VALUE && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
// If we succeeded, but there was no original thread token,
// return NULL to indicate we need to do SetThreadToken(NULL, NULL)
// to release privs.
if (fResult && hOriginalThreadToken == INVALID_HANDLE_VALUE) hOriginalThreadToken = NULL;
LocalFree(ptp);
return hOriginalThreadToken; }
void ReleasePrivileges(HANDLE hToken) { BOOL fResult; if (INVALID_HANDLE_VALUE != hToken) { fResult = SetThreadToken(NULL, hToken); if (hToken) CloseHandle(hToken); } }
HRESULT myGetActiveModule( CertSvrCA *pCA, IN BOOL fPolicyModule, IN DWORD Index, OPTIONAL OUT LPOLESTR *ppwszProgIdModule, // CoTaskMem*
OPTIONAL OUT CLSID *pclsidModule) { HRESULT hr; WCHAR *pwsz; variant_t var; hr = pCA->GetConfigEntry( fPolicyModule?wszREGKEYPOLICYMODULES:wszREGKEYEXITMODULES, wszREGACTIVE, &var); _JumpIfError(hr, error, "GetConfigEntry");
hr = HRESULT_FROM_WIN32(ERROR_MOD_NOT_FOUND);
if(V_VT(&var)==VT_BSTR) { pwsz = V_BSTR(&var); } else if(V_VT(&var)==(VT_ARRAY|VT_BSTR)) { SafeArrayEnum<BSTR> saenum(V_ARRAY(&var)); hr = saenum.GetAt(Index, pwsz); _JumpIfError(hr, error, "GetConfigEntry"); } else { _JumpError(hr, error, "Bad active entry type"); }
if(!pwsz) { _JumpError(hr, error, "empty entry"); }
if (NULL != pclsidModule) { hr = CLSIDFromProgID(pwsz, pclsidModule); _JumpIfError(hr, error, "CLSIDFromProgID"); } if (NULL != ppwszProgIdModule) { *ppwszProgIdModule = (LPOLESTR) CoTaskMemAlloc( (wcslen(pwsz) + 1) * sizeof(WCHAR)); if (NULL == *ppwszProgIdModule) { hr = E_OUTOFMEMORY; _JumpError(hr, error, "CoTaskMemAlloc"); } wcscpy(*ppwszProgIdModule, pwsz); } hr = S_OK; // not reset after ERROR_MOD_NOT_FOUND in all cases
error: return(hr); }
HRESULT FindComputerObjectSid( LPCWSTR pcwszCAComputerDNSName, PSID &pSid) { HRESULT hr = S_OK; ADS_SEARCHPREF_INFO asi[1]; IDirectorySearch *pSearch = NULL; LPWSTR pwszAttr = L"objectSid"; ADS_SEARCH_HANDLE hADS = NULL; static LPCWSTR pwszgc = L"GC://"; static LPCWSTR pwszformat = L"(&(objectClass=computer)(servicePrincipalName=host/%ws))"; LPWSTR pwszSearchFilter = NULL; LPWSTR pwszGC = NULL; DWORD dwres; PDOMAIN_CONTROLLER_INFO pdci = NULL; ADS_SEARCH_COLUMN col; dwres = DsGetDcName( NULL, NULL, NULL, NULL, DS_RETURN_DNS_NAME|DS_DIRECTORY_SERVICE_REQUIRED, &pdci); if(NO_ERROR != dwres) { hr = myHError(dwres); _JumpIfError(hr, error, "DsGetDcName"); } pwszGC = (LPWSTR)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*(wcslen(pwszgc)+wcslen(pdci->DnsForestName)+1)); _JumpIfAllocFailed(pwszGC, error);
wcscpy(pwszGC, pwszgc); wcscat(pwszGC, pdci->DnsForestName);
hr = ADsGetObject(pwszGC, IID_IDirectorySearch, (void**)&pSearch); _JumpIfError(hr, error, "ADsGetObject(GC:)");
asi[0].dwSearchPref = ADS_SEARCHPREF_SEARCH_SCOPE; asi[0].vValue.dwType = ADSTYPE_INTEGER; asi[0].vValue.Integer = ADS_SCOPE_SUBTREE;
hr = pSearch->SetSearchPreference(asi, 1); _JumpIfError(hr, error, "SetSearchPreference");
pwszSearchFilter = (LPWSTR)LocalAlloc(LMEM_FIXED, sizeof(WCHAR)*(wcslen(pwszformat)+wcslen(pcwszCAComputerDNSName)+1));
wsprintf(pwszSearchFilter, pwszformat, pcwszCAComputerDNSName); hr = pSearch->ExecuteSearch( pwszSearchFilter, &pwszAttr, 1, &hADS); _JumpIfErrorStr(hr, error, "ExecuteSearch", pwszSearchFilter);
hr = pSearch->GetFirstRow(hADS); _JumpIfError(hr, error, "GetFirstRow");
hr = pSearch->GetColumn(hADS, pwszAttr, &col); _JumpIfErrorStr(hr, error, "GetColumn", pwszAttr);
CSASSERT(IsValidSid(col.pADsValues[0].OctetString.lpValue)); CSASSERT(GetLengthSid(col.pADsValues[0].OctetString.lpValue)== col.pADsValues[0].OctetString.dwLength);
pSid = LocalAlloc(LMEM_FIXED, col.pADsValues[0].OctetString.dwLength); _JumpIfAllocFailed(pSid, error);
CopySid(col.pADsValues[0].OctetString.dwLength, pSid, col.pADsValues[0].OctetString.lpValue);
error:
if(pdci) NetApiBufferFree(pdci);
if(pSearch) { pSearch->FreeColumn(&col);
if(hADS) pSearch->CloseSearchHandle(hADS); pSearch->Release(); } LOCAL_FREE(pwszSearchFilter); LOCAL_FREE(pwszGC); return hr; }
HRESULT IsUserDomainAdministrator(BOOL* pfIsAdministrator) { HRESULT hr = S_OK;
*pfIsAdministrator = FALSE;
PSID psidAdministrators; SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
BOOL bResult = AllocateAndInitializeSid (&siaNtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdministrators); if ( bResult ) { bResult = CheckTokenMembership (0, psidAdministrators, pfIsAdministrator); ASSERT (bResult); if ( !bResult ) { hr = myHLastError (); _PrintError(hr, "CheckTokenMembership"); } FreeSid (psidAdministrators); } else { hr = myHLastError (); _PrintError(hr, "AllocateAndInitializeSid"); } return hr; }
BOOL RestartService(HWND hWnd, CertSvrMachine* pMachine) { // notify user we can't apply immediately
CString cstrText; cstrText.LoadString(IDS_CONFIRM_SERVICE_RESTART);
if (IDYES == ::MessageBox(hWnd, (LPCWSTR)cstrText, (LPCWSTR)g_pResources->m_DescrStr_CA, MB_YESNO | MB_ICONWARNING )) { DWORD dwErr;
// stop the service
if (pMachine->IsCertSvrServiceRunning()) pMachine->CertSvrStartStopService(hWnd, FALSE);
// start the serviec
dwErr = pMachine->CertSvrStartStopService(hWnd, TRUE); if (S_OK != dwErr) DisplayGenericCertSrvError(hWnd, dwErr);
return TRUE; }
return FALSE; // didn't restart
}
static BOOL s_fLogOpened = FALSE;
VOID LogOpen( IN BOOL fForceOpen) { BOOL fOpenLog;
DbgPrintfInit("+"); // reinitialize debug print mask first
fOpenLog = DbgIsSSActive(DBG_SS_OPENLOG);
if (fOpenLog || fForceOpen) { if (!s_fLogOpened) { csiLogOpen("+certmmc.log"); s_fLogOpened = TRUE; CSILOGFILEVERSION(0, L"certmmc.dll", szCSVER_STR); } } }
VOID LogClose() { if (s_fLogOpened) { csiLogClose(); s_fLogOpened = FALSE; } }
|