|
|
//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1996 - 1999
//
// File: owner.cpp
//
// This file contains the implementation of the Owner page.
//
//--------------------------------------------------------------------------
#include "aclpriv.h"
#include <initguid.h> // needed to get the GUIDs defined in oleacc.h
#include <oleacc.h> // contains IAccProp* definitions
//Context Help IDs
const static DWORD aEffHelpIDs[] = { IDC_EFF_NAME_STATIC, IDH_EFF_NAME, IDC_EFF_NAME, IDH_EFF_NAME, IDC_EFF_SELECT, IDH_EFF_SELECT, IDC_EFF_PERMISSION_STATIC, IDH_EFF_PERM_LIST, IDC_EFF_PERM_LIST, IDH_EFF_PERM_LIST, IDC_EFF_STATIC, -1, 0, 0 };
LPCWSTR g_ListStateMap = L"A:0" L":0:0x50" // checked, disabled - STATE_SYSTEM_READONLY | STATE_SYSTEM_CHECKED
L":1:0x40" // disabled - STATE_SYSTEM_READONLY
L":";
LPCWSTR g_ListRoleMap = L"A:0" L":0:0x2C" // checkbox - ROLE_SYSTEM_CHECKBUTTON (ie. checkbox)
L":1:0x2C" L":";
int LV_ADDITEM(HWND hwndList, LPCTSTR pszName, int index, PSI_ACCESS pAccess, BOOL bChecked) { LVITEM lvItem; TraceAssert(pAccess != NULL); TraceAssert(pszName != NULL);
lvItem.mask = LVIF_TEXT | LVIF_PARAM | LVIF_IMAGE; lvItem.iItem = index; lvItem.iSubItem = 0; lvItem.pszText = (LPTSTR)pszName; lvItem.lParam = (LPARAM)pAccess; lvItem.iImage = bChecked ? 0 : 1;
// Insert item into list
index = ListView_InsertItem(hwndList, &lvItem); ListView_SetCheckState(hwndList,index,bChecked); return index; }
typedef struct _EffCacheItem { POBJECT_TYPE_LIST pObjectTypeList; ULONG cObjectTypeListLength; PACCESS_MASK pGrantedAccessList; PSID pSid; }EFFCACHEITEM,*PEFFCACHEITEM;
//This Function checks is pAccess is granted.
BOOL IsChecked( PSI_ACCESS pAccess, PEFFCACHEITEM pCacheItem) { TraceEnter(TRACE_EFFPERM, "IsChecked"); TraceAssert(pCacheItem != NULL); TraceAssert(pAccess != NULL);
POBJECT_TYPE_LIST pObjectTypeList = pCacheItem->pObjectTypeList; ULONG cObjectTypeListLength = pCacheItem->cObjectTypeListLength; PACCESS_MASK pGrantedAccessList = pCacheItem->pGrantedAccessList;
//0th Grant is for full object.
if( (pAccess->mask & pGrantedAccessList[0]) == pAccess->mask ) return TRUE;
BOOL bGuidNULL = pAccess->pguid ?IsEqualGUID(*(pAccess->pguid), GUID_NULL): TRUE; LPGUID pguid;
for( UINT i = 1; i < cObjectTypeListLength; ++i ) { pguid = pObjectTypeList[i].ObjectType; if( pguid == NULL || IsEqualGUID(*pguid, GUID_NULL) || (!bGuidNULL && IsEqualGUID(*pguid,*(pAccess->pguid))) ) { if( (pAccess->mask & pGrantedAccessList[i]) == pAccess->mask ) return TRUE; } } return FALSE; }
class CEffPage: public CSecurityPage { public: CEffPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo); virtual ~CEffPage();
private: virtual BOOL DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); BOOL InitDlg(HWND hDlg); void OnSelect(HWND hDlg); void InitListBox(HWND hDlg); HRESULT GetEffectivePerm(PSID pSid, PEFFCACHEITEM *ppCacheItem); PSID GetSelectedSID(){ return m_pSid; }
private: PSID m_pSid; //Sid of the security principal for which permissions are displayed
PSI_ACCESS m_pAccess; ULONG m_cAccesses; };
HPROPSHEETPAGE CreateEffectivePermPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo) { HPROPSHEETPAGE hPage = NULL; CEffPage *pPage; TraceEnter(TRACE_EFFPERM, "CreateEffectivePermPage"); TraceAssert(psi!=NULL); TraceAssert(psiObjectInfo);
pPage = new CEffPage(psi, psiObjectInfo);
if (pPage) { hPage = pPage->CreatePropSheetPage(MAKEINTRESOURCE(IDD_EFFECTIVE_PERM_PAGE));
if (!hPage) delete pPage; }
TraceLeaveValue(hPage); }
CEffPage::CEffPage(LPSECURITYINFO psi, SI_OBJECT_INFO *psiObjectInfo) : CSecurityPage(psi, SI_PAGE_OWNER) , m_pSid(NULL), m_pAccess(NULL), m_cAccesses(0) { // Lookup known SIDs asynchronously so the dialog
// will initialize faster
}
CEffPage::~CEffPage() { if (m_pSid) LocalFree(m_pSid); } BOOL CEffPage::DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL bResult = TRUE; LPPSHNOTIFY lpsn; switch(uMsg) { case WM_INITDIALOG: InitDlg(hDlg); break;
case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDC_EFF_SELECT: OnSelect(hDlg); break; default: bResult = FALSE; } break;
case WM_HELP: if (IsWindowEnabled(hDlg)) { WinHelp((HWND)((LPHELPINFO)lParam)->hItemHandle, c_szAcluiHelpFile, HELP_WM_HELP, (DWORD_PTR)aEffHelpIDs); } break;
case WM_CONTEXTMENU: if (IsWindowEnabled(hDlg)) { WinHelp(hDlg, c_szAcluiHelpFile, HELP_CONTEXTMENU, (DWORD_PTR)aEffHelpIDs); } break; case PSM_QUERYSIBLINGS: if(GetSelectedSID()) InitListBox(hDlg); break;
default: bResult = FALSE; }
return bResult; }
BOOL CEffPage::InitDlg( HWND hDlg ) {
HWND hwndList; RECT rc; LV_COLUMN col; TCHAR szBuffer[MAX_COLUMN_CHARS]; HRESULT hr = S_OK; ULONG iDefaultAccess; HCURSOR hcur = SetCursor(LoadCursor(NULL, IDC_WAIT));
TraceEnter(TRACE_EFFPERM, "CEffPage::InitDlg"); TraceAssert(hDlg != NULL); TraceAssert(m_psi != NULL); TraceAssert(m_pei != NULL);
hwndList = GetDlgItem(hDlg, IDC_EFF_PERM_LIST);
//
// Create & set the image list for the listview. If there is a
// problem CreateSidImageList will return NULL which won't hurt
// anything. In that case we'll just continue without an image list.
//
ListView_SetImageList(hwndList, LoadImageList(::hModule, MAKEINTRESOURCE(IDB_CHECKBOX)), LVSIL_SMALL);
// Set extended LV style for whole line selection with InfoTips
ListView_SetExtendedListViewStyleEx(hwndList, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP, LVS_EX_FULLROWSELECT | LVS_EX_INFOTIP);
IAccPropServices * pAccPropSvc = NULL; hr = CoCreateInstance( CLSID_AccPropServices, NULL, CLSCTX_SERVER, IID_IAccPropServices, (void **) & pAccPropSvc ); if( hr == S_OK && pAccPropSvc ) { // Don't have to check HRESULT here, since if they fail we just ignore anyway,
// but may want to log it while debugging.
pAccPropSvc->SetHwndPropStr(hwndList, OBJID_CLIENT, 0, PROPID_ACC_ROLEMAP, g_ListRoleMap ); pAccPropSvc->SetHwndPropStr(hwndList, OBJID_CLIENT, 0, PROPID_ACC_STATEMAP, g_ListStateMap ); pAccPropSvc->Release(); }
//
// Add appropriate listview columns
//
GetClientRect(hwndList, &rc);
LoadString(::hModule, IDS_PERMISSIONS, szBuffer, ARRAYSIZE(szBuffer)); col.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM | LVCF_WIDTH; col.fmt = LVCFMT_LEFT; col.pszText = szBuffer; col.iSubItem = 0; col.cx = rc.right - GetSystemMetrics(SM_CXVSCROLL); ListView_InsertColumn(hwndList, 0, &col);
//Get the access Rights
hr = m_psi->GetAccessRights(&GUID_NULL, SI_ADVANCED|SI_EDIT_EFFECTIVE, &m_pAccess, &m_cAccesses, &iDefaultAccess); FailGracefully(hr, "GetAccessRights Failed"); //Initialize the List box
InitListBox(hDlg);
exit_gracefully:
SetCursor(hcur);
if (FAILED(hr)) { HWND hwnd; // Hide and disable everything
for (hwnd = GetWindow(hDlg, GW_CHILD); hwnd != NULL; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { ShowWindow(hwnd, SW_HIDE); EnableWindow(hwnd, FALSE); }
// Enable and show the "No Security" message
hwnd = GetDlgItem(hDlg, IDC_NO_EFFECTIVE); EnableWindow(hwnd, TRUE); ShowWindow(hwnd, SW_SHOW); }
TraceLeaveValue(TRUE); }
VOID CEffPage::OnSelect(HWND hDlg) { PUSER_LIST pUserList = NULL; LPEFFECTIVEPERMISSION pei; HRESULT hr = S_OK;
TraceEnter(TRACE_EFFPERM, "CEffPage::OnSelect");
if (S_OK == GetUserGroup(hDlg, FALSE, &pUserList)) { TraceAssert(NULL != pUserList); TraceAssert(1 == pUserList->cUsers);
// Free up previous sid
if (m_pSid) LocalFree(m_pSid);
// Copy the new sid
m_pSid = LocalAllocSid(pUserList->rgUsers[0].pSid); if (m_pSid) { SetDlgItemText(hDlg, IDC_EFF_NAME, pUserList->rgUsers[0].pszName); } LocalFree(pUserList); InitListBox(hDlg); } }
VOID CEffPage::InitListBox(HWND hDlg) { HWND hwndList; BOOL bProperties;
PSI_ACCESS pAccess; ULONG cAccesses; DWORD dwType; TCHAR szName[MAX_PATH]; PSID pSid = NULL; PEFFCACHEITEM pCacheItem = NULL; int index; TraceEnter(TRACE_EFFPERM, "CEffPage::InitListBox"); TraceAssert( m_pAccess != NULL ); TraceAssert(m_cAccesses != 0 );
HRESULT hr = S_OK; hwndList = GetDlgItem(hDlg, IDC_EFF_PERM_LIST);
if(!IsWindowEnabled(hwndList)) { //Hide Error Message
HWND hwnd = GetDlgItem(hDlg, IDC_EFF_ERROR); EnableWindow(hwnd, FALSE); ShowWindow(hwnd, SW_HIDE); //Show List box
EnableWindow(hwndList, TRUE); ShowWindow(hwndList, SW_SHOW); }
//Clear all items
ListView_DeleteAllItems(hwndList);
pAccess = m_pAccess; cAccesses = m_cAccesses; dwType = SI_ACCESS_SPECIFIC | SI_ACCESS_PROPERTY; //Get the current sid
pSid = GetSelectedSID(); if( pSid ) { hr = GetEffectivePerm(pSid, &pCacheItem); FailGracefully(hr,"GetEffectivePermission Failed"); }
index = 0; // Enumerate the permissions and add to the checklist
ULONG i; for (i = 0; i < cAccesses; i++, pAccess++) { LPCTSTR pszName;
// Only add permissions that have any of the flags specified in dwType
if (!(pAccess->dwFlags & dwType)) continue;
//Don't Add Permission which have inherit only on
if( pAccess->dwFlags & INHERIT_ONLY_ACE ) continue;
pszName = pAccess->pszName; if (IS_INTRESOURCE(pszName)) { TraceAssert(m_siObjectInfo.hInstance != NULL);
if (LoadString(m_siObjectInfo.hInstance, (UINT)((ULONG_PTR)pszName), szName, ARRAYSIZE(szName)) == 0) { LoadString(::hModule, IDS_UNKNOWN, szName, ARRAYSIZE(szName)); } pszName = szName; } BOOL bChecked = FALSE; if(pSid) { bChecked = IsChecked( pAccess, pCacheItem ); } index = LV_ADDITEM( hwndList, pszName, index, pAccess, bChecked); index++; } if(index) { SelectListViewItem(hwndList, 0); // Redraw the list
SendMessage(hwndList, WM_SETREDRAW, TRUE, 0); ListView_RedrawItems(hwndList, 0, -1); }
exit_gracefully: if(pCacheItem) { if(pCacheItem->pGrantedAccessList) LocalFree(pCacheItem->pGrantedAccessList); LocalFree(pCacheItem); } if(FAILED(hr)) { //Hide List box
HWND hwnd = GetDlgItem(hDlg, IDC_EFF_PERM_LIST); EnableWindow(hwnd, FALSE); ShowWindow(hwnd, SW_HIDE); //Format Error Message To Display
WCHAR buffer[MAX_PATH]; LPWSTR pszCaption = NULL; GetWindowText(GetDlgItem(hDlg, IDC_EFF_NAME), buffer, MAX_PATH-1); FormatStringID(&pszCaption, ::hModule, IDS_EFF_ERROR, buffer); //Show Error Message
hwnd = GetDlgItem(hDlg, IDC_EFF_ERROR); EnableWindow(hwnd, TRUE); SetWindowText(hwnd,pszCaption); ShowWindow(hwnd, SW_SHOW); LocalFreeString(&pszCaption); } TraceLeaveVoid(); }
//Calling function frees *ppCacheItem->pGrantedAccessList
//and *ppCacheItem
HRESULT CEffPage::GetEffectivePerm(PSID pSid, PEFFCACHEITEM *ppCacheItem ) { PSECURITY_DESCRIPTOR pSD; HRESULT hr = S_OK; ULONG cItems = 0; PEFFCACHEITEM pCacheTemp = NULL;
TraceEnter(TRACE_EFFPERM, "CEffPage::GetEffectivePerm"); TraceAssert(pSid != NULL); TraceAssert(ppCacheItem != NULL);
pCacheTemp = (PEFFCACHEITEM)LocalAlloc( LPTR, sizeof(EFFCACHEITEM) + GetLengthSid(pSid)); if(!pCacheTemp) ExitGracefully(hr, E_OUTOFMEMORY, "Lcoal Alloc Failed"); pCacheTemp->pSid = (PSID)(pCacheTemp + 1); CopySid(GetLengthSid(pSid), pCacheTemp->pSid, pSid);
if(m_psi) { hr = m_psi->GetSecurity(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, &pSD, FALSE); FailGracefully(hr, "GetSecurity Failed"); } if( m_pei) { DWORD dwTemp; hr = m_pei->GetEffectivePermission(&(m_siObjectInfo.guidObjectType), pCacheTemp->pSid, m_siObjectInfo.pszServerName, //NULL,
pSD, &(pCacheTemp->pObjectTypeList), &(pCacheTemp->cObjectTypeListLength), &(pCacheTemp->pGrantedAccessList), &dwTemp); if(SUCCEEDED(hr)) { if(!pCacheTemp->pObjectTypeList || !pCacheTemp->pGrantedAccessList) hr = E_FAIL; }
FailGracefully(hr, "GetEffectivePermission Failed"); } exit_gracefully: if( !SUCCEEDED(hr) ) { LocalFree(pCacheTemp); pCacheTemp = NULL; } *ppCacheItem = pCacheTemp;
TraceLeaveResult(hr); }
|