|
|
/*++
Copyright (C) Microsoft Corporation, 1997-2002
Module Name:
ShellExt.cpp
Abstract: This is the implementation file for Dfs Shell Extension object which implements IShellIExtInit and IShellPropSheetExt.
Author:
Constancio Fernandes (ferns@qspl.stpp.soft.net) 12-Jan-1998
Environment: NT only. */ #include "stdafx.h"
#include <dsclient.h>
#include "ShellExt.h"
#include "TemplateGeneralPropertyPage.h"
#include "TemplateV1RequestPropertyPage.h"
#include "TemplateV2RequestPropertyPage.h"
#include "TemplateV1SubjectNamePropertyPage.h"
#include "TemplateV2SubjectNamePropertyPage.h"
#include "TemplateV2AuthenticationPropertyPage.h"
#include "TemplateV2SupercedesPropertyPage.h"
#include "TemplateExtensionsPropertyPage.h"
#include "SecurityPropertyPage.h"
#include "PolicyOID.h"
#define ByteOffset(base, offset) (((LPBYTE)base)+offset)
/*----------------------------------------------------------------------
IShellExtInit Implementation. ------------------------------------------------------------------------*/ CCertTemplateShellExt::CCertTemplateShellExt() : m_Count (0), m_apCertTemplates (0), m_uiEditId (0) { }
CCertTemplateShellExt::~CCertTemplateShellExt() { if ( m_apCertTemplates ) { for (int nIndex = 0; nIndex < m_Count; nIndex++) { if ( m_apCertTemplates[nIndex] ) m_apCertTemplates[nIndex]->Release (); } } }
STDMETHODIMP CCertTemplateShellExt::Initialize ( IN LPCITEMIDLIST /*pidlFolder*/, // Points to an ITEMIDLIST structure
IN LPDATAOBJECT pDataObj, // Points to an IDataObject interface
IN HKEY /*hkeyProgID*/ // Registry key for the file object or folder type
) {
HRESULT hr = 0; FORMATETC fmte = {CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; STGMEDIUM medium = { TYMED_NULL }; LPDSOBJECTNAMES pDsObjects; CString csClass, csPath; USES_CONVERSION;
PWSTR wszTypeDN = 0; PWSTR wszTemplateName = 0; PWSTR wszType = 0;
AFX_MANAGE_STATE(AfxGetStaticModuleState());
// if we have a pDataObj then try and get the first name from it
if ( pDataObj ) { // get path and class
fmte.cfFormat = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_DSOBJECTNAMES); if ( SUCCEEDED(pDataObj->GetData(&fmte, &medium)) ) { pDsObjects = (LPDSOBJECTNAMES)medium.hGlobal; m_Count = pDsObjects->cItems;
if(m_Count > 0) {
m_apCertTemplates = (CCertTemplate **) ::LocalAlloc ( LPTR, sizeof(CCertTemplate*)*m_Count); if(m_apCertTemplates == NULL) { hr = E_OUTOFMEMORY; goto error; }
for (UINT index = 0; index < m_Count ; index++) { LPWSTR wszEnd = NULL; wszTypeDN = (LPWSTR)ByteOffset(pDsObjects, pDsObjects->aObjects[index].offsetName); if(wszTypeDN == NULL) { continue; } wszTemplateName = wcsstr(wszTypeDN, L"CN="); if(wszTemplateName == NULL) { continue; } wszTemplateName += 3;
// security review 2/21/2002 BryanWal ok - worst case: wszTemplateName is "";
wszType = (LPWSTR) ::LocalAlloc (LPTR, sizeof(WCHAR)*(wcslen(wszTemplateName)+1)); if ( wszType == NULL ) { hr = E_OUTOFMEMORY; goto error; } // security review 2/21/2002 BryanWal ok
wcscpy (wszType, wszTemplateName); wszEnd = wcschr (wszType, L','); if ( wszEnd ) { *wszEnd = 0; }
m_apCertTemplates[index] = new CCertTemplate (0, wszType, wszTypeDN, false, true); LocalFree(wszType); wszType = NULL; }
} ReleaseStgMedium(&medium); } } hr = S_OK; // success
error: return hr;
}
STDMETHODIMP CCertTemplateShellExt::AddPages ( IN LPFNADDPROPSHEETPAGE lpfnAddPage, IN LPARAM lParam )
{ HRESULT hr = S_OK; AFX_MANAGE_STATE(AfxGetStaticModuleState());
if(m_apCertTemplates[0] == NULL) { return E_UNEXPECTED; }
DWORD dwType = m_apCertTemplates[0]->GetType (); switch (dwType) { case 1: hr = AddVersion1CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam); break;
case 2: hr = AddVersion2CertTemplatePropPages (m_apCertTemplates[0], lpfnAddPage, lParam); break;
default: _ASSERT (0); break; }
/*
CCertTemplateGeneralPage* pControlPage = new CCertTemplateGeneralPage(m_apCertTemplates[0]); if(pControlPage) { pBasePage = pControlPage; HPROPSHEETPAGE hPage = MyCreatePropertySheetPage(&pBasePage->m_psp); if (hPage == NULL) { delete (pControlPage); return E_UNEXPECTED; } lpfnAddPage(hPage, lParam); } */ return hr; }
HRESULT CCertTemplateShellExt::AddVersion1CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) { _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n"); HRESULT hr = S_OK; _ASSERT (pCertTemplate && lpfnAddPage); if ( pCertTemplate && lpfnAddPage ) { BOOL bResult = FALSE;
_ASSERT (1 == pCertTemplate->GetType ());
// Add General page
CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage ( *pCertTemplate, 0); if ( pGeneralPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; }
// Add Request page only if subject is not a CA
if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () ) { CTemplateV1RequestPropertyPage * pRequestPage = new CTemplateV1RequestPropertyPage (*pCertTemplate); if ( pRequestPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add Subject Name page only if subject is not a CA
if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () ) { CTemplateV1SubjectNamePropertyPage * pSubjectNamePage = new CTemplateV1SubjectNamePropertyPage (*pCertTemplate); if ( pSubjectNamePage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add extensions page
if ( SUCCEEDED (hr) ) { CTemplateExtensionsPropertyPage * pExtensionsPage = new CTemplateExtensionsPropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty); if ( pExtensionsPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add security page
if ( SUCCEEDED (hr) ) { // if error, don't display this page
LPSECURITYINFO pCertTemplateSecurity = NULL;
hr = CreateCertTemplateSecurityInfo (pCertTemplate, &pCertTemplateSecurity); if ( SUCCEEDED (hr) ) { // save the pCASecurity pointer for later releasing
pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity); if (hPage == NULL) { hr = HRESULT_FROM_WIN32 (GetLastError()); _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr); } bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); } } } _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr); return hr; }
HRESULT CCertTemplateShellExt::AddVersion2CertTemplatePropPages (CCertTemplate* pCertTemplate, LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) { _TRACE (1, L"Entering CCertTemplateShellExt::AddVersion1CertTemplatePropPages\n"); HRESULT hr = S_OK; BOOL bResult = FALSE; _ASSERT (pCertTemplate && lpfnAddPage); if ( pCertTemplate && lpfnAddPage ) { _ASSERT (2 == pCertTemplate->GetType ()); // Add General page
CTemplateGeneralPropertyPage * pGeneralPage = new CTemplateGeneralPropertyPage ( *pCertTemplate, 0); if ( pGeneralPage ) { pGeneralPage->m_lNotifyHandle = 0; //lNotifyHandle;
//m_lNotifyHandle = lNotifyHandle;
HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pGeneralPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; }
// Add Request page only if subject is not a CA
if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () ) { CTemplateV2RequestPropertyPage * pRequestPage = new CTemplateV2RequestPropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty); if ( pRequestPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pRequestPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add Subject Name page only if subject is not a CA
if ( SUCCEEDED (hr) && !pCertTemplate->SubjectIsCA () ) { CTemplateV2SubjectNamePropertyPage * pSubjectNamePage = new CTemplateV2SubjectNamePropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty); if ( pSubjectNamePage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSubjectNamePage->m_psp); _ASSERT (hPage); bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); } else { hr = E_OUTOFMEMORY; } }
// Add Authentication Name page
if ( SUCCEEDED (hr) ) { CTemplateV2AuthenticationPropertyPage * pAuthenticationPage = new CTemplateV2AuthenticationPropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty); if ( pAuthenticationPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pAuthenticationPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add Superceded page
if ( SUCCEEDED (hr) ) { CTemplateV2SupercedesPropertyPage * pSupercededPage = new CTemplateV2SupercedesPropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty, 0); if ( pSupercededPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pSupercededPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add extensions page
if ( SUCCEEDED (hr) ) { CTemplateExtensionsPropertyPage * pExtensionsPage = new CTemplateExtensionsPropertyPage (*pCertTemplate, pGeneralPage->m_bIsDirty); if ( pExtensionsPage ) { HPROPSHEETPAGE hPage = MyCreatePropertySheetPage (&pExtensionsPage->m_psp); _ASSERT (hPage); if ( hPage ) { bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); if ( !bResult ) hr = E_FAIL; } else hr = E_FAIL; } else { hr = E_OUTOFMEMORY; } }
// Add security page
if ( SUCCEEDED (hr) ) { // if error, don't display this page
LPSECURITYINFO pCertTemplateSecurity = NULL;
hr = CreateCertTemplateSecurityInfo (pCertTemplate, &pCertTemplateSecurity); if ( SUCCEEDED (hr) ) { // save the pCertTemplateSecurity pointer for later releasing
pGeneralPage->SetAllocedSecurityInfo (pCertTemplateSecurity);
HPROPSHEETPAGE hPage = CreateSecurityPage (pCertTemplateSecurity); if (hPage == NULL) { hr = HRESULT_FROM_WIN32 (GetLastError()); _TRACE (0, L"CreateSecurityPage () failed: 0x%x\n", hr); } bResult = lpfnAddPage (hPage, lParam); _ASSERT (bResult); } } } _TRACE (-1, L"Leaving CCertTemplateShellExt::AddVersion1CertTemplatePropPages: 0x%x\n", hr); return hr; }
STDMETHODIMP CCertTemplateShellExt::ReplacePage ( IN UINT /*uPageID*/, IN LPFNADDPROPSHEETPAGE /*lpfnReplaceWith*/, IN LPARAM /*lParam*/ ) { return E_FAIL; }
// IContextMenu methods
STDMETHODIMP CCertTemplateShellExt::GetCommandString ( UINT_PTR idCmd, UINT uFlags, UINT* /*pwReserved*/, LPSTR pszName, UINT cchMax ) { if((idCmd == m_uiEditId) && (m_uiEditId != 0)) { if (uFlags == GCS_HELPTEXT) { LoadString(AfxGetResourceHandle( ), IDS_EDIT_HINT, (LPTSTR)pszName, cchMax); return S_OK; } } return E_NOTIMPL; }
STDMETHODIMP CCertTemplateShellExt::InvokeCommand ( LPCMINVOKECOMMANDINFO lpici ) { if (!HIWORD(lpici->lpVerb)) { UINT idCmd = LOWORD(lpici->lpVerb); switch(idCmd) { case 0: // Edit
// InvokeCertTypeWizard(m_ahCertTemplates[0],
// lpici->hwnd);
return S_OK;
} }
return E_NOTIMPL; }
STDMETHODIMP CCertTemplateShellExt::QueryContextMenu ( HMENU hmenu, UINT indexMenu, UINT idCmdFirst, UINT /*idCmdLast*/, UINT /*uFlags*/ ) {
CString szEdit; MENUITEMINFO mii; UINT idLastUsedCmd = idCmdFirst; AFX_MANAGE_STATE(AfxGetStaticModuleState());
// security review 2/21/2002 BryanWal ok
ZeroMemory (&mii, sizeof (mii)); if ( IsCerttypeEditingAllowed () ) { mii.cbSize = sizeof(mii); mii.fMask = MIIM_TYPE | MIIM_ID; mii.fType = MFT_STRING; mii.wID = idCmdFirst;
szEdit.LoadString(IDS_EDIT);
mii.dwTypeData = (LPTSTR)(LPCTSTR)szEdit; mii.cch = szEdit.GetLength();
// Add new menu items to the context menu. //
::InsertMenuItem(hmenu, indexMenu++, TRUE, &mii);
}
return ResultFromScode (MAKE_SCODE (SEVERITY_SUCCESS, 0, USHORT (idLastUsedCmd + 1))); }
|