/*
* ReactOS Access Control List Editor
- * Copyright (C) 2004 ReactOS Team
+ * Copyright (C) 2004-2005 ReactOS Team
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-/* $Id: aclui.c,v 1.8 2004/10/21 18:28:05 weiden Exp $
+/* $Id$
*
* PROJECT: ReactOS Access Control List Editor
* FILE: lib/aclui/aclui.c
* PURPOSE: Access Control List Editor
- * PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
+ * PROGRAMMER: Thomas Weidenmueller <w3seek@reactos.com>
*
* UPDATE HISTORY:
* 08/10/2004 Created
*/
-#define INITGUID
-#include <windows.h>
-#include <commctrl.h>
-#include <prsht.h>
-#include <aclui.h>
-#include <rosrtl/resstr.h>
-#include "internal.h"
-#include "resource.h"
+#include <precomp.h>
+
+#define NDEBUG
+#include <debug.h>
HINSTANCE hDllInstance;
-UINT CALLBACK
-SecurityPageCallback(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE ppsp)
+#define SIDN_LOOKUPSUCCEEDED (0x101)
+typedef struct _SIDLOOKUPNOTIFYINFO
+{
+ NMHDR nmh;
+ PSID Sid;
+ PSIDREQRESULT SidRequestResult;
+} SIDLOOKUPNOTIFYINFO, *PSIDLOOKUPNOTIFYINFO;
+
+static PSID
+AceHeaderToSID(IN PACE_HEADER AceHeader)
+{
+ PSID Sid = NULL;
+ switch (AceHeader->AceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_ALLOWED_ACE)AceHeader)->SidStart;
+ break;
+#if 0
+ case ACCESS_ALLOWED_CALLBACK_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_ACE)AceHeader)->SidStart;
+ break;
+ case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart;
+ break;
+#endif
+ case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)AceHeader)->SidStart;
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_DENIED_ACE)AceHeader)->SidStart;
+ break;
+#if 0
+ case ACCESS_DENIED_CALLBACK_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_DENIED_CALLBACK_ACE)AceHeader)->SidStart;
+ break;
+ case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_DENIED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart;
+ break;
+#endif
+ case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+ Sid = (PSID)&((PACCESS_DENIED_OBJECT_ACE)AceHeader)->SidStart;
+ break;
+ }
+
+ return Sid;
+}
+
+static VOID
+DestroySecurityPage(IN PSECURITY_PAGE sp)
+{
+ if(sp->hiPrincipals != NULL)
+ {
+ ImageList_Destroy(sp->hiPrincipals);
+ }
+
+ DestroySidCacheMgr(sp->SidCacheMgr);
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ sp);
+
+ CoUninitialize();
+}
+
+static VOID
+FreePrincipalsList(IN PSECURITY_PAGE sp,
+ IN PPRINCIPAL_LISTITEM *PrincipalsListHead)
+{
+ PPRINCIPAL_LISTITEM CurItem, NextItem;
+ PACE_ENTRY AceEntry, NextAceEntry;
+
+ CurItem = *PrincipalsListHead;
+ while (CurItem != NULL)
+ {
+ /* Free all ACEs */
+ AceEntry = CurItem->ACEs;
+ while (AceEntry != NULL)
+ {
+ NextAceEntry = AceEntry->Next;
+ HeapFree(GetProcessHeap(),
+ 0,
+ AceEntry);
+ AceEntry = NextAceEntry;
+ }
+
+ /* free the SID string if present */
+ if (CurItem->SidReqResult != NULL)
+ {
+ DereferenceSidReqResult(sp->SidCacheMgr,
+ CurItem->SidReqResult);
+ }
+
+ if (CurItem->DisplayString != NULL)
+ {
+ LocalFree((HLOCAL)CurItem->DisplayString);
+ }
+
+ /* free the ACE list item */
+ NextItem = CurItem->Next;
+ HeapFree(GetProcessHeap(),
+ 0,
+ CurItem);
+ CurItem = NextItem;
+ }
+
+ *PrincipalsListHead = NULL;
+}
+
+static PACE_ENTRY
+AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal,
+ IN PACE_HEADER AceHeader)
{
- switch(uMsg)
- {
- case PSPCB_CREATE:
- {
- PSECURITY_PAGE sp;
-
- sp = LocalAlloc(LHND, sizeof(SECURITY_PAGE));
- if(sp != NULL)
- {
- /* save the pointer to the ISecurityInformation interface */
- sp->psi = (LPSECURITYINFO)ppsp->lParam;
- /* set the lParam to the allocated structure */
- ppsp->lParam = (LPARAM)sp;
- return TRUE;
- }
- return FALSE;
- }
- case PSPCB_RELEASE:
- {
- if(ppsp->lParam != 0)
- {
- PSECURITY_PAGE sp = (PSECURITY_PAGE)ppsp->lParam;
- if(sp->hiUsrs != NULL)
+ PACE_ENTRY AceEntry, *AceLink;
+
+ AceEntry = HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(ACE_ENTRY) + AceHeader->AceSize);
+ if (AceEntry != NULL)
+ {
+ AceEntry->Next = NULL;
+
+ /* copy the ACE */
+ CopyMemory(AceEntry + 1,
+ AceHeader,
+ AceHeader->AceSize);
+
+ /* append it to the list */
+ AceLink = &Principal->ACEs;
+ while (*AceLink != NULL)
{
- ImageList_Destroy(sp->hiUsrs);
+ AceLink = &(*AceLink)->Next;
}
- LocalFree((HLOCAL)sp);
- }
- return FALSE;
+ *AceLink = AceEntry;
}
- }
- return FALSE;
+ return AceEntry;
+}
+
+static PPRINCIPAL_LISTITEM
+FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead,
+ IN PSID Sid,
+ IN PACE_HEADER AceHeader)
+{
+ PPRINCIPAL_LISTITEM CurItem;
+
+ for (CurItem = PrincipalsListHead;
+ CurItem != NULL;
+ CurItem = CurItem->Next)
+ {
+ if (EqualSid((PSID)(CurItem + 1),
+ Sid))
+ {
+ if (AddAceToPrincipal(CurItem,
+ AceHeader) != NULL)
+ {
+ return CurItem;
+ }
+
+ /* unable to add the ACE to the principal */
+ break;
+ }
+ }
+
+ return NULL;
}
+static VOID
+SidLookupCompletion(IN HANDLE SidCacheMgr,
+ IN PSID Sid,
+ IN PSIDREQRESULT SidRequestResult,
+ IN PVOID Context)
+{
+ PSECURITY_PAGE sp = (PSECURITY_PAGE)Context;
+
+ /* NOTE: this routine may be executed in a different thread
+ than the GUI! */
+
+ if (SidRequestResult != NULL)
+ {
+ SIDLOOKUPNOTIFYINFO LookupInfo;
+
+ LookupInfo.nmh.hwndFrom = sp->hWnd;
+ LookupInfo.nmh.idFrom = 0;
+ LookupInfo.nmh.code = SIDN_LOOKUPSUCCEEDED;
+ LookupInfo.Sid = Sid;
+ LookupInfo.SidRequestResult = SidRequestResult;
+
+ /* notify the page that the sid lookup succeeded */
+ SendMessage(sp->hWnd,
+ WM_NOTIFY,
+ (WPARAM)LookupInfo.nmh.idFrom,
+ (LPARAM)&LookupInfo.nmh);
+ }
+}
-INT_PTR CALLBACK
-SecurityPageProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+static PPRINCIPAL_LISTITEM
+AddPrincipalToList(IN PSECURITY_PAGE sp,
+ IN PSID Sid,
+ IN PACE_HEADER AceHeader,
+ OUT BOOL *LookupDeferred OPTIONAL)
{
- PSECURITY_PAGE sp;
-
- switch(uMsg)
- {
- case WM_INITDIALOG:
- {
- sp = (PSECURITY_PAGE)lParam;
- if(sp != NULL)
- {
- LV_COLUMN lvc;
- RECT rcLvClient;
-
- sp->hWnd = hwndDlg;
- sp->hWndUsrList = GetDlgItem(hwndDlg, IDC_ACELIST);
- sp->hiUsrs = ImageList_LoadBitmap(hDllInstance, MAKEINTRESOURCE(IDB_USRGRPIMAGES), 16, 3, 0);
-
- /* save the pointer to the structure */
- SetWindowLongPtr(hwndDlg, DWL_USER, (DWORD_PTR)sp);
+ PPRINCIPAL_LISTITEM PrincipalListItem = NULL, *PrincipalLink;
+ PACE_ENTRY AceEntry;
+ BOOL Deferred = FALSE;
+
+ if (!FindSidInPrincipalsListAddAce(sp->PrincipalsListHead,
+ Sid,
+ AceHeader))
+ {
+ DWORD SidLength;
- GetClientRect(sp->hWndUsrList, &rcLvClient);
+ PrincipalLink = &sp->PrincipalsListHead;
+ while (*PrincipalLink != NULL)
+ {
+ PrincipalLink = &(*PrincipalLink)->Next;
+ }
- /* setup the listview control */
- ListView_SetExtendedListViewStyleEx(sp->hWndUsrList, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
- ListView_SetImageList(sp->hWndUsrList, sp->hiUsrs, LVSIL_SMALL);
-
- /* add a column to the list view */
- lvc.mask = LVCF_FMT | LVCF_WIDTH;
- lvc.fmt = LVCFMT_LEFT;
- lvc.cx = rcLvClient.right;
- ListView_InsertColumn(sp->hWndUsrList, 0, &lvc);
+ SidLength = GetLengthSid(Sid);
+
+ /* allocate the principal */
+ PrincipalListItem = HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(PRINCIPAL_LISTITEM) + SidLength);
+ if (PrincipalListItem != NULL)
+ {
+ PrincipalListItem->DisplayString = NULL;
+ PrincipalListItem->SidReqResult = NULL;
+
+ CopySid(SidLength,
+ (PSID)(PrincipalListItem + 1),
+ Sid);
+
+ /* allocate some memory for the ACE and copy it */
+ AceEntry = HeapAlloc(GetProcessHeap(),
+ 0,
+ sizeof(ACE_ENTRY) + AceHeader->AceSize);
+ if (AceEntry != NULL)
+ {
+ AceEntry->Next = NULL;
+ CopyMemory(AceEntry + 1,
+ AceHeader,
+ AceHeader->AceSize);
+
+ /* add the ACE to the list */
+ PrincipalListItem->ACEs = AceEntry;
+
+ PrincipalListItem->Next = NULL;
+
+ /* append item to the principals list */
+ *PrincipalLink = PrincipalListItem;
+
+ /* lookup the SID now */
+ Deferred = !LookupSidCache(sp->SidCacheMgr,
+ Sid,
+ SidLookupCompletion,
+ sp);
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(),
+ 0,
+ PrincipalListItem);
+ PrincipalListItem = NULL;
+ }
+ }
+ }
+
+ if (PrincipalListItem != NULL && LookupDeferred != NULL)
+ {
+ *LookupDeferred = Deferred;
+ }
+
+ return PrincipalListItem;
+}
+
+static LPWSTR
+GetPrincipalDisplayString(IN PPRINCIPAL_LISTITEM PrincipalListItem)
+{
+ LPWSTR lpDisplayString = NULL;
+
+ if (PrincipalListItem->SidReqResult != NULL)
+ {
+ if (PrincipalListItem->SidReqResult->SidNameUse == SidTypeUser ||
+ PrincipalListItem->SidReqResult->SidNameUse == SidTypeGroup)
+ {
+ LoadAndFormatString(hDllInstance,
+ IDS_USERDOMAINFORMAT,
+ &lpDisplayString,
+ PrincipalListItem->SidReqResult->AccountName,
+ PrincipalListItem->SidReqResult->DomainName,
+ PrincipalListItem->SidReqResult->AccountName);
+ }
+ else
+ {
+ LoadAndFormatString(hDllInstance,
+ IDS_USERFORMAT,
+ &lpDisplayString,
+ PrincipalListItem->SidReqResult->AccountName);
+ }
+ }
+ else
+ {
+ ConvertSidToStringSid((PSID)(PrincipalListItem + 1),
+ &lpDisplayString);
+ }
+
+ return lpDisplayString;
+}
+
+static LPWSTR
+GetPrincipalAccountNameString(IN PPRINCIPAL_LISTITEM PrincipalListItem)
+{
+ LPWSTR lpDisplayString = NULL;
+
+ if (PrincipalListItem->SidReqResult != NULL)
+ {
+ LoadAndFormatString(hDllInstance,
+ IDS_USERFORMAT,
+ &lpDisplayString,
+ PrincipalListItem->SidReqResult->AccountName);
+ }
+ else
+ {
+ ConvertSidToStringSid((PSID)(PrincipalListItem + 1),
+ &lpDisplayString);
+ }
+
+ return lpDisplayString;
+}
+
+static VOID
+CreatePrincipalListItem(OUT LVITEM *li,
+ IN PSECURITY_PAGE sp,
+ IN PPRINCIPAL_LISTITEM PrincipalListItem,
+ IN INT Index,
+ IN BOOL Selected)
+{
+ INT ImageIndex = 2;
+
+ if (PrincipalListItem->SidReqResult != NULL)
+ {
+ switch (PrincipalListItem->SidReqResult->SidNameUse)
+ {
+ case SidTypeUser:
+ ImageIndex = 0;
+ break;
+ case SidTypeWellKnownGroup:
+ case SidTypeGroup:
+ ImageIndex = 1;
+ break;
+ default:
+ break;
+ }
+ }
+
+ li->mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE | LVIF_TEXT;
+ li->iItem = Index;
+ li->iSubItem = 0;
+ li->state = (Selected ? LVIS_SELECTED : 0);
+ li->stateMask = LVIS_SELECTED;
+ li->pszText = PrincipalListItem->DisplayString;
+ li->iImage = ImageIndex;
+ li->lParam = (LPARAM)PrincipalListItem;
+}
+
+static INT
+AddPrincipalListEntry(IN PSECURITY_PAGE sp,
+ IN PPRINCIPAL_LISTITEM PrincipalListItem,
+ IN INT Index,
+ IN BOOL Selected)
+{
+ LVITEM li;
+ INT Ret;
+
+ if (PrincipalListItem->DisplayString != NULL)
+ {
+ LocalFree((HLOCAL)PrincipalListItem->DisplayString);
+ }
+ PrincipalListItem->DisplayString = GetPrincipalDisplayString(PrincipalListItem);
+
+ CreatePrincipalListItem(&li,
+ sp,
+ PrincipalListItem,
+ Index,
+ Selected);
+
+ Ret = ListView_InsertItem(sp->hWndPrincipalsList,
+ &li);
+
+ return Ret;
+}
+
+static int CALLBACK
+PrincipalCompare(IN LPARAM lParam1,
+ IN LPARAM lParam2,
+ IN LPARAM lParamSort)
+{
+ PPRINCIPAL_LISTITEM Item1 = (PPRINCIPAL_LISTITEM)lParam1;
+ PPRINCIPAL_LISTITEM Item2 = (PPRINCIPAL_LISTITEM)lParam2;
+
+ if (Item1->DisplayString != NULL && Item2->DisplayString != NULL)
+ {
+ return wcscmp(Item1->DisplayString,
+ Item2->DisplayString);
+ }
+
+ return 0;
+}
+
+static VOID
+UpdatePrincipalListItem(IN PSECURITY_PAGE sp,
+ IN INT PrincipalIndex,
+ IN PPRINCIPAL_LISTITEM PrincipalListItem,
+ IN PSIDREQRESULT SidReqResult)
+{
+ LVITEM li;
+
+ /* replace the request result structure */
+ if (PrincipalListItem->SidReqResult != NULL)
+ {
+ DereferenceSidReqResult(sp->SidCacheMgr,
+ PrincipalListItem->SidReqResult);
+ }
+
+ ReferenceSidReqResult(sp->SidCacheMgr,
+ SidReqResult);
+ PrincipalListItem->SidReqResult = SidReqResult;
+
+ /* update the display string */
+ if (PrincipalListItem->DisplayString != NULL)
+ {
+ LocalFree((HLOCAL)PrincipalListItem->DisplayString);
+ }
+ PrincipalListItem->DisplayString = GetPrincipalDisplayString(PrincipalListItem);
+
+ /* update the list item */
+ CreatePrincipalListItem(&li,
+ sp,
+ PrincipalListItem,
+ PrincipalIndex,
+ FALSE);
+
+ /* don't change the list item state */
+ li.mask &= ~(LVIF_STATE | LVIF_PARAM);
+
+ ListView_SetItem(sp->hWndPrincipalsList,
+ &li);
+
+ /* sort the principals list view again */
+ ListView_SortItems(sp->hWndPrincipalsList,
+ PrincipalCompare,
+ (LPARAM)sp);
+}
+
+static VOID
+ReloadPrincipalsList(IN PSECURITY_PAGE sp)
+{
+ PSECURITY_DESCRIPTOR SecurityDescriptor;
+ BOOL DaclPresent, DaclDefaulted;
+ PACL Dacl = NULL;
+ HRESULT hRet;
+
+ /* delete the cached ACL */
+ FreePrincipalsList(sp,
+ &sp->PrincipalsListHead);
+
+ /* query the ACL */
+ hRet = sp->psi->lpVtbl->GetSecurity(sp->psi,
+ DACL_SECURITY_INFORMATION,
+ &SecurityDescriptor,
+ FALSE);
+ if (SUCCEEDED(hRet) && SecurityDescriptor != NULL)
+ {
+ if (GetSecurityDescriptorDacl(SecurityDescriptor,
+ &DaclPresent,
+ &Dacl,
+ &DaclDefaulted) &&
+ DaclPresent && Dacl != NULL)
+ {
+ PSID Sid;
+ PACE_HEADER AceHeader;
+ ULONG AceIndex;
+
+ for (AceIndex = 0;
+ AceIndex < Dacl->AceCount;
+ AceIndex++)
+ {
+ if (GetAce(Dacl,
+ AceIndex,
+ (LPVOID*)&AceHeader) &&
+ AceHeader != NULL)
+ {
+ BOOL LookupDeferred;
+ PPRINCIPAL_LISTITEM PrincipalListItem;
+
+ Sid = AceHeaderToSID(AceHeader);
+
+ PrincipalListItem = AddPrincipalToList(sp,
+ Sid,
+ AceHeader,
+ &LookupDeferred);
+
+ if (PrincipalListItem != NULL && LookupDeferred)
+ {
+ AddPrincipalListEntry(sp,
+ PrincipalListItem,
+ -1,
+ FALSE);
+ }
+ }
+ }
+ }
+ LocalFree((HLOCAL)SecurityDescriptor);
+ }
+}
+
+static VOID
+UpdateControlStates(IN PSECURITY_PAGE sp)
+{
+ PPRINCIPAL_LISTITEM Selected = (PPRINCIPAL_LISTITEM)ListViewGetSelectedItemData(sp->hWndPrincipalsList);
+
+ EnableWindow(sp->hBtnRemove,
+ Selected != NULL);
+ EnableWindow(sp->hAceCheckList,
+ Selected != NULL);
+
+ if (Selected != NULL)
+ {
+ LPWSTR szLabel;
+ LPWSTR szDisplayString;
+
+ szDisplayString = GetPrincipalAccountNameString(Selected);
+ if (LoadAndFormatString(hDllInstance,
+ IDS_PERMISSIONS_FOR,
+ &szLabel,
+ szDisplayString))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szLabel);
+
+ LocalFree((HLOCAL)szLabel);
+ }
+
+ LocalFree((HLOCAL)szDisplayString);
+
+ /* FIXME - update the checkboxes */
+ }
+ else
+ {
+ WCHAR szPermissions[255];
- /* FIXME - hide controls in case the flags aren't present */
- }
- break;
+ if (LoadString(hDllInstance,
+ IDS_PERMISSIONS,
+ szPermissions,
+ sizeof(szPermissions) / sizeof(szPermissions[0])))
+ {
+ SetWindowText(sp->hPermissionsForLabel,
+ szPermissions);
+ }
+
+ SendMessage(sp->hAceCheckList,
+ CLM_CLEARCHECKBOXES,
+ 0,
+ 0);
+ }
+}
+
+static void
+UpdatePrincipalInfo(IN PSECURITY_PAGE sp,
+ IN PSIDLOOKUPNOTIFYINFO LookupInfo)
+{
+ PPRINCIPAL_LISTITEM CurItem;
+
+ for (CurItem = sp->PrincipalsListHead;
+ CurItem != NULL;
+ CurItem = CurItem->Next)
+ {
+ if (EqualSid((PSID)(CurItem + 1),
+ LookupInfo->Sid))
+ {
+ INT PrincipalIndex;
+ LVFINDINFO lvfi;
+
+ /* find the principal in the list */
+ lvfi.flags = LVFI_PARAM;
+ lvfi.lParam = (LPARAM)CurItem;
+ PrincipalIndex = ListView_FindItem(sp->hWndPrincipalsList,
+ -1,
+ &lvfi);
+
+ if (PrincipalIndex != -1)
+ {
+ /* update the principal in the list view control */
+ UpdatePrincipalListItem(sp,
+ PrincipalIndex,
+ CurItem,
+ LookupInfo->SidRequestResult);
+
+ if (ListViewGetSelectedItemData(sp->hWndPrincipalsList) == (LPARAM)CurItem)
+ {
+ UpdateControlStates(sp);
+ }
+ }
+ else
+ {
+ AddPrincipalListEntry(sp,
+ CurItem,
+ -1,
+ FALSE);
+ }
+ break;
+ }
+ }
+}
+
+static UINT CALLBACK
+SecurityPageCallback(IN HWND hwnd,
+ IN UINT uMsg,
+ IN LPPROPSHEETPAGE ppsp)
+{
+ PSECURITY_PAGE sp = (PSECURITY_PAGE)ppsp->lParam;
+
+ switch (uMsg)
+ {
+ case PSPCB_CREATE:
+ {
+ return TRUE;
+ }
+ case PSPCB_RELEASE:
+ {
+ DestroySecurityPage(sp);
+ return FALSE;
+ }
+ }
+
+ return FALSE;
+}
+
+static VOID
+SetAceCheckListColumns(IN HWND hAceCheckList,
+ IN UINT Button,
+ IN HWND hLabel)
+{
+ POINT pt;
+ RECT rcLabel;
+
+ GetWindowRect(hLabel,
+ &rcLabel);
+ pt.y = 0;
+ pt.x = (rcLabel.right - rcLabel.left) / 2;
+ MapWindowPoints(hLabel,
+ hAceCheckList,
+ &pt,
+ 1);
+
+ SendMessage(hAceCheckList,
+ CLM_SETCHECKBOXCOLUMN,
+ Button,
+ pt.x);
+}
+
+static VOID
+LoadPermissionsList(IN PSECURITY_PAGE sp,
+ IN GUID *GuidObjectType,
+ IN DWORD dwFlags,
+ OUT SI_ACCESS *DefaultAccess)
+{
+ HRESULT hRet;
+ PSI_ACCESS AccessList;
+ ULONG nAccessList, DefaultAccessIndex;
+ WCHAR szSpecialPermissions[255];
+ BOOLEAN SpecialPermissionsPresent = FALSE;
+ ACCESS_MASK SpecialPermissionsMask = 0;
+
+ /* clear the permissions list */
+
+ SendMessage(sp->hAceCheckList,
+ CLM_CLEAR,
+ 0,
+ 0);
+
+ /* query the access rights from the server */
+ hRet = sp->psi->lpVtbl->GetAccessRights(sp->psi,
+ GuidObjectType,
+ dwFlags, /* FIXME */
+ &AccessList,
+ &nAccessList,
+ &DefaultAccessIndex);
+ if (SUCCEEDED(hRet) && nAccessList != 0)
+ {
+ LPCWSTR NameStr;
+ PSI_ACCESS CurAccess, LastAccess;
+ WCHAR NameBuffer[MAX_PATH];
+
+ /* save the default access rights to be used when adding ACEs later */
+ if (DefaultAccess != NULL)
+ {
+ *DefaultAccess = AccessList[DefaultAccessIndex];
+ }
+
+ LastAccess = AccessList + nAccessList;
+ for (CurAccess = &AccessList[0];
+ CurAccess != LastAccess;
+ CurAccess++)
+ {
+ if (CurAccess->dwFlags & dwFlags)
+ {
+ /* get the permission name, load it from a string table if necessary */
+ if (IS_INTRESOURCE(CurAccess->pszName))
+ {
+ if (!LoadString(sp->ObjectInfo.hInstance,
+ (UINT)((ULONG_PTR)CurAccess->pszName),
+ NameBuffer,
+ sizeof(NameBuffer) / sizeof(NameBuffer[0])))
+ {
+ LoadString(hDllInstance,
+ IDS_UNKNOWN,
+ NameBuffer,
+ sizeof(NameBuffer) / sizeof(NameBuffer[0]));
+ }
+ NameStr = NameBuffer;
+ }
+ else
+ {
+ NameStr = CurAccess->pszName;
+ }
+
+ SendMessage(sp->hAceCheckList,
+ CLM_ADDITEM,
+ (WPARAM)CurAccess->mask,
+ (LPARAM)NameStr);
+ }
+ else if (CurAccess->dwFlags & SI_ACCESS_SPECIFIC)
+ {
+ SpecialPermissionsPresent = TRUE;
+ SpecialPermissionsMask |= CurAccess->mask;
+ }
+ }
+ }
+
+ /* add the special permissions check item in case the specific access rights
+ aren't displayed */
+ if (SpecialPermissionsPresent &&
+ LoadString(hDllInstance,
+ IDS_SPECIAL_PERMISSIONS,
+ szSpecialPermissions,
+ sizeof(szSpecialPermissions) / sizeof(szSpecialPermissions[0])))
+ {
+ /* add the special permissions check item */
+ sp->SpecialPermCheckIndex = (INT)SendMessage(sp->hAceCheckList,
+ CLM_ADDITEM,
+ (WPARAM)SpecialPermissionsMask,
+ (LPARAM)szSpecialPermissions);
+ if (sp->SpecialPermCheckIndex != -1)
+ {
+ SendMessage(sp->hAceCheckList,
+ CLM_SETITEMSTATE,
+ (WPARAM)sp->SpecialPermCheckIndex,
+ CIS_ALLOWDISABLED | CIS_DENYDISABLED | CIS_NONE);
+ }
+ }
+}
+
+static VOID
+ResizeControls(IN PSECURITY_PAGE sp,
+ IN INT Width,
+ IN INT Height)
+{
+ HWND hWndAllow, hWndDeny;
+ RECT rcControl, rcControl2, rcControl3, rcWnd;
+ INT cxWidth, cxEdge, btnSpacing;
+ POINT pt, pt2;
+ HDWP dwp;
+ INT nControls = 7;
+ LVCOLUMN lvc;
+
+ hWndAllow = GetDlgItem(sp->hWnd,
+ IDC_LABEL_ALLOW);
+ hWndDeny = GetDlgItem(sp->hWnd,
+ IDC_LABEL_DENY);
+
+ GetWindowRect(sp->hWnd,
+ &rcWnd);
+
+ cxEdge = GetSystemMetrics(SM_CXEDGE);
+
+ /* use the left margin of the principal list view control for all control
+ margins */
+ pt.x = 0;
+ pt.y = 0;
+ MapWindowPoints(sp->hWndPrincipalsList,
+ sp->hWnd,
+ &pt,
+ 1);
+ cxWidth = Width - (2 * pt.x);
+
+ if (sp->ObjectInfo.dwFlags & SI_ADVANCED)
+ {
+ nControls += 2;
+ }
+
+ if ((dwp = BeginDeferWindowPos(nControls)))
+ {
+ /* resize the Principal list view */
+ GetWindowRect(sp->hWndPrincipalsList,
+ &rcControl);
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hWndPrincipalsList,
+ NULL,
+ 0,
+ 0,
+ cxWidth,
+ rcControl.bottom - rcControl.top,
+ SWP_NOMOVE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move the Add Principal button */
+ GetWindowRect(sp->hBtnAdd,
+ &rcControl);
+ GetWindowRect(sp->hBtnRemove,
+ &rcControl2);
+ btnSpacing = rcControl2.left - rcControl.right;
+ pt2.x = 0;
+ pt2.y = 0;
+ MapWindowPoints(sp->hBtnAdd,
+ sp->hWnd,
+ &pt2,
+ 1);
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hBtnAdd,
+ NULL,
+ pt.x + cxWidth - (rcControl2.right - rcControl2.left) -
+ (rcControl.right - rcControl.left) -
+ btnSpacing - cxEdge,
+ pt2.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move the Delete Principal button */
+ pt2.x = 0;
+ pt2.y = 0;
+ MapWindowPoints(sp->hBtnRemove,
+ sp->hWnd,
+ &pt2,
+ 1);
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hBtnRemove,
+ NULL,
+ pt.x + cxWidth - (rcControl2.right - rcControl2.left) - cxEdge,
+ pt2.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move the Permissions For label */
+ GetWindowRect(hWndAllow,
+ &rcControl);
+ GetWindowRect(hWndDeny,
+ &rcControl2);
+ GetWindowRect(sp->hPermissionsForLabel,
+ &rcControl3);
+ pt2.x = 0;
+ pt2.y = 0;
+ MapWindowPoints(sp->hPermissionsForLabel,
+ sp->hWnd,
+ &pt2,
+ 1);
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hPermissionsForLabel,
+ NULL,
+ 0,
+ 0,
+ cxWidth - (rcControl2.right - rcControl2.left) -
+ (rcControl.right - rcControl.left) -
+ (2 * btnSpacing) - cxEdge,
+ rcControl3.bottom - rcControl3.top,
+ SWP_NOMOVE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move the Allow label */
+ pt2.x = 0;
+ pt2.y = 0;
+ MapWindowPoints(hWndAllow,
+ sp->hWnd,
+ &pt2,
+ 1);
+ if (!(dwp = DeferWindowPos(dwp,
+ hWndAllow,
+ NULL,
+ cxWidth - (rcControl2.right - rcControl2.left) -
+ (rcControl.right - rcControl.left) -
+ btnSpacing - cxEdge,
+ pt2.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move the Deny label */
+ pt2.x = 0;
+ pt2.y = 0;
+ MapWindowPoints(hWndDeny,
+ sp->hWnd,
+ &pt2,
+ 1);
+ if (!(dwp = DeferWindowPos(dwp,
+ hWndDeny,
+ NULL,
+ cxWidth - (rcControl2.right - rcControl2.left) - cxEdge,
+ pt2.y,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* resize the Permissions check list box */
+ GetWindowRect(sp->hAceCheckList,
+ &rcControl);
+ GetWindowRect(sp->hBtnAdvanced,
+ &rcControl2);
+ GetWindowRect(GetDlgItem(sp->hWnd,
+ IDC_LABEL_ADVANCED),
+ &rcControl3);
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hAceCheckList,
+ NULL,
+ 0,
+ 0,
+ cxWidth,
+ ((sp->ObjectInfo.dwFlags & SI_ADVANCED) ?
+ Height - (rcControl.top - rcWnd.top) -
+ (rcControl3.bottom - rcControl3.top) - pt.x - btnSpacing :
+ Height - (rcControl.top - rcWnd.top) - pt.x),
+ SWP_NOMOVE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ if (sp->ObjectInfo.dwFlags & SI_ADVANCED)
+ {
+ /* move and resize the Advanced label */
+ if (!(dwp = DeferWindowPos(dwp,
+ GetDlgItem(sp->hWnd,
+ IDC_LABEL_ADVANCED),
+ NULL,
+ pt.x,
+ Height - (rcControl3.bottom - rcControl3.top) - pt.x,
+ cxWidth - (rcControl2.right - rcControl2.left) - cxEdge,
+ rcControl3.bottom - rcControl3.top,
+ SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+
+ /* move and resize the Advanced button */
+ if (!(dwp = DeferWindowPos(dwp,
+ sp->hBtnAdvanced,
+ NULL,
+ cxWidth - (rcControl2.right - rcControl2.left) + pt.x,
+ Height - (rcControl2.bottom - rcControl2.top) - pt.x,
+ 0,
+ 0,
+ SWP_NOSIZE | SWP_NOZORDER)))
+ {
+ goto EndDeferWnds;
+ }
+ }
+
+ EndDeferWindowPos(dwp);
+ }
+
+EndDeferWnds:
+ /* update the width of the principal list view column */
+ GetClientRect(sp->hWndPrincipalsList,
+ &rcControl);
+ lvc.mask = LVCF_WIDTH;
+ lvc.cx = rcControl.right;
+ ListView_SetColumn(sp->hWndPrincipalsList,
+ 0,
+ &lvc);
+
+ /* calculate the columns of the allow/deny checkboxes */
+ SetAceCheckListColumns(sp->hAceCheckList,
+ CLB_ALLOW,
+ hWndAllow);
+ SetAceCheckListColumns(sp->hAceCheckList,
+ CLB_DENY,
+ hWndDeny);
+}
+
+static PACE_HEADER
+BuildDefaultPrincipalAce(IN PSECURITY_PAGE sp,
+ IN PSID pSid)
+{
+ PACCESS_ALLOWED_ACE Ace;
+ DWORD SidLen;
+ WORD AceSize;
+
+ SidLen = GetLengthSid(pSid);
+ AceSize = sizeof(ACCESS_ALLOWED_ACE) + (WORD)SidLen - sizeof(DWORD);
+ Ace = HeapAlloc(GetProcessHeap(),
+ 0,
+ AceSize);
+ if (Ace != NULL)
+ {
+ Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
+ Ace->Header.AceFlags = 0; /* FIXME */
+ Ace->Header.AceSize = AceSize;
+ Ace->Mask = sp->DefaultAccess.mask;
+
+ if (CopySid(SidLen,
+ (PSID)&Ace->SidStart,
+ pSid))
+ {
+ return &Ace->Header;
+ }
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ Ace);
+ }
+
+ return NULL;
+}
+
+static BOOL
+AddSelectedPrincipal(IN IDsObjectPicker *pDsObjectPicker,
+ IN HWND hwndParent OPTIONAL,
+ IN PSID pSid,
+ IN PVOID Context OPTIONAL)
+{
+ PACE_HEADER AceHeader;
+ PSECURITY_PAGE sp = (PSECURITY_PAGE)Context;
+
+ AceHeader = BuildDefaultPrincipalAce(sp,
+ pSid);
+ if (AceHeader != NULL)
+ {
+ PPRINCIPAL_LISTITEM PrincipalListItem;
+ BOOL LookupDeferred;
+
+ PrincipalListItem = AddPrincipalToList(sp,
+ pSid,
+ AceHeader,
+ &LookupDeferred);
+
+ if (PrincipalListItem != NULL && LookupDeferred)
+ {
+ AddPrincipalListEntry(sp,
+ PrincipalListItem,
+ -1,
+ FALSE);
+ }
+
+ HeapFree(GetProcessHeap(),
+ 0,
+ AceHeader);
+ }
+
+ return TRUE;
+}
+
+static INT_PTR CALLBACK
+SecurityPageProc(IN HWND hwndDlg,
+ IN UINT uMsg,
+ IN WPARAM wParam,
+ IN LPARAM lParam)
+{
+ PSECURITY_PAGE sp;
+ INT_PTR Ret = FALSE;
+
+ sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg,
+ DWL_USER);
+ if (sp != NULL || uMsg == WM_INITDIALOG)
+ {
+ switch (uMsg)
+ {
+ case WM_NOTIFY:
+ {
+ NMHDR *pnmh = (NMHDR*)lParam;
+
+ if (pnmh->hwndFrom == sp->hWndPrincipalsList)
+ {
+ switch (pnmh->code)
+ {
+ case LVN_ITEMCHANGED:
+ {
+ LPNMLISTVIEW pnmv = (LPNMLISTVIEW)lParam;
+
+ if ((pnmv->uChanged & LVIF_STATE) &&
+ ((pnmv->uOldState & (LVIS_FOCUSED | LVIS_SELECTED)) ||
+ (pnmv->uNewState & (LVIS_FOCUSED | LVIS_SELECTED))))
+ {
+ UpdateControlStates(sp);
+ }
+ break;
+ }
+ }
+ }
+ else if (pnmh->hwndFrom == sp->hAceCheckList)
+ {
+ switch (pnmh->code)
+ {
+ case CLN_CHANGINGITEMCHECKBOX:
+ {
+ PNMCHANGEITEMCHECKBOX pcicb = (PNMCHANGEITEMCHECKBOX)lParam;
+
+ /* make sure only one of both checkboxes is only checked
+ at the same time */
+ if (pcicb->Checked)
+ {
+ pcicb->NewState &= ~((pcicb->CheckBox != CLB_DENY) ? CIS_DENY : CIS_ALLOW);
+ }
+ break;
+ }
+ }
+ }
+ else if (pnmh->hwndFrom == sp->hWnd)
+ {
+ switch(pnmh->code)
+ {
+ case SIDN_LOOKUPSUCCEEDED:
+ {
+ PSIDLOOKUPNOTIFYINFO LookupInfo = CONTAINING_RECORD(lParam,
+ SIDLOOKUPNOTIFYINFO,
+ nmh);
+
+ /* a SID lookup succeeded, update the information */
+ UpdatePrincipalInfo(sp,
+ LookupInfo);
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ case WM_COMMAND:
+ {
+ switch (LOWORD(wParam))
+ {
+ case IDC_ADD_PRINCIPAL:
+ {
+ HRESULT hRet;
+
+ hRet = InitializeObjectPicker(sp->ServerName,
+ &sp->ObjectInfo,
+ &sp->pDsObjectPicker);
+ if (SUCCEEDED(hRet))
+ {
+ hRet = InvokeObjectPickerDialog(sp->pDsObjectPicker,
+ hwndDlg,
+ AddSelectedPrincipal,
+ sp);
+ if (FAILED(hRet))
+ {
+ MessageBox(hwndDlg, L"InvokeObjectPickerDialog failed!\n", NULL, 0);
+ }
+
+ /* delete the instance */
+ FreeObjectPicker(sp->pDsObjectPicker);
+ }
+ else
+ {
+ MessageBox(hwndDlg, L"InitializeObjectPicker failed!\n", NULL, 0);
+ }
+ break;
+ }
+
+ case IDC_REMOVE_PRINCIPAL:
+ {
+ PPRINCIPAL_LISTITEM SelectedPrincipal;
+
+ SelectedPrincipal = (PPRINCIPAL_LISTITEM)ListViewGetSelectedItemData(sp->hWndPrincipalsList);
+ if (SelectedPrincipal != NULL)
+ {
+ /* FIXME */
+ }
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_SIZE:
+ {
+ ResizeControls(sp,
+ (INT)LOWORD(lParam),
+ (INT)HIWORD(lParam));
+ break;
+ }
+
+ case WM_INITDIALOG:
+ {
+ sp = (PSECURITY_PAGE)((LPPROPSHEETPAGE)lParam)->lParam;
+ if(sp != NULL)
+ {
+ LV_COLUMN lvc;
+ RECT rcLvClient;
+
+ sp->hWnd = hwndDlg;
+ sp->hWndPrincipalsList = GetDlgItem(hwndDlg, IDC_PRINCIPALS);
+ sp->hBtnAdd = GetDlgItem(hwndDlg, IDC_ADD_PRINCIPAL);
+ sp->hBtnRemove = GetDlgItem(hwndDlg, IDC_REMOVE_PRINCIPAL);
+ sp->hBtnAdvanced = GetDlgItem(hwndDlg, IDC_ADVANCED);
+ sp->hAceCheckList = GetDlgItem(hwndDlg, IDC_ACE_CHECKLIST);
+ sp->hPermissionsForLabel = GetDlgItem(hwndDlg, IDC_LABEL_PERMISSIONS_FOR);
+
+ sp->SpecialPermCheckIndex = -1;
+
+ /* save the pointer to the structure */
+ SetWindowLongPtr(hwndDlg,
+ DWL_USER,
+ (DWORD_PTR)sp);
+
+ ListView_SetExtendedListViewStyleEx(sp->hWndPrincipalsList,
+ LVS_EX_FULLROWSELECT,
+ LVS_EX_FULLROWSELECT);
+
+ sp->hiPrincipals = ImageList_LoadBitmap(hDllInstance,
+ MAKEINTRESOURCE(IDB_USRGRPIMAGES),
+ 16,
+ 3,
+ RGB(255,
+ 0,
+ 255));
+
+ /* setup the listview control */
+ if (sp->hiPrincipals != NULL)
+ {
+ ListView_SetImageList(sp->hWndPrincipalsList,
+ sp->hiPrincipals,
+ LVSIL_SMALL);
+ }
+
+ GetClientRect(sp->hWndPrincipalsList,
+ &rcLvClient);
+
+ /* add a column to the list view */
+ lvc.mask = LVCF_FMT | LVCF_WIDTH;
+ lvc.fmt = LVCFMT_LEFT;
+ lvc.cx = rcLvClient.right;
+ ListView_InsertColumn(sp->hWndPrincipalsList,
+ 0,
+ &lvc);
+
+ ReloadPrincipalsList(sp);
+
+ ListViewSelectItem(sp->hWndPrincipalsList,
+ 0);
+
+ /* calculate the columns of the allow/deny checkboxes */
+ SetAceCheckListColumns(sp->hAceCheckList,
+ CLB_ALLOW,
+ GetDlgItem(hwndDlg, IDC_LABEL_ALLOW));
+ SetAceCheckListColumns(sp->hAceCheckList,
+ CLB_DENY,
+ GetDlgItem(hwndDlg, IDC_LABEL_DENY));
+
+ LoadPermissionsList(sp,
+ NULL,
+ SI_ACCESS_GENERAL |
+ ((sp->ObjectInfo.dwFlags & SI_CONTAINER) ? SI_ACCESS_CONTAINER : 0),
+ &sp->DefaultAccess);
+
+ /* hide controls in case the flags aren't present */
+ if (sp->ObjectInfo.dwFlags & SI_ADVANCED)
+ {
+ /* editing the permissions is least the user can do when
+ the advanced button is showed */
+ sp->ObjectInfo.dwFlags |= SI_EDIT_PERMS;
+ }
+ else
+ {
+ ShowWindow(sp->hBtnAdvanced,
+ SW_HIDE);
+ ShowWindow(GetDlgItem(hwndDlg, IDC_LABEL_ADVANCED),
+ SW_HIDE);
+ }
+
+ /* enable quicksearch for the permissions checklist control */
+ SendMessage(sp->hAceCheckList,
+ CLM_ENABLEQUICKSEARCH,
+ TRUE,
+ 0);
+
+ UpdateControlStates(sp);
+ }
+
+ Ret = TRUE;
+ break;
+ }
+ }
}
- }
- return 0;
+ return Ret;
}
*/
HPROPSHEETPAGE
WINAPI
-CreateSecurityPage(LPSECURITYINFO psi)
+CreateSecurityPage(IN LPSECURITYINFO psi)
{
- PROPSHEETPAGE psp;
- SI_OBJECT_INFO ObjectInfo;
- HRESULT hRet;
+ PROPSHEETPAGE psp = {0};
+ PSECURITY_PAGE sPage;
+ SI_OBJECT_INFO ObjectInfo = {0};
+ HANDLE SidCacheMgr;
+ LPCWSTR SystemName = NULL;
+ HRESULT hRet;
- if(psi == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
+ if (psi == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
- DPRINT("No ISecurityInformation class passed!\n");
- return NULL;
- }
+ DPRINT("No ISecurityInformation class passed!\n");
+ return NULL;
+ }
- /* get the object information from the server interface */
- hRet = psi->lpVtbl->GetObjectInformation(psi, &ObjectInfo);
+ /* get the object information from the server. Zero the structure before
+ because some applications seem to return SUCCESS but only seem to set the
+ fields they care about. */
+ hRet = psi->lpVtbl->GetObjectInformation(psi,
+ &ObjectInfo);
- if(FAILED(hRet))
- {
- SetLastError(hRet);
+ if (FAILED(hRet))
+ {
+ SetLastError(hRet);
- DPRINT("CreateSecurityPage() failed!\n");
- return NULL;
- }
-
- psp.dwSize = sizeof(PROPSHEETPAGE);
- psp.dwFlags = PSP_DEFAULT | PSP_USECALLBACK;
- psp.hInstance = hDllInstance;
- psp.pszTemplate = MAKEINTRESOURCE(IDD_SECPAGE);
- psp.pfnDlgProc = SecurityPageProc;
- psp.lParam = (LPARAM)psi;
- psp.pfnCallback = SecurityPageCallback;
-
- if((ObjectInfo.dwFlags & SI_PAGE_TITLE) != 0 &&
- ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
- {
- /* Set the page title if the flag is present and the string isn't empty */
- psp.pszTitle = ObjectInfo.pszPageTitle;
- psp.dwFlags |= PSP_USETITLE;
- }
-
- return CreatePropertySheetPage(&psp);
+ DPRINT("CreateSecurityPage() failed! Failed to query the object information!\n");
+ return NULL;
+ }
+
+ if ((ObjectInfo.dwFlags & SI_SERVER_IS_DC) &&
+ ObjectInfo.pszServerName != NULL &&
+ ObjectInfo.pszServerName[0] != L'\0')
+ {
+ SystemName = ObjectInfo.pszServerName;
+ }
+
+ SidCacheMgr = CreateSidCacheMgr(GetProcessHeap(),
+ SystemName);
+ if (SidCacheMgr == NULL)
+ {
+ DPRINT("Creating the SID cache failed!\n");
+ return NULL;
+ }
+
+ hRet = CoInitialize(NULL);
+ if (FAILED(hRet))
+ {
+ DestroySidCacheMgr(SidCacheMgr);
+ DPRINT("CoInitialize failed!\n");
+ return NULL;
+ }
+
+ sPage = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SECURITY_PAGE));
+ if (sPage == NULL)
+ {
+ DestroySidCacheMgr(SidCacheMgr);
+ CoUninitialize();
+
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+
+ DPRINT("Not enough memory to allocate a SECURITY_PAGE!\n");
+ return NULL;
+ }
+
+ sPage->psi = psi;
+ sPage->ObjectInfo = ObjectInfo;
+ sPage->ServerName = SystemName;
+ sPage->SidCacheMgr = SidCacheMgr;
+
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = PSP_USECALLBACK;
+ psp.hInstance = hDllInstance;
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_SECPAGE);
+ psp.pfnDlgProc = SecurityPageProc;
+ psp.lParam = (LPARAM)sPage;
+ psp.pfnCallback = SecurityPageCallback;
+
+ if (ObjectInfo.dwFlags & SI_PAGE_TITLE)
+ {
+ psp.pszTitle = ObjectInfo.pszPageTitle;
+
+ if (psp.pszTitle != NULL)
+ {
+ psp.dwFlags |= PSP_USETITLE;
+ }
+ }
+ else
+ {
+ psp.pszTitle = NULL;
+ }
+
+ /* NOTE: the SECURITY_PAGE structure will be freed by the property page
+ callback! */
+
+ return CreatePropertySheetPage(&psp);
}
*/
BOOL
WINAPI
-EditSecurity(HWND hwndOwner, LPSECURITYINFO psi)
+EditSecurity(IN HWND hwndOwner,
+ IN LPSECURITYINFO psi)
{
- HRESULT hRet;
- SI_OBJECT_INFO ObjectInfo;
- PROPSHEETHEADER psh;
- HPROPSHEETPAGE hPages[1];
- LPWSTR lpCaption;
- BOOL Ret;
-
- if(psi == NULL)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
-
- DPRINT("No ISecurityInformation class passed!\n");
- return FALSE;
- }
-
- /* get the object information from the server interface */
- hRet = psi->lpVtbl->GetObjectInformation(psi, &ObjectInfo);
-
- if(FAILED(hRet))
- {
- SetLastError(hRet);
-
- DPRINT("GetObjectInformation() failed!\n");
- return FALSE;
- }
+ HRESULT hRet;
+ SI_OBJECT_INFO ObjectInfo = {0};
+ PROPSHEETHEADER psh;
+ HPROPSHEETPAGE hPages[1];
+ LPWSTR lpCaption = NULL;
+ BOOL Ret;
+
+ if (psi == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+
+ DPRINT("No ISecurityInformation class passed!\n");
+ return FALSE;
+ }
+
+ /* get the object information from the server. Zero the structure before
+ because some applications seem to return SUCCESS but only seem to set the
+ fields they care about. */
+ hRet = psi->lpVtbl->GetObjectInformation(psi,
+ &ObjectInfo);
+
+ if (FAILED(hRet))
+ {
+ SetLastError(hRet);
+
+ DPRINT("GetObjectInformation() failed!\n");
+ return FALSE;
+ }
+
+ /* create the page */
+ hPages[0] = CreateSecurityPage(psi);
+ if (hPages[0] == NULL)
+ {
+ DPRINT("CreateSecurityPage(), couldn't create property sheet!\n");
+ return FALSE;
+ }
+
+ psh.dwSize = sizeof(PROPSHEETHEADER);
+ psh.dwFlags = PSH_DEFAULT;
+ psh.hwndParent = hwndOwner;
+ psh.hInstance = hDllInstance;
- /* create the page */
- hPages[0] = CreateSecurityPage(psi);
- if(hPages[0] == NULL)
- {
- DPRINT("CreateSecurityPage(), couldn't create property sheet!\n");
- return FALSE;
- }
-
- psh.dwSize = sizeof(PROPSHEETHEADER);
- psh.dwFlags = PSH_DEFAULT;
- psh.hwndParent = hwndOwner;
- psh.hInstance = hDllInstance;
- if((ObjectInfo.dwFlags & SI_PAGE_TITLE) != 0 &&
- ObjectInfo.pszPageTitle != NULL && ObjectInfo.pszPageTitle[0] != L'\0')
- {
- /* Set the page title if the flag is present and the string isn't empty */
- psh.pszCaption = ObjectInfo.pszPageTitle;
- lpCaption = NULL;
- }
- else
- {
/* Set the page title to the object name, make sure the format string
has "%1" NOT "%s" because it uses FormatMessage() to automatically
allocate the right amount of memory. */
- RosLoadAndFormatStr(hDllInstance, IDS_PSP_TITLE, &lpCaption, ObjectInfo.pszObjectName);
- psh.pszCaption = lpCaption;
- }
- psh.nPages = sizeof(hPages) / sizeof(HPROPSHEETPAGE);
- psh.nStartPage = 0;
- psh.phpage = hPages;
-
- Ret = (PropertySheet(&psh) != -1);
-
- if(lpCaption != NULL)
- {
- LocalFree((HLOCAL)lpCaption);
- }
-
- return Ret;
+ if (LoadAndFormatString(hDllInstance,
+ IDS_PSP_TITLE,
+ &lpCaption,
+ ObjectInfo.pszObjectName))
+ {
+ psh.pszCaption = lpCaption;
+ }
+ else
+ {
+ psh.pszCaption = ObjectInfo.pszObjectName;
+ }
+
+ psh.nPages = sizeof(hPages) / sizeof(HPROPSHEETPAGE);
+ psh.nStartPage = 0;
+ psh.phpage = hPages;
+
+ Ret = (PropertySheet(&psh) != -1);
+
+ if (lpCaption != NULL)
+ {
+ LocalFree((HLOCAL)lpCaption);
+ }
+
+ return Ret;
}
-BOOL STDCALL
-DllMain(HINSTANCE hinstDLL,
- DWORD dwReason,
- LPVOID lpvReserved)
+BOOL
+WINAPI
+DllMain(IN HINSTANCE hinstDLL,
+ IN DWORD dwReason,
+ IN LPVOID lpvReserved)
{
- switch (dwReason)
- {
- case DLL_PROCESS_ATTACH:
- hDllInstance = hinstDLL;
- break;
- case DLL_THREAD_ATTACH:
- break;
- case DLL_THREAD_DETACH:
- break;
- case DLL_PROCESS_DETACH:
- break;
- }
- return TRUE;
+ switch (dwReason)
+ {
+ case DLL_PROCESS_ATTACH:
+ hDllInstance = hinstDLL;
+
+ DisableThreadLibraryCalls(hinstDLL);
+
+ if (!RegisterCheckListControl(hinstDLL))
+ {
+ DPRINT("Registering the CHECKLIST_ACLUI class failed!\n");
+ return FALSE;
+ }
+ break;
+
+ case DLL_PROCESS_DETACH:
+ UnregisterCheckListControl();
+ break;
+ }
+
+ return TRUE;
}