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.
 
 
 
 
 
 

1076 lines
46 KiB

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997-2002.
//
// File: locate.cpp
//
// Contents: Implementation of Add EFS Agent Wizard Location Page
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "AddSheet.h"
#include "Locate.h"
#pragma warning(push, 3)
#include <initguid.h>
#include <cmnquery.h>
#include <dsquery.h>
#include <winldap.h>
#include <dsgetdc.h>
#include <ntdsapi.h>
#include <efsstruc.h>
#pragma warning(pop)
USE_HANDLE_MACROS("CERTMGR(locate.cpp)")
#ifdef _DEBUG
#ifndef ALPHA
#define new DEBUG_NEW
#endif
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define szCertAttr _T ("?userCertificate")
/////////////////////////////////////////////////////////////////////////////
// CAddEFSWizLocate property page
IMPLEMENT_DYNCREATE(CAddEFSWizLocate, CWizard97PropertyPage)
CAddEFSWizLocate::CAddEFSWizLocate() : CWizard97PropertyPage(CAddEFSWizLocate::IDD)
{
//{{AFX_DATA_INIT(CAddEFSWizLocate)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
VERIFY (m_szHeaderTitle.LoadString (IDS_EFS_LOCATE_TITLE));
VERIFY (m_szHeaderSubTitle.LoadString (IDS_EFS_LOCATE_SUBTITLE));
InitWizard97 (FALSE);
}
CAddEFSWizLocate::~CAddEFSWizLocate()
{
}
void CAddEFSWizLocate::DoDataExchange(CDataExchange* pDX)
{
CWizard97PropertyPage::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAddEFSWizLocate)
DDX_Control (pDX, IDC_ADDLIST, m_UserAddList);
//}}AFX_DATA_MAP
InitWizard97 (FALSE);
}
BEGIN_MESSAGE_MAP(CAddEFSWizLocate, CWizard97PropertyPage)
//{{AFX_MSG_MAP(CAddEFSWizLocate)
ON_BN_CLICKED (IDC_BROWSE_DIR, OnBrowseDir)
ON_BN_CLICKED (IDC_BROWSE_FILE, OnBrowseFile)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CAddEFSWizLocate message handlers
BOOL CAddEFSWizLocate::OnSetActive ()
{
BOOL bResult = CWizard97PropertyPage::OnSetActive ();
EnableControls ();
return bResult;
}
void CAddEFSWizLocate::OnBrowseDir ()
{
FindUserFromDir ();
EnableControls ();
}
void CAddEFSWizLocate::OnBrowseFile ()
{
CString szFileFilter;
VERIFY (szFileFilter.LoadString (IDS_CERTFILEFILTER));
// replace "|" with 0;
// security review 2/27/2002 BryanWal ok
const size_t nFilterLen = wcslen (szFileFilter) + 1;
PWSTR pszFileFilter = new WCHAR [nFilterLen];
if ( pszFileFilter )
{
// security review 2/27/2002 BryanWal ok
wcscpy (pszFileFilter, szFileFilter);
for (int nIndex = 0; nIndex < nFilterLen; nIndex++)
{
if ( L'|' == pszFileFilter[nIndex] )
pszFileFilter[nIndex] = 0;
}
WCHAR szFile[MAX_PATH];
// security review 2/27/2002 BryanWal ok
::ZeroMemory (szFile, sizeof (szFile));
OPENFILENAME ofn;
// security review 2/27/2002 BryanWal ok
::ZeroMemory (&ofn, sizeof (ofn));
ofn.lStructSize = sizeof (OPENFILENAME);
ofn.hwndOwner = m_hWnd;
ofn.lpstrFilter = (PCWSTR) pszFileFilter;
ofn.lpstrFile = szFile;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
BOOL bResult = ::GetOpenFileName (&ofn);
if ( bResult )
{
CString szFileName = ofn.lpstrFile;
//
// Open cert store from the file
//
HCERTSTORE hCertStore = NULL;
PVOID FileNameVoidP = (PVOID) (LPCWSTR)szFileName;
PCCERT_CONTEXT pCertContext = NULL;
DWORD dwEncodingType = 0;
DWORD dwContentType = 0;
DWORD dwFormatType = 0;
BOOL bReturn = ::CryptQueryObject (
CERT_QUERY_OBJECT_FILE,
FileNameVoidP,
CERT_QUERY_CONTENT_FLAG_ALL,
CERT_QUERY_FORMAT_FLAG_ALL,
0,
&dwEncodingType,
&dwContentType,
&dwFormatType,
&hCertStore,
NULL,
(const void **)&pCertContext);
ASSERT (bReturn);
if ( bReturn )
{
//
// Success. See what we get back. A store or a cert.
//
if ( (dwContentType == CERT_QUERY_CONTENT_SERIALIZED_STORE)
&& hCertStore)
{
CERT_ENHKEY_USAGE enhKeyUsage;
// security review 2/27/2002 BryanWal ok
::ZeroMemory (&enhKeyUsage, sizeof (enhKeyUsage));
enhKeyUsage.cUsageIdentifier = 1;
enhKeyUsage.rgpszUsageIdentifier[0] = szOID_EFS_RECOVERY;
//
// We get the certificate store
//
pCertContext = ::CertFindCertificateInStore (
hCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_ENHKEY_USAGE,
&enhKeyUsage,
NULL);
if ( !pCertContext )
{
CString caption;
CString text;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_EFS_FILE_HAS_NO_EFS_USAGE));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
return;
}
if ( hCertStore )
::CertCloseStore (hCertStore, 0);
}
else if ( (dwContentType != CERT_QUERY_CONTENT_CERT) || !pCertContext )
{
//
// Neither a valid cert file nor a store file we like.
//
if ( hCertStore )
::CertCloseStore (hCertStore, 0);
if ( pCertContext )
::CertFreeCertificateContext (pCertContext);
CString ErrMsg;
CThemeContextActivator activator;
VERIFY (ErrMsg.LoadString (IDS_CERTFILEFORMATERR));
MessageBox (ErrMsg);
return;
}
if ( hCertStore )
{
::CertCloseStore (hCertStore, 0);
hCertStore = NULL;
}
//
// Add the user
//
if ( CertHasEFSKeyUsage (pCertContext) )
{
//
// We got the cert. Add it to the structure. We need get the subject name first.
//
// verify that certificate is not revoked
if ( !IsCertificateRevoked (pCertContext) )
{
// verify that certificate is valid
if ( 0 == CertVerifyTimeValidity (NULL, pCertContext->pCertInfo) )
{
LPWSTR pszUserCertName = 0;
INT_PTR iRetCode = GetCertNameFromCertContext (
pCertContext,
&pszUserCertName);
if ( ERROR_SUCCESS != iRetCode )
{
if ( pCertContext )
{
::CertFreeCertificateContext (pCertContext);
}
return;
}
CAddEFSWizSheet* pAddSheet = reinterpret_cast <CAddEFSWizSheet*> (m_pWiz);
ASSERT (pAddSheet);
if ( !pAddSheet )
return;
EFS_CERTIFICATE_BLOB certBlob;
certBlob.cbData = pCertContext->cbCertEncoded;
certBlob.pbData = pCertContext->pbCertEncoded;
certBlob.dwCertEncodingType = pCertContext->dwCertEncodingType;
iRetCode = pAddSheet->Add (
NULL,
pszUserCertName,
(PVOID)&certBlob,
NULL,
USERADDED,
pCertContext);
if ( (ERROR_SUCCESS != iRetCode) && (CRYPT_E_EXISTS != iRetCode) )
{
//
// Error in adding the user
//
::CertFreeCertificateContext (pCertContext);
pCertContext = NULL;
}
else
{
//
// Add the user to the list box.
//
if ( iRetCode == ERROR_SUCCESS )
{
LV_ITEM fillItem;
CString userUnknown;
try {
if (!userUnknown.LoadString (IDS_UNKNOWNUSER))
{
ASSERT (0);
userUnknown.Empty ();
}
}
catch (...)
{
userUnknown.Empty ();
}
fillItem.mask = LVIF_TEXT;
fillItem.iItem = 0;
fillItem.iSubItem = 0;
if ( userUnknown.IsEmpty () )
{
fillItem.pszText = _T ("");
}
else
{
fillItem.pszText = userUnknown.GetBuffer (userUnknown.GetLength () + 1);
}
fillItem.iItem = m_UserAddList.InsertItem (&fillItem);
if ( !userUnknown.IsEmpty () )
{
userUnknown.ReleaseBuffer ();
}
if ( fillItem.iItem != -1 )
{
fillItem.pszText = pszUserCertName;
fillItem.iSubItem = 1;
m_UserAddList.SetItem (&fillItem);
}
else
{
pAddSheet->Remove (NULL, pszUserCertName);
}
pszUserCertName = NULL;
}
else
{
//
// Already deleted inside the Add.
//
pszUserCertName = NULL;
}
}
if (pszUserCertName)
{
delete [] pszUserCertName;
pszUserCertName = NULL;
}
}
else
{
CString text;
CString caption;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_EFS_CERT_IS_NOT_VALID));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
}
}
}
else
{
CString caption;
CString text;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_EFS_FILE_HAS_NO_EFS_USAGE));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
}
}
else
{
//
// Fail. Get the error code.
//
DWORD dwErr = GetLastError ();
CString text;
CString caption;
CThemeContextActivator activator;
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
text.FormatMessage (IDS_CERTFILEOPENERR,
szFileName, GetSystemMessage (dwErr));
MessageBox (text, caption);
}
}
delete [] pszFileFilter;
}
EnableControls ();
}
HRESULT CAddEFSWizLocate::FindUserFromDir ()
{
HRESULT hr = S_OK;
LPWSTR pszListUserName = NULL;
LPWSTR pszUserCertName = NULL;
FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
STGMEDIUM medium = { TYMED_NULL, NULL, NULL };
ICommonQuery* pCommonQuery = NULL;
OPENQUERYWINDOW oqw;
DSQUERYINITPARAMS dqip;
bool bCheckDS = false;
HANDLE hDS = NULL;
CAddEFSWizSheet* pAddSheet = reinterpret_cast <CAddEFSWizSheet *> (m_pWiz);
ASSERT (pAddSheet);
if ( !pAddSheet )
return E_POINTER;
// security review 2/27/2002 BryanWal ok
hr = ::CoCreateInstance (CLSID_CommonQuery, NULL, CLSCTX_INPROC_SERVER,
IID_ICommonQuery, (LPVOID*)&pCommonQuery);
ASSERT (SUCCEEDED (hr));
if ( SUCCEEDED (hr) )
{
dqip.cbStruct = sizeof (dqip);
dqip.dwFlags = DSQPF_SHOWHIDDENOBJECTS |
DSQPF_ENABLEADMINFEATURES;
dqip.pDefaultScope = NULL; //szScopeLocn
oqw.cbStruct = sizeof (oqw);
oqw.dwFlags = OQWF_OKCANCEL |
// OQWF_SINGLESELECT |
OQWF_DEFAULTFORM |
OQWF_REMOVEFORMS ;
oqw.clsidHandler = CLSID_DsQuery;
oqw.pHandlerParameters = &dqip;
oqw.clsidDefaultForm = CLSID_DsFindPeople;
IDataObject* pDataObject = NULL;
hr = pCommonQuery->OpenQueryWindow (m_hWnd, &oqw, &pDataObject);
ASSERT (SUCCEEDED (hr));
if ( SUCCEEDED (hr) && pDataObject )
{
// Fill the list view
fmte.cfFormat = pAddSheet->GetDataFormat ();
hr = pDataObject->GetData (&fmte, &medium);
// A return of DV_E_FORMATETC (0x80040064) here can mean that
// nothing was selected in the query window
if ( SUCCEEDED (hr) )
{
LPDSOBJECTNAMES pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal;
hr = DsBind (NULL, NULL, &hDS);
if ( SUCCEEDED (hr) )
{
//
// We are going to use the DS to crack the names
//
bCheckDS = true;
}
if ( pDsObjects->cItems )
{
// Verify that each user has a cert that allows the necessary
// action (efs decryption)
for ( UINT i = 0 ; i < pDsObjects->cItems ; i++ )
{
PWSTR pszTemp = (PWSTR)
( ( (LPBYTE)pDsObjects)+pDsObjects->aObjects[i].offsetName);
DS_NAME_RESULT* pUserName = NULL;
PSID userSID = NULL;
DWORD cbSid = 0;
PWSTR pszReferencedDomainName = NULL;
DWORD cbReferencedDomainName = 0;
SID_NAME_USE SidUse;
//
// Get rid of the head :\\
//
LPWSTR pszSearch = wcschr (pszTemp, _T (':'));
if (pszSearch && (pszSearch[1] == _T ('/')) && (pszSearch[2] == _T ('/')))
{
pszTemp = pszSearch + 3;
}
if ( bCheckDS )
{
hr = DsCrackNames (
hDS,
DS_NAME_NO_FLAGS,
DS_FQDN_1779_NAME,
DS_NT4_ACCOUNT_NAME,
1,
&pszTemp,
&pUserName
);
if ( SUCCEEDED (hr) && pUserName )
{
if ( ( pUserName->cItems > 0 ) && (DS_NAME_NO_ERROR == pUserName->rItems[0].status))
{
//
// Save the NT4 name first, in case we cannot get the principle name
//
pszListUserName = new WCHAR[wcslen (pUserName->rItems[0].pName) + 1];
if (pszListUserName)
{
// security review 2/27/2002 BryanWal ok
wcscpy (pszListUserName, pUserName->rItems[0].pName);
}
else
{
hr = E_OUTOFMEMORY;
break;
}
BOOL bReturn = ::LookupAccountName (
NULL,
pUserName->rItems[0].pName,
userSID,
&cbSid,
pszReferencedDomainName,
&cbReferencedDomainName,
&SidUse
);
hr = GetLastError ();
if ( !bReturn && (HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER) == hr) )
{
//
// We are expecting this error
//
userSID = new BYTE[cbSid];
pszReferencedDomainName = new WCHAR[cbReferencedDomainName];
if ( userSID && pszReferencedDomainName )
{
bReturn = ::LookupAccountName (
NULL,
pUserName->rItems[0].pName,
userSID,
&cbSid,
pszReferencedDomainName,
&cbReferencedDomainName,
&SidUse);
delete [] pszReferencedDomainName;
pszReferencedDomainName = NULL;
if (!bReturn)
{
//
// Get SID failed. We can live with it.
//
userSID = NULL;
}
}
else
{
if (userSID)
{
delete [] userSID;
userSID = NULL;
}
if (pszReferencedDomainName)
{
delete [] pszReferencedDomainName;
pszReferencedDomainName = NULL;
}
hr = E_OUTOFMEMORY;
break;
}
}
else
{
ASSERT (!bReturn);
userSID = NULL;
}
}
}
else
{
//
// Cannot get the NT4 name. Set the SID to NULL. Go on.
//
userSID = NULL;
}
if (pUserName)
{
DsFreeNameResult (pUserName);
pUserName = NULL;
}
hr = DsCrackNames (
hDS,
DS_NAME_NO_FLAGS,
DS_FQDN_1779_NAME,
DS_USER_PRINCIPAL_NAME,
1,
&pszTemp,
&pUserName);
ASSERT (SUCCEEDED (hr));
if ( (HRESULT_FROM_WIN32 (ERROR_SUCCESS) == hr) &&
( pUserName->cItems > 0 ) &&
(DS_NAME_NO_ERROR == pUserName->rItems[0].status) )
{
//
// We got the principal name
//
LPWSTR pszTmpNameStr =
new WCHAR[wcslen (pUserName->rItems[0].pName) + 1];
if ( pszTmpNameStr )
{
// security review 2/27/2002 BryanWal ok
wcscpy (pszTmpNameStr, pUserName->rItems[0].pName);
delete [] pszListUserName;
pszListUserName = pszTmpNameStr;
}
else
{
hr = ERROR_OUTOFMEMORY;
}
}
}
if ( (HRESULT_FROM_WIN32 (ERROR_OUTOFMEMORY) != hr) && ( !pszListUserName))
{
//
// Use the LDAP name
//
pszListUserName = new WCHAR[wcslen (pszTemp)+1];
if ( pszListUserName )
{
// security review 2/27/2002 BryanWal ok
wcscpy (pszListUserName, pszTemp);
}
else
{
hr = ERROR_OUTOFMEMORY;
}
}
if (pUserName)
{
DsFreeNameResult (pUserName);
pUserName = NULL;
}
if ( HRESULT_FROM_WIN32 (ERROR_OUTOFMEMORY) != hr )
{
//
// Now is the time to get the certificate
//
PCWSTR pszHeader1 = L"LDAP://";
PCWSTR pszHeader2 = L"LDAP:///";
PWSTR pszLdapUrl = new WCHAR[wcslen (pszTemp) +
wcslen (pszHeader2) + // pszHeader2 because it's the longer of the two
wcslen (szCertAttr) + 2];
if ( pszLdapUrl )
{
PCWSTR szCN = L"CN=";
//
// This is really not necessary. MS should make the name convention consistant.
//
// security review 2/27/2002 BryanWal ok
if ( !wcsncmp (pszTemp, szCN, wcslen (szCN)) )
{
// pszTemp is object name without server
wcscpy (pszLdapUrl, pszHeader2);
}
else
wcscpy (pszLdapUrl, pszHeader1);
wcscat (pszLdapUrl, pszTemp);
wcscat (pszLdapUrl, szCertAttr);
hr = ERROR_SUCCESS;
HCERTSTORE hDSCertStore = ::CertOpenStore (
sz_CERT_STORE_PROV_LDAP,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
NULL,
CERT_STORE_MAXIMUM_ALLOWED_FLAG,
(void*) pszLdapUrl);
//
// In case delete change the result of GetLastError ()
//
hr = GetLastError ();
if (hDSCertStore)
{
CERT_ENHKEY_USAGE enhKeyUsage;
// security review 2/27/2002 BryanWal ok
::ZeroMemory (&enhKeyUsage, sizeof (enhKeyUsage));
enhKeyUsage.cUsageIdentifier = 1;
enhKeyUsage.rgpszUsageIdentifier = new LPSTR[1];
if ( enhKeyUsage.rgpszUsageIdentifier )
{
enhKeyUsage.rgpszUsageIdentifier[0] = szOID_EFS_RECOVERY;
//
// We get the certificate store
//
PCCERT_CONTEXT pCertContext =
::CertFindCertificateInStore (
hDSCertStore,
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
0,
CERT_FIND_ENHKEY_USAGE,
&enhKeyUsage,
NULL);
if ( pCertContext )
{
if ( CertHasEFSKeyUsage (pCertContext) )
{
// check to see if cert is revoked
if ( !IsCertificateRevoked (pCertContext) )
{
// verify that certificate is valid
if ( 0 == CertVerifyTimeValidity (NULL, pCertContext->pCertInfo) )
{
//
// We got the certificate. Add it to the lists.
// Get the certificate display name first
//
hr = GetCertNameFromCertContext (
pCertContext,
&pszUserCertName);
//
// Add the user
//
EFS_CERTIFICATE_BLOB certBlob;
certBlob.cbData = pCertContext->cbCertEncoded;
certBlob.pbData = pCertContext->pbCertEncoded;
certBlob.dwCertEncodingType = pCertContext->dwCertEncodingType;
hr = pAddSheet->Add (
pszListUserName,
pszUserCertName,
(PVOID)&certBlob,
userSID,
USERADDED,
pCertContext);
if ( FAILED (hr) && (HRESULT_FROM_WIN32 (CRYPT_E_EXISTS) != hr) )
{
//
// Error in adding the user
//
::CertFreeCertificateContext (pCertContext);
pCertContext = NULL;
}
else
{
//
// Add the user to the list box.
//
if ( SUCCEEDED (hr) )
{
LV_ITEM fillItem;
fillItem.mask = LVIF_TEXT;
fillItem.iItem = 0;
fillItem.iSubItem = 0;
fillItem.pszText = pszListUserName;
fillItem.iItem = m_UserAddList.InsertItem (&fillItem);
if ( fillItem.iItem == -1 )
{
pAddSheet->Remove ( pszListUserName, pszUserCertName);
}
else
{
fillItem.pszText = pszUserCertName;
fillItem.iSubItem = 1;
m_UserAddList.SetItem (&fillItem);
}
}
//
//Either deleted (CRYPT_E_EXISTS) or should not be freed (ERROR_SUCCESS)
//
pszListUserName = NULL;
pszUserCertName = NULL;
}
}
else
{
CString text;
CString caption;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_EFS_CERT_IS_NOT_VALID));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
}
}
}
else
{
CString caption;
CString text;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_USER_OBJECT_HAS_NO_CERTS));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
}
}
else
{
CString text;
CString caption;
CThemeContextActivator activator;
VERIFY (text.LoadString (IDS_USER_OBJECT_HAS_NO_CERTS));
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
MessageBox (text, caption, MB_OK);
}
delete [] enhKeyUsage.rgpszUsageIdentifier;
}
else
{
hr = E_OUTOFMEMORY;
}
delete [] userSID;
userSID = NULL;
if (pszListUserName)
{
delete [] pszListUserName;
pszListUserName = NULL;
}
if (pszUserCertName)
{
delete [] pszUserCertName;
pszUserCertName = NULL;
}
if ( hDSCertStore )
{
CertCloseStore (hDSCertStore, 0);
hDSCertStore = NULL;
}
}
else
{
//
// Failed to open the cert store
//
delete [] userSID;
userSID = NULL;
if (pszListUserName)
{
delete [] pszListUserName;
pszListUserName = NULL;
}
if (pszUserCertName)
{
delete [] pszUserCertName;
pszUserCertName = NULL;
}
CString caption;
CString text;
CThemeContextActivator activator;
VERIFY (caption.LoadString (IDS_CERTIFICATE_MANAGER));
text.FormatMessage (IDS_UNABLE_TO_OPEN_EFS_STORE, pszLdapUrl,
GetSystemMessage (hr));
::MessageBox (NULL, text, caption, MB_OK);
}
delete [] pszLdapUrl;
pszLdapUrl = NULL;
}
else
{
hr = ERROR_OUTOFMEMORY;
}
}
if ( HRESULT_FROM_WIN32 (ERROR_OUTOFMEMORY) == hr )
{
//
// Free the memory. Delete works for NULL. No check is needed.
//
delete [] userSID;
userSID = NULL;
delete [] pszListUserName;
pszListUserName = NULL;
delete [] pszUserCertName;
pszUserCertName = NULL;
}
}//For
}
if (bCheckDS)
{
DsUnBindW ( &hDS);
}
ReleaseStgMedium (&medium);
}
pDataObject->Release ();
}
pCommonQuery->Release ();
}
return hr;
}
DWORD CAddEFSWizLocate::GetCertNameFromCertContext (
PCCERT_CONTEXT pCertContext, PWSTR *ppwszUserCertName)
//////////////////////////////////////////////////////////////////////
// Routine Description:
// Get the user name from the certificate
// Arguments:
// pCertContext -- Cert Context
// pszUserCertName -- User name
// ( Caller is responsible to delete this memory using delete [] )
// Return Value:
// ERROR_SUCCESS if succeed.
// If No Name if found. "USER_UNKNOWN is returned".
//
//////////////////////////////////////////////////////////////////////
{
if ( !ppwszUserCertName || !pCertContext)
{
return ERROR_INVALID_PARAMETER;
}
*ppwszUserCertName = NULL;
CString szSubjectName = ::GetNameString (pCertContext, 0);
if ( !szSubjectName.IsEmpty () )
{
// security review 2/27/2002 BryanWal ok
*ppwszUserCertName = new WCHAR[wcslen (szSubjectName) + 1];
if ( *ppwszUserCertName )
{
// security review 2/27/2002 BryanWal ok
wcscpy (*ppwszUserCertName, szSubjectName);
}
else
return ERROR_NOT_ENOUGH_MEMORY;
}
else
return ERROR_FILE_NOT_FOUND;
return ERROR_SUCCESS;
}
BOOL CAddEFSWizLocate::OnInitDialog ()
{
CWizard97PropertyPage::OnInitDialog ();
CString userNameTitle;
CString userDNTitle;
RECT rcList;
try {
m_UserAddList.GetClientRect (&rcList);
DWORD dwColWidth = (rcList.right - rcList.left)/2;
VERIFY (userNameTitle.LoadString (IDS_USERCOLTITLE));
VERIFY (userDNTitle.LoadString (IDS_DNCOLTITLE));
m_UserAddList.InsertColumn (0, userNameTitle, LVCFMT_LEFT, dwColWidth);
m_UserAddList.InsertColumn (1, userDNTitle, LVCFMT_LEFT, dwColWidth);
}
catch (...){
}
CAddEFSWizSheet* pAddSheet = reinterpret_cast <CAddEFSWizSheet*> (m_pWiz);
ASSERT (pAddSheet);
if ( pAddSheet )
{
if ( pAddSheet->m_bMachineIsStandAlone )
GetDlgItem (IDC_BROWSE_DIR)->EnableWindow (FALSE);
}
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
LRESULT CAddEFSWizLocate::OnWizardBack ()
{
CAddEFSWizSheet *pAddSheet = reinterpret_cast <CAddEFSWizSheet *> (m_pWiz);
ASSERT (pAddSheet);
if ( !pAddSheet )
return -1;
pAddSheet->ClearUserList ();
m_UserAddList.DeleteAllItems ();
return CWizard97PropertyPage::OnWizardBack ();
}
void CAddEFSWizLocate::EnableControls ()
{
if ( m_UserAddList.GetItemCount () <= 0 )
{
GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_BACK);
}
else
GetParent ()->PostMessage (PSM_SETWIZBUTTONS, 0, PSWIZB_NEXT | PSWIZB_BACK);
}
bool CAddEFSWizLocate::IsCertificateRevoked (PCCERT_CONTEXT pCertContext)
{
ASSERT (pCertContext);
if ( !pCertContext )
return true;
bool bIsRevoked = false;
const DWORD cNumCerts = 1;
PVOID rgpvContext[cNumCerts] = {(PVOID)pCertContext};
CERT_REVOCATION_PARA crp;
CERT_REVOCATION_STATUS crs;
::ZeroMemory (&crp, sizeof (crp));
crp.cbSize = sizeof (crp);
::ZeroMemory (&crs, sizeof (crs));
crs.cbSize = sizeof (crs);
BOOL bResult = ::CertVerifyRevocation (
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
CERT_CONTEXT_REVOCATION_TYPE,
cNumCerts,
rgpvContext,
0, // dwFlags
&crp,
&crs);
if ( !bResult )
{
DWORD dwErr = GetLastError ();
CString text;
CString caption;
CThemeContextActivator activator;
VERIFY (caption.LoadString (IDS_ADD_RECOVERY_AGENT));
if ( CRYPT_E_REVOKED == HRESULT_FROM_WIN32 (dwErr) )
{
text.FormatMessage (IDS_EFS_CERT_IS_REVOKED, GetSystemMessage (dwErr));
MessageBox (text, caption, MB_OK);
bIsRevoked = true;
}
else
{
text.FormatMessage (IDS_EFS_CERT_REVOCATION_NOT_VERIFIED, GetSystemMessage (GetLastError ()));
if ( IDNO == MessageBox (text, caption, MB_YESNO) )
bIsRevoked = true;
}
}
else
bIsRevoked = false;
return bIsRevoked;
}