Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

593 lines
14 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1998 - 1999
//
// File: misc.cpp
//
//--------------------------------------------------------------------------
#include <stdafx.h>
// sddl.h requires this value to be at least
// 0x0500. Bump it up if necessary. NOTE: This
// 'bump' comes after all other H files that may
// be sensitive to this value.
#if(_WIN32_WINNT < 0x500)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#include "tmpllist.h"
#include <sddl.h>
#include <shlobj.h>
#include <dsclient.h>
#include <dsgetdc.h>
#include <lm.h>
#include <lmapibuf.h>
#include <objsel.h>
#define __dwFILE__ __dwFILE_CAPESNPN_MISC_CPP__
CLIPFORMAT g_cfDsObjectPicker = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
// returns (if cstr.IsEmpty()) ? NULL : cstr)
LPCWSTR GetNullMachineName(CString* pcstr)
{
LPCWSTR szMachine = (pcstr->IsEmpty()) ? NULL : (LPCWSTR)*pcstr;
return szMachine;
}
/////////////////////////////////////////
// fxns to load/save cstrings to a streams
STDMETHODIMP CStringLoad(CString& cstr, IStream *pStm)
{
ASSERT(pStm);
HRESULT hr;
DWORD cbSize=0;
ULONG nBytesRead;
// get cbSize (bytes)
hr = pStm->Read(&cbSize, sizeof(cbSize), &nBytesRead);
ASSERT(SUCCEEDED(hr) && (nBytesRead == sizeof(cbSize)) );
if (FAILED(hr))
return E_FAIL;
// get string
hr = pStm->Read(cstr.GetBuffer(cbSize), cbSize, &nBytesRead);
ASSERT(SUCCEEDED(hr) && (nBytesRead == cbSize));
cstr.ReleaseBuffer();
return SUCCEEDED(hr) ? S_OK : E_FAIL;
}
STDMETHODIMP CStringSave(CString& cstr, IStream *pStm, BOOL fClearDirty)
{
// Write the string
DWORD cbSize = (cstr.GetLength()+1)*sizeof(WCHAR);
ULONG nBytesWritten;
HRESULT hr;
// write size in bytes
hr = pStm->Write(&cbSize, sizeof(cbSize), &nBytesWritten);
ASSERT(SUCCEEDED(hr) && (nBytesWritten == sizeof(cbSize)) );
if (FAILED(hr))
return STG_E_CANTSAVE;
// write string
hr = pStm->Write((LPCWSTR)cstr, cbSize, &nBytesWritten);
ASSERT(SUCCEEDED(hr) && (nBytesWritten == cbSize));
// Verify that the write operation succeeded
return SUCCEEDED(hr) ? S_OK : STG_E_CANTSAVE;
}
LPSTR AllocAndCopyStr(LPCSTR psz)
{
LPSTR pszReturn;
pszReturn = (LPSTR) new(BYTE[strlen(psz)+1]);
if(pszReturn)
{
strcpy(pszReturn, psz);
}
return pszReturn;
}
LPWSTR AllocAndCopyStr(LPCWSTR pwsz)
{
LPWSTR pwszReturn;
pwszReturn = (LPWSTR) new(WCHAR[wcslen(pwsz)+1]);
if(pwszReturn)
{
wcscpy(pwszReturn, pwsz);
}
return pwszReturn;
}
LPWSTR BuildErrorMessage(DWORD dwErr)
{
LPWSTR lpMsgBuf = NULL;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dwErr,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPWSTR) &lpMsgBuf,
0,
NULL );
return lpMsgBuf;
}
//////////////////////////////////////////////////////////////////
// given an error code and a console pointer, will pop error dlg
void DisplayGenericCertSrvError(LPCONSOLE2 pConsole, DWORD dwErr)
{
ASSERT(pConsole);
LPWSTR lpMsgBuf = BuildErrorMessage(dwErr);
if(lpMsgBuf)
{
// ...
// Display the string.
pConsole->MessageBoxW(lpMsgBuf, L"Certificate Services Error", MB_OK | MB_ICONINFORMATION, NULL);
// Free the buffer.
LocalFree( lpMsgBuf );
}
}
// returns localized, stringized time
BOOL FileTimeToLocalTimeString(FILETIME* pftGMT, LPWSTR* ppszTmp)
{
FILETIME ftLocal;
if (FileTimeToLocalFileTime(pftGMT, &ftLocal))
{
SYSTEMTIME sysLocal;
if (FileTimeToSystemTime(
&ftLocal,
&sysLocal))
{
WCHAR rgTmpDate[128], rgTmpTime[128];
DWORD dwLen;
dwLen = GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &sysLocal,
NULL, rgTmpDate, ARRAYLEN(rgTmpDate));
dwLen += GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &sysLocal,
NULL, rgTmpTime, ARRAYLEN(rgTmpTime));
dwLen += sizeof(L" ");
*ppszTmp = new WCHAR[dwLen];
if(*ppszTmp == NULL)
{
return FALSE;
}
wcscpy(*ppszTmp, rgTmpDate);
wcscat(*ppszTmp, L" ");
wcscat(*ppszTmp, rgTmpTime);
}
}
return TRUE;
}
void MyErrorBox(HWND hwndParent, UINT nIDText, UINT nIDCaption, DWORD dwErrorCode)
{
CString cstrTitle, cstrFormatText, cstrFullText;
cstrTitle.LoadString(nIDCaption);
cstrFormatText.LoadString(nIDText);
WCHAR const *pwszError = NULL;
if (dwErrorCode != ERROR_SUCCESS)
{
pwszError = myGetErrorMessageText(dwErrorCode, TRUE);
cstrFullText.Format(cstrFormatText, pwszError);
// Free the buffer
if (NULL != pwszError)
{
LocalFree(const_cast<WCHAR *>(pwszError));
}
}
::MessageBoxW(hwndParent, cstrFullText, cstrTitle, MB_OK | MB_ICONERROR);
}
BOOL MyGetOIDInfo(LPWSTR string, DWORD stringSize, LPSTR pszObjId)
{
PCCRYPT_OID_INFO pOIDInfo;
pOIDInfo = CryptFindOIDInfo(
CRYPT_OID_INFO_OID_KEY,
pszObjId,
0);
if (pOIDInfo != NULL)
{
if (wcslen(pOIDInfo->pwszName)+1 <= stringSize)
{
wcscpy(string, pOIDInfo->pwszName);
}
else
{
return FALSE;
}
}
else
{
return (MultiByteToWideChar(CP_ACP, 0, pszObjId, -1, string, stringSize) != 0);
}
return TRUE;
}
BOOL MyGetEnhancedKeyUsages(HCERTTYPE hCertType, CString **aszUsages, DWORD *cUsages, BOOL *pfCritical, BOOL fGetOIDSNotNames)
{
PCERT_EXTENSIONS pCertExtensions;
CERT_ENHKEY_USAGE *pehku;
DWORD cb = 0;
WCHAR OIDName[256];
unsigned int i;
LPWSTR pwszOID;
HRESULT hr;
CSASSERT(cUsages);
if(aszUsages)
*aszUsages = NULL;
hr = CAGetCertTypeExtensionsEx(hCertType, CT_EXTENSION_EKU, NULL, &pCertExtensions);
if(hr != S_OK)
{
return FALSE;
}
if(1 != pCertExtensions->cExtension)
{
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return FALSE;
}
i = 0;
if (pfCritical != NULL)
{
*pfCritical = pCertExtensions->rgExtension[i].fCritical;
}
CryptDecodeObject(
X509_ASN_ENCODING,
X509_ENHANCED_KEY_USAGE,
pCertExtensions->rgExtension[i].Value.pbData,
pCertExtensions->rgExtension[i].Value.cbData,
0,
NULL,
&cb);
if (NULL == (pehku = (CERT_ENHKEY_USAGE *) new(BYTE[cb])))
{
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return FALSE;
}
CryptDecodeObject(
X509_ASN_ENCODING,
X509_ENHANCED_KEY_USAGE,
pCertExtensions->rgExtension[i].Value.pbData,
pCertExtensions->rgExtension[i].Value.cbData,
0,
pehku,
&cb);
if(!aszUsages)
{
// only retrieving the usage count
*cUsages = pehku->cUsageIdentifier;
}
else
{
// retrieving usage strings, count better match
CSASSERT(*cUsages == pehku->cUsageIdentifier);
for (i=0; i<pehku->cUsageIdentifier; i++)
{
if (fGetOIDSNotNames)
{
pwszOID = MyMkWStr(pehku->rgpszUsageIdentifier[i]);
aszUsages[i]= new CString(pwszOID);
delete(pwszOID);
if(aszUsages[i] == NULL)
{
return FALSE;
}
}
else
{
MyGetOIDInfo(OIDName, sizeof(OIDName)/sizeof(WCHAR), pehku->rgpszUsageIdentifier[i]);
aszUsages[i]= new CString(OIDName);
if(aszUsages[i] == NULL)
{
return FALSE;
}
}
}
}
delete[](pehku);
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return TRUE;
}
BOOL GetIntendedUsagesString(HCERTTYPE hCertType, CString *pUsageString)
{
CString **aszUsages = NULL;
DWORD cNumUsages = 0;
unsigned int i;
if(!MyGetEnhancedKeyUsages(hCertType, NULL, &cNumUsages, NULL, FALSE))
return FALSE;
if(0==cNumUsages)
{
*pUsageString = "";
return TRUE;
}
aszUsages = new CString*[cNumUsages];
if(!aszUsages)
return FALSE;
if(!MyGetEnhancedKeyUsages(hCertType, aszUsages, &cNumUsages, NULL, FALSE))
{
delete[] aszUsages;
return FALSE;
}
*pUsageString = "";
for (i=0; i<cNumUsages; i++)
{
if (i != 0)
{
*pUsageString += ", ";
}
*pUsageString += *(aszUsages[i]);
delete(aszUsages[i]);
}
delete[] aszUsages;
return TRUE;
}
BOOL MyGetKeyUsages(HCERTTYPE hCertType, CRYPT_BIT_BLOB **ppBitBlob, BOOL *pfPublicKeyUsageCritical)
{
PCERT_EXTENSIONS pCertExtensions;
DWORD cb = 0;
unsigned int i;
HRESULT hr;
hr = CAGetCertTypeExtensionsEx(hCertType, CT_EXTENSION_KEY_USAGE, NULL, &pCertExtensions);
if(hr != S_OK)
{
return FALSE;
}
if(1 != pCertExtensions->cExtension)
{
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return FALSE;
}
i = 0;
if (pfPublicKeyUsageCritical != NULL)
{
*pfPublicKeyUsageCritical = pCertExtensions->rgExtension[i].fCritical;
}
CryptDecodeObject(
X509_ASN_ENCODING,
X509_KEY_USAGE,
pCertExtensions->rgExtension[i].Value.pbData,
pCertExtensions->rgExtension[i].Value.cbData,
0,
NULL,
&cb);
if (NULL == (*ppBitBlob = (CRYPT_BIT_BLOB *) new(BYTE[cb])))
{
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return FALSE;
}
CryptDecodeObject(
X509_ASN_ENCODING,
X509_KEY_USAGE,
pCertExtensions->rgExtension[i].Value.pbData,
pCertExtensions->rgExtension[i].Value.cbData,
0,
*ppBitBlob,
&cb);
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return TRUE;
}
BOOL MyGetBasicConstraintInfo(HCERTTYPE hCertType, BOOL *pfCA, BOOL *pfPathLenConstraint, DWORD *pdwPathLenConstraint)
{
PCERT_EXTENSIONS pCertExtensions;
DWORD cb = sizeof(CERT_BASIC_CONSTRAINTS2_INFO);
unsigned int i;
CERT_BASIC_CONSTRAINTS2_INFO basicConstraintsInfo;
HRESULT hr;
hr = CAGetCertTypeExtensionsEx(hCertType, CT_EXTENSION_BASIC_CONTRAINTS, NULL, &pCertExtensions);
if(hr != S_OK)
{
return FALSE;
}
if(1 != pCertExtensions->cExtension)
{
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return FALSE;
}
i = 0;
CryptDecodeObject(
X509_ASN_ENCODING,
X509_BASIC_CONSTRAINTS2,
pCertExtensions->rgExtension[i].Value.pbData,
pCertExtensions->rgExtension[i].Value.cbData,
0,
&basicConstraintsInfo,
&cb);
*pfCA = basicConstraintsInfo.fCA;
*pfPathLenConstraint = basicConstraintsInfo.fPathLenConstraint;
*pdwPathLenConstraint = basicConstraintsInfo.dwPathLenConstraint;
CAFreeCertTypeExtensions(hCertType, pCertExtensions);
return TRUE;
}
LPSTR MyMkMBStr(LPCWSTR pwsz)
{
int cb;
LPSTR psz;
if (pwsz == NULL)
{
return NULL;
}
cb = WideCharToMultiByte(
0,
0,
pwsz,
-1,
NULL,
0,
NULL,
NULL);
if (NULL == (psz = (LPSTR) new BYTE[cb]))
{
return NULL;
}
cb = WideCharToMultiByte(
0,
0,
pwsz,
-1,
psz,
cb,
NULL,
NULL);
if (cb==0)
{
delete [] psz;
return NULL;
}
return(psz);
}
LPWSTR MyMkWStr(LPCSTR psz)
{
int cWChars;
LPWSTR pwsz;
if (psz == NULL)
{
return NULL;
}
cWChars = MultiByteToWideChar(
0,
0,
psz,
-1,
NULL,
0);
if (NULL == (pwsz = (LPWSTR) new BYTE[cWChars * sizeof(WCHAR)] ))
{
return NULL;
}
cWChars = MultiByteToWideChar(
0,
0,
psz,
-1,
pwsz,
cWChars);
if (cWChars == 0)
{
delete [] pwsz;
return NULL;
}
return(pwsz);
}
HRESULT
UpdateCATemplateList(
HWND hwndParent,
HCAINFO hCAInfo,
const CTemplateList& list)
{
HRESULT hr = myUpdateCATemplateListToCA(hCAInfo, list);
if(S_OK != hr)
{
// if failed to update through the CA for any reason, try
// writing directly to DS
CString cstrMsg, cstrTitle, cstrFormat;
cstrFormat.LoadString(IDS_ERROR_CANNOT_SAVE_TEMPLATES);
cstrTitle.LoadString(IDS_TITLE_CANNOT_SAVE_TEMPLATES);
CAutoLPWSTR pwszError;
pwszError.Attach((LPWSTR)myGetErrorMessageText(hr, TRUE));
cstrMsg.Format(cstrFormat, (LPCWSTR)pwszError);
if (IDYES != MessageBox(
hwndParent,
(LPCWSTR)cstrMsg,
(LPCWSTR)cstrTitle,
MB_YESNO))
return ERROR_CANCELLED;
hr = myUpdateCATemplateListToDS(hCAInfo);
}
return hr;
}